diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 000000000..219e21816 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,7 @@ +language: "en-US" +reviews: + auto_review: + enabled: true + labels: ["Needs review"] + ignore_usernames: ["dependabot[bot]", "renovate[bot]"] + ignore_title_keywords: ["wip", "draft"] diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a7e537ad3..7a898016e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,6 +16,7 @@ packages/bsp/jethub/ @armbian/build-scripts @adeepn tools/ @iav @neheb @hzyitc @mhoffrog # The following contents are generated by board configs +config/boards/9tripod-x3568-v4.csc @rbqvq config/boards/aml-a311d-cc.conf @Tonymac32 config/boards/aml-c400-plus.conf @jomadeto config/boards/aml-s905d3-cc.wip @Tonymac32 @@ -42,6 +43,7 @@ config/boards/bananapim7.conf @amazingfate config/boards/beaglebone-ai64.conf @Grippy98 config/boards/beagleplay.conf @Grippy98 config/boards/beagley-ai.conf @Grippy98 +config/boards/bestv-r3300-l.csc @retro98boy config/boards/bigtreetech-cb1.conf @JohnTheCoolingFan config/boards/bigtreetech-cb2.conf @JohnTheCoolingFan config/boards/cainiao-cniot-core.csc @retro98boy @@ -51,6 +53,7 @@ config/boards/cm3588-nas.csc @ColorfulRhino config/boards/coolpi-cm5.csc @andyshrk config/boards/coolpi-genbook.csc @andyshrk config/boards/dusun-dsom-010r.csc @paolosabatino +config/boards/espressobin.conf @igorpecovnik config/boards/firefly-itx-3588j.csc @SeeleVolleri config/boards/fxblox-rk1.csc @mahdichi config/boards/gateway-gz80x.conf @pyavitz @@ -80,9 +83,14 @@ config/boards/lepotato.conf @Tonymac32 config/boards/licheepi-4a.eos @chainsx config/boards/longanpi-4b.csc @chainsx config/boards/lubancat2.csc @andyshrk +config/boards/luckfox-lyra-plus.csc @vidplace7 +config/boards/luckfox-lyra-ultra-w.csc @vidplace7 +config/boards/luckfox-lyra-zero-w.csc @vidplace7 +config/boards/luckfox-pico-mini.csc @vidplace7 config/boards/mangopi-m28k.csc @sputnik2019 config/boards/mba8mpxl-ras314.conf @schmiedelm config/boards/mba8mpxl.conf @schmiedelm +config/boards/mekotronics-r58-4x4.conf @150balbes config/boards/mekotronics-r58hd.conf @igorpecovnik config/boards/mixtile-blade3.csc @rpardini config/boards/mksklipad50.conf @torte71 @@ -128,19 +136,19 @@ config/boards/orangepizeroplus.csc @schwar3kat config/boards/phytiumpi.conf @chainsx config/boards/pine64.conf @PanderMusubi config/boards/pinebook-a64.csc @Qvy-png -config/boards/pinebook-pro.csc @TRSx80 @ahoneybun +config/boards/pinebook-pro.csc @ahoneybun config/boards/pocketbeagle2.conf @Grippy98 config/boards/pocketchip-sd.csc @TheSnowfield config/boards/qemu-uboot-arm64.csc @rpardini config/boards/qemu-uboot-x86.csc @rpardini -config/boards/qemu-uefi-x86.conf @davidandreoletti config/boards/radxa-dragon-q6a.conf @HeyMeco config/boards/radxa-e20c.csc @mattx433 config/boards/radxa-e25.csc @krachlatte config/boards/radxa-e52c.conf @amazingfate @schwar3kat +config/boards/radxa-e54c.csc @kamilsaigol config/boards/radxa-nio-12l.conf @HeyMeco config/boards/radxa-rock-4d.csc @HeyMeco -config/boards/radxa-zero.conf @clee @engineer-80 +config/boards/radxa-zero.conf @engineer-80 config/boards/recore.csc @eliasbakken config/boards/renegade.conf @Tonymac32 config/boards/retro-lite-cm5.csc @ginkage @@ -156,16 +164,14 @@ config/boards/rock-5b.conf @amazingfate @linhz0hz config/boards/rock-5c.conf @schwar3kat config/boards/rock-5t.conf @HeyMeco config/boards/rock-s0.conf @brentr -config/boards/rock64.conf @clee -config/boards/rockpi-4a.csc @clee config/boards/rockpi-e.conf @paolosabatino config/boards/rockpi-s.conf @brentr config/boards/rockpro64.csc @joekhoobyar config/boards/rpi4b.conf @PanderMusubi @teknoid config/boards/sakurapi-rk3308b.csc @TheSnowfield -config/boards/sk-am62b.conf @glneo -config/boards/sk-am62p.conf @Grippy98 -config/boards/sk-am64b.conf @glneo +config/boards/sk-am62b.conf @jonaswood01 +config/boards/sk-am62p.conf @jonaswood01 +config/boards/sk-am64b.conf @jonaswood01 config/boards/sk-am68.conf @glneo config/boards/sk-am69.conf @glneo config/boards/sk-tda4vm.conf @glneo @@ -191,18 +197,22 @@ config/boards/yy3568.csc @hqnicolas config/kernel/linux-arm64-*.config @PeterChrz @rpardini config/kernel/linux-bcm2711-*.config @PanderMusubi @teknoid config/kernel/linux-genio-*.config @HeyMeco -config/kernel/linux-k3-*.config @Grippy98 @glneo +config/kernel/linux-k3-*.config @Grippy98 @glneo @jonaswood01 config/kernel/linux-k3-beagle-*.config @Grippy98 +config/kernel/linux-k3-beagle-vendor-*.config @Grippy98 +config/kernel/linux-k3-vendor-*.config @Grippy98 @glneo @jonaswood01 config/kernel/linux-meson-*.config @hzyitc @juanlufont config/kernel/linux-meson-s4t7-*.config @adeepn @leggewie @pyavitz @rpardini -config/kernel/linux-meson64-*.config @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @biot @clee @engineer-80 @igorpecovnik @jeanrhum @jomadeto @pyavitz @retro98boy @rpardini @teknoid +config/kernel/linux-meson64-*.config @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @biot @engineer-80 @igorpecovnik @jeanrhum @jomadeto @pyavitz @retro98boy @rpardini @teknoid config/kernel/linux-mvebu-*.config @Heisath @leggewie +config/kernel/linux-mvebu64-*.config @igorpecovnik config/kernel/linux-odroidxu4-*.config @joekhoobyar config/kernel/linux-phytium-embedded-*.config @chainsx config/kernel/linux-qcs6490-*.config @HeyMeco -config/kernel/linux-rk35xx-*.config @CodeChenL @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @krachlatte @lanefu @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @vamzii -config/kernel/linux-rockchip-*.config @amazingfate @paolosabatino -config/kernel/linux-rockchip64-*.config @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TRSx80 @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @clee @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii +config/kernel/linux-rk35xx-*.config @150balbes @CodeChenL @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @lanefu @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @vamzii +config/kernel/linux-rockchip-*.config @amazingfate @paolosabatino @vidplace7 +config/kernel/linux-rockchip-rv1106-*.config @vidplace7 +config/kernel/linux-rockchip64-*.config @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii config/kernel/linux-sm8250-*.config @amazingfate config/kernel/linux-sm8550-*.config @FantasyGmm config/kernel/linux-spacemit-*.config @pyavitz @@ -213,7 +223,7 @@ config/kernel/linux-sunxi64-*.config @AGM1968 @IsMrX @JohnTheCoolingFan @Kreyre config/kernel/linux-thead-*.config @chainsx config/kernel/linux-tqma-*.config @schmiedelm config/kernel/linux-uefi-arm64-*.config @rpardini -config/kernel/linux-uefi-x86-*.config @davidandreoletti @rpardini +config/kernel/linux-uefi-x86-*.config @rpardini config/kernel/linux-wsl2-arm64-*.config @rpardini config/kernel/linux-wsl2-x86-*.config @rpardini config/kernel/linux-xpressreal-t3-*.config @wei633 @@ -222,10 +232,11 @@ patch/atf/atf-bcm2711/ @PanderMusubi @teknoid patch/atf/atf-genio/ @HeyMeco patch/atf/atf-imx8/ @schmiedelm patch/atf/atf-k3-beagle/ @Grippy98 -patch/atf/atf-k3/ @Grippy98 @glneo +patch/atf/atf-k3/ @Grippy98 @glneo @jonaswood01 +patch/atf/atf-mvebu64/ @igorpecovnik patch/atf/atf-phytium-embedded/ @chainsx patch/atf/atf-qcs6490/ @HeyMeco -patch/atf/atf-rockchip64/ @ColorfulRhino @SuperKali @TRSx80 @Tonymac32 @ahoneybun @andyshrk @clee @joekhoobyar @paolosabatino @prahal +patch/atf/atf-rockchip64/ @ColorfulRhino @SuperKali @Tonymac32 @ahoneybun @andyshrk @joekhoobyar @paolosabatino @prahal patch/atf/atf-sm8250/ @amazingfate patch/atf/atf-sm8550/ @FantasyGmm patch/atf/atf-spacemit/ @pyavitz @@ -234,28 +245,30 @@ patch/atf/atf-sunxi64/ @AGM1968 @IsMrX @JohnTheCoolingFan @Kreyren @PanderMusub patch/atf/atf-wsl2-arm64/ @rpardini patch/kernel/archive/bcm2711-*/ @PanderMusubi @teknoid patch/kernel/archive/imx8m-*/ @schmiedelm -patch/kernel/archive/k3-*/ @Grippy98 @glneo +patch/kernel/archive/k3-*/ @Grippy98 @glneo @jonaswood01 patch/kernel/archive/k3-beagle-*/ @Grippy98 patch/kernel/archive/meson-*/ @hzyitc @juanlufont patch/kernel/archive/meson-s4t7-*/ @adeepn @leggewie @pyavitz @rpardini -patch/kernel/archive/meson64-*/ @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @biot @clee @engineer-80 @igorpecovnik @jeanrhum @jomadeto @pyavitz @retro98boy @rpardini @teknoid +patch/kernel/archive/meson64-*/ @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @biot @engineer-80 @igorpecovnik @jeanrhum @jomadeto @pyavitz @retro98boy @rpardini @teknoid patch/kernel/archive/mvebu-*/ @Heisath @leggewie +patch/kernel/archive/mvebu64-*/ @igorpecovnik patch/kernel/archive/odroidxu4-*/ @joekhoobyar patch/kernel/archive/qcs6490-*/ @HeyMeco patch/kernel/archive/realtek-rtd1619b-*/ @wei633 patch/kernel/archive/rockchip-*/ @paolosabatino -patch/kernel/archive/rockchip64-*/ @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TRSx80 @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @clee @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii +patch/kernel/archive/rockchip64-*/ @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @chainsx @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @pyavitz @rbqvq @redrathnure @retro98boy @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii patch/kernel/archive/sm8250-*/ @amazingfate patch/kernel/archive/sm8550-*/ @FantasyGmm patch/kernel/archive/spacemit-*/ @pyavitz patch/kernel/archive/sunxi-*/ @1ubuntuuser @AGM1968 @AaronNGray @DylanHP @IsMrX @Janmcha @JohnTheCoolingFan @Kreyren @PanderMusubi @Qvy-png @Ressetkk @StephenGraf @The-going @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @igorpecovnik @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @pyavitz @schwar3kat @sgjava @sicXnull @spendist @teknoid patch/kernel/archive/uefi-arm64-*/ @PeterChrz @rpardini -patch/kernel/archive/uefi-x86-*/ @davidandreoletti @rpardini +patch/kernel/archive/uefi-x86-*/ @rpardini patch/kernel/archive/wsl2-arm64-*/ @rpardini patch/kernel/archive/wsl2-x86-*/ @rpardini patch/kernel/genio-1200-*/ @HeyMeco patch/kernel/phytium-embedded-*/ @chainsx -patch/kernel/rk35xx-vendor-*/ @CodeChenL @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @krachlatte @lanefu @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @vamzii +patch/kernel/rk35xx-vendor-*/ @150balbes @CodeChenL @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @andyshrk @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @lanefu @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @vamzii @vidplace7 +patch/kernel/rv1106-vendor-*/ @vidplace7 patch/kernel/starfive2-*/ @libiunc patch/kernel/sun55iw3-syterkit-*/ @chainsx patch/kernel/thead-*/ @chainsx @@ -264,17 +277,17 @@ patch/u-boot/legacy/ @chainsx @joekhoobyar @juanlufont @lanefu patch/u-boot/legacy/u-boot-clearfog/ @Heisath patch/u-boot/legacy/u-boot-helios4/ @leggewie patch/u-boot/legacy/u-boot-khadas-edge2-rk3588/ @efectn -patch/u-boot/legacy/u-boot-radxa-rk35xx/ @CodeChenL @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @krachlatte @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @tdleiyao @vamzii +patch/u-boot/legacy/u-boot-radxa-rk35xx/ @150balbes @CodeChenL @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @igorpecovnik @kamilsaigol @krachlatte @linhz0hz @mahdichi @mattx433 @prahal @rpardini @schwar3kat @sputnik2019 @tdleiyao @vamzii +patch/u-boot/legacy/u-boot-rockchip-buildroot/ @vidplace7 patch/u-boot/legacy/u-boot-spacemit-k1/ @pyavitz -patch/u-boot/u-boot-beagle/ @Grippy98 patch/u-boot/u-boot-k3-beagle/ @Grippy98 -patch/u-boot/u-boot-k3/ @Grippy98 @glneo +patch/u-boot/u-boot-k3/ @Grippy98 @glneo @jonaswood01 patch/u-boot/u-boot-meson-s4t7/ @adeepn @leggewie @pyavitz @rpardini patch/u-boot/u-boot-qemu-arm64/ @rpardini patch/u-boot/u-boot-qemu-x86/ @rpardini -patch/u-boot/u-boot-rk3506/ @amazingfate -patch/u-boot/u-boot-rockchip64-v2022.04/ @TRSx80 @ahoneybun @paolosabatino -patch/u-boot/u-boot-rockchip64/ @Tonymac32 @andyshrk @clee @igorpecovnik @prahal @redrathnure @sicXnull +patch/u-boot/u-boot-rk3506/ @amazingfate @vidplace7 +patch/u-boot/u-boot-rockchip64-v2022.04/ @ahoneybun @paolosabatino +patch/u-boot/u-boot-rockchip64/ @Tonymac32 @andyshrk @igorpecovnik @prahal @redrathnure @sicXnull patch/u-boot/u-boot-sunxi-crust/ @AGM1968 @Kreyren @PanderMusubi @Qvy-png @Tonymac32 @devdotnetorg @igorpecovnik @schwar3kat @spendist @teknoid patch/u-boot/u-boot-sunxi/ @1ubuntuuser @AGM1968 @DylanHP @Janmcha @JohnTheCoolingFan @Kreyren @PanderMusubi @Qvy-png @Ressetkk @StephenGraf @TheSnowfield @Tonymac32 @devdotnetorg @eliasbakken @igorpecovnik @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @schwar3kat @sgjava @sicXnull @spendist @teknoid patch/u-boot/u-boot-sunxi/board_bananapim3/ @AaronNGray @@ -283,45 +296,50 @@ patch/u-boot/u-boot-xpressreal/ @wei633 patch/u-boot/v2022.01/ @teknoid patch/u-boot/v2022.07/ @Tonymac32 @igorpecovnik patch/u-boot/v2022.10/ @NicoD-SBC -patch/u-boot/v2023.07.02/ @clee @engineer-80 +patch/u-boot/v2023.07.02/ @engineer-80 patch/u-boot/v2023.10/ @adeepn -patch/u-boot/v2024.01/ @Tonymac32 @rpardini +patch/u-boot/v2024.01/ @Tonymac32 patch/u-boot/v2024.04-rock5b-radxa/ @amazingfate @linhz0hz patch/u-boot/v2024.04/ @Tonymac32 @utlark patch/u-boot/v2024.07-coolpi-cm5/ @andyshrk patch/u-boot/v2024.07/ @adeepn @igorpecovnik patch/u-boot/v2024.07/board_station-m1/ @150balbes -patch/u-boot/v2024.10/ @alexl83 @brentr @pyavitz +patch/u-boot/v2024.10/ @brentr @pyavitz patch/u-boot/v2024.10/board_bigtreetech-cb2/ @JohnTheCoolingFan patch/u-boot/v2025-sunxi/ @The-going @alexl83 @chraac patch/u-boot/v2025.01-rc3-coolpi-cm5/ @andyshrk -patch/u-boot/v2025.01/ @ColorfulRhino @efectn @jeanrhum @joekhoobyar @pyavitz @rpardini @torte71 +patch/u-boot/v2025.01/ @jeanrhum @joekhoobyar @pyavitz @torte71 patch/u-boot/v2025.01/board_h96-tvbox-3566/ @hqnicolas -patch/u-boot/v2025.04/ @HeyMeco @IsMrX @NicoD-SBC @SuperKali @TheSnowfield @Tonymac32 @ZazaBR @amazingfate @andyshrk @biot @catalinii @fridtjof @mlegenovic @pyavitz @retro98boy @rpardini @vamzii -patch/u-boot/v2025.07/ @efectn @pyavitz -patch/u-boot/v2025.10/ @paolosabatino @rpardini +patch/u-boot/v2025.04/ @HeyMeco @IsMrX @NicoD-SBC @TheSnowfield @andyshrk @fridtjof @mlegenovic @retro98boy @rpardini +patch/u-boot/v2025.07/ @pyavitz +patch/u-boot/v2025.10/ @SuperKali @ZazaBR @alexl83 @amazingfate @catalinii @efectn @igorpecovnik @paolosabatino @pyavitz @rpardini @vamzii +patch/u-boot/v2025.10/board_9tripod-x3568-v4/ @rbqvq +patch/u-boot/v2026.01/ @ColorfulRhino @SuperKali @Tonymac32 @biot @rpardini sources/families/bcm2711.conf @PanderMusubi @teknoid sources/families/genio.conf @HeyMeco sources/families/imx8m.conf @schmiedelm sources/families/jethub.conf @adeepn -sources/families/k3.conf @Grippy98 @glneo +sources/families/k3-beagle.conf @Grippy98 +sources/families/k3.conf @Grippy98 @glneo @jonaswood01 sources/families/meson-axg.conf @pyavitz -sources/families/meson-g12a.conf @clee @engineer-80 +sources/families/meson-g12a.conf @engineer-80 sources/families/meson-g12b.conf @NicoD-SBC @Tonymac32 @jeanrhum @pyavitz @retro98boy @rpardini sources/families/meson-gxbb.conf @teknoid -sources/families/meson-gxl.conf @SteeManMI @Tonymac32 @igorpecovnik @jomadeto +sources/families/meson-gxl.conf @SteeManMI @Tonymac32 @igorpecovnik @jomadeto @retro98boy sources/families/meson-s4t7.conf @adeepn @leggewie @pyavitz @rpardini sources/families/meson-sm1.conf @Tonymac32 @biot @igorpecovnik @rpardini sources/families/meson8b.conf @hzyitc @juanlufont sources/families/mvebu.conf @Heisath @leggewie +sources/families/mvebu64.conf @igorpecovnik sources/families/odroidxu4.conf @joekhoobyar sources/families/phytium-embedded.conf @chainsx sources/families/qcs6490.conf @HeyMeco sources/families/realtek-rtd1619b.conf @wei633 sources/families/rk35xx.conf @CodeChenL @HeyMeco @SuperKali @ZazaBR @amazingfate @andyshrk @catalinii @efectn @hoochiwetech @hqnicolas @krachlatte @mattx433 @pyavitz @sputnik2019 @tdleiyao @vamzii -sources/families/rockchip-rk3588.conf @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @alexl83 @amazingfate @andyshrk @chainsx @efectn @fridtjof @ginkage @igorpecovnik @lanefu @linhz0hz @mahdichi @prahal @rpardini @schwar3kat -sources/families/rockchip.conf @amazingfate @paolosabatino -sources/families/rockchip64.conf @150balbes @JohnTheCoolingFan @TRSx80 @TheSnowfield @Tonymac32 @ahoneybun @andyshrk @brentr @clee @hqnicolas @igorpecovnik @joekhoobyar @mlegenovic @paolosabatino @prahal @redrathnure @retro98boy @rpardini @sicXnull @torte71 @utlark +sources/families/rockchip-rk3588.conf @150balbes @ColorfulRhino @HeyMeco @JackHuang021 @SeeleVolleri @SuperKali @Tonymac32 @alexl83 @amazingfate @andyshrk @chainsx @efectn @fridtjof @ginkage @igorpecovnik @kamilsaigol @lanefu @linhz0hz @mahdichi @prahal @rpardini @schwar3kat +sources/families/rockchip-rv1106.conf @vidplace7 +sources/families/rockchip.conf @amazingfate @paolosabatino @vidplace7 +sources/families/rockchip64.conf @150balbes @JohnTheCoolingFan @TheSnowfield @Tonymac32 @ahoneybun @andyshrk @brentr @hqnicolas @igorpecovnik @joekhoobyar @mlegenovic @paolosabatino @prahal @rbqvq @redrathnure @retro98boy @rpardini @sicXnull @torte71 @utlark sources/families/sm8250.conf @amazingfate sources/families/sm8550.conf @FantasyGmm sources/families/spacemit.conf @pyavitz @@ -337,4 +355,4 @@ sources/families/sun7i.conf @DylanHP @janprunk sources/families/sun8i.conf @1ubuntuuser @AaronNGray @Janmcha @StephenGraf @Tonymac32 @lbmendes @leggewie @mhawkins-consultant @sgjava @spendist sources/families/thead.conf @chainsx sources/families/uefi-arm64.conf @PeterChrz @rpardini -sources/families/uefi-x86.conf @davidandreoletti @rpardini +sources/families/uefi-x86.conf @rpardini diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3ea0080ea..1e7889ac4 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -19,5 +19,5 @@ contact_links: url: https://github.com/armbian/configng/issues/new about: Utility for configuring your board, adjusting services and installing applications. - name: Issue with infrastructure - url: https://github.com/armbian/mirror/issues/new + url: https://github.com/armbian/armbian-router/issues/new about: Broken download links or just slow download diff --git a/.github/workflows/clean-workflow-logs.yml b/.github/workflows/clean-workflow-logs.yml index bafb106a5..4d1d399a9 100644 --- a/.github/workflows/clean-workflow-logs.yml +++ b/.github/workflows/clean-workflow-logs.yml @@ -21,7 +21,7 @@ jobs: permissions: actions: write steps: - - uses: igorjs/gh-actions-clean-workflow@v6 + - uses: igorjs/gh-actions-clean-workflow@v7 with: runs_older_than: ${{ github.event.inputs.runs_older_than || env.SCHEDULED_RUNS_OLDER_THAN }} runs_to_keep: ${{ github.event.inputs.runs_to_keep || env.SCHEDULED_RUNS_TO_KEEP }} diff --git a/.github/workflows/merge-announce.yml b/.github/workflows/merge-announce.yml index 78dbd801e..1d609deaa 100644 --- a/.github/workflows/merge-announce.yml +++ b/.github/workflows/merge-announce.yml @@ -6,6 +6,8 @@ on: jobs: announcepush: + # Do not run this workflow in forks + if: ${{ github.repository == 'armbian/build' }} runs-on: ubuntu-latest steps: - name: Get repo diff --git a/.github/workflows/pr-kernel-security-analysis.yml b/.github/workflows/pr-kernel-security-analysis.yml index f478ca12b..df4e7561e 100644 --- a/.github/workflows/pr-kernel-security-analysis.yml +++ b/.github/workflows/pr-kernel-security-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@d03a93c0dbfac6d6dd6a0d8a5e7daff992b07449 # v46.0.3 + uses: tj-actions/changed-files@70069877f29101175ed2b055d210fe8b1d54d7d7 # v46.0.3 - name: Checkout repository uses: actions/checkout@v5 diff --git a/.github/workflows/pr-label-on-approved.yml b/.github/workflows/pr-label-on-approved.yml index 70ca45b27..f2479478d 100644 --- a/.github/workflows/pr-label-on-approved.yml +++ b/.github/workflows/pr-label-on-approved.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Download PR number artifact from upstream run - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: pr-number-${{ github.event.workflow_run.id }} # same unique name path: . diff --git a/.github/workflows/pr-lint-scripts.yml b/.github/workflows/pr-lint-scripts.yml index ae6566891..2285eb01e 100644 --- a/.github/workflows/pr-lint-scripts.yml +++ b/.github/workflows/pr-lint-scripts.yml @@ -30,7 +30,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@d03a93c0dbfac6d6dd6a0d8a5e7daff992b07449 # v46.0.3 + uses: tj-actions/changed-files@70069877f29101175ed2b055d210fe8b1d54d7d7 # v46.0.3 - name: List all changed files run: | diff --git a/.github/workflows/pr-review-listener.yml b/.github/workflows/pr-review-listener.yml index dfbbacc16..431c3360b 100644 --- a/.github/workflows/pr-review-listener.yml +++ b/.github/workflows/pr-review-listener.yml @@ -13,7 +13,7 @@ jobs: - name: Save PR number run: echo "${{ github.event.pull_request.number }}" > pr.txt - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: # unique name: includes workflow run id name: pr-number-${{ github.run_id }} diff --git a/.github/workflows/rewrite-kernel-configs.yml b/.github/workflows/rewrite-kernel-configs.yml index 360f99c40..d0da5c493 100644 --- a/.github/workflows/rewrite-kernel-configs.yml +++ b/.github/workflows/rewrite-kernel-configs.yml @@ -12,7 +12,7 @@ permissions: jobs: build-matrix: name: Build dynamic matrix - runs-on: ubuntu-latest + runs-on: super outputs: matrix: ${{ steps.gen.outputs.matrix }} count: ${{ steps.gen.outputs.count }} @@ -162,7 +162,7 @@ jobs: - name: Upload artifact (per job; unique; overwrite safe) if: steps.collect.outputs.nothing_to_upload != 'true' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: changes-${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }}-${{ github.run_attempt }} path: artifact/${{ matrix.linuxfamily }}-${{ matrix.branch }}-${{ matrix.board }} @@ -181,7 +181,7 @@ jobs: - name: Download all change artifacts (no merge) continue-on-error: true - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: path: _artifacts pattern: changes-* diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f102ec470..d8b1421ca 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: SARIF file path: results.sarif diff --git a/action.yml b/action.yml index 4e36b5c17..1c3a63b41 100644 --- a/action.yml +++ b/action.yml @@ -140,9 +140,33 @@ runs: - shell: bash run: | - # read version from upstream Armbian OS - cat os/stable.json | jq '.version' | sed "s/\"//g" | sed 's/^/ARMBIAN_VERSION=/' >> $GITHUB_ENV - [[ "${{ inputs.armbian_version }}" != '' ]] && echo "ARMBIAN_VERSION=${{ inputs.armbian_version }}" >> $GITHUB_ENV + # Resolve base version (prefer workflow input if provided) + BASE_VERSION="${{ inputs.armbian_version }}" + if [ -z "$BASE_VERSION" ]; then + BASE_VERSION="$(jq -r '.version' os/stable.json)" + fi + + # Preserve optional 'v' prefix but strip it for math + PREFIX='' + if [[ "$BASE_VERSION" == v* ]]; then + PREFIX='v' + BASE_NO_PREFIX="${BASE_VERSION#v}" + else + BASE_NO_PREFIX="$BASE_VERSION" + fi + + # Drop any pre-release/build metadata (e.g., -rc1, +meta) + CORE="${BASE_NO_PREFIX%%[-+]*}" + + # Split and increment patch + IFS='.' read -r MAJOR MINOR PATCH <<<"$CORE" + PATCH=${PATCH:-0} + NEXT_PATCH=$((PATCH + 1)) + NEXT_VERSION="${PREFIX}${MAJOR}.${MINOR}.${NEXT_PATCH}" + + { + echo "ARMBIAN_VERSION=${NEXT_VERSION}" + } >> "$GITHUB_ENV" # copy os userpatches and custom mkdir -pv build/userpatches diff --git a/config/boards/9tripod-x3568-v4.csc b/config/boards/9tripod-x3568-v4.csc new file mode 100644 index 000000000..10e90bd10 --- /dev/null +++ b/config/boards/9tripod-x3568-v4.csc @@ -0,0 +1,87 @@ +# Rockchip RK3568 quad core 2GB-8GB RAM SoC 2 x GBE eMMC USB3 WiFi/BT PCIe SATA NVMe +BOARD_NAME="9Tripod X3568 v4" +BOARDFAMILY="rockchip64" +BOARD_MAINTAINER="rbqvq" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +FULL_DESKTOP="yes" +BOOT_SOC="rk3568" +BOOT_LOGO="desktop" +BOOT_FDT_FILE="rockchip/rk3568-9tripod-x3568-v4.dtb" +IMAGE_PARTITION_TABLE="gpt" +MODULES="ledtrig_netdev" + +OVERLAY_PREFIX="rk3568-9tripod-x3568-v4" + +# Mainline U-Boot +function post_family_config__9tripod_x3568_v4_use_mainline_uboot() { + display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" + + declare -g BOOTCONFIG="9tripod-x3568-v4-rk3568_defconfig" + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10/board_${BOARD}" + + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" + + unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd + + function write_uboot_platform() { + dd if=$1/u-boot-rockchip.bin of=$2 seek=64 conv=notrunc status=none + } +} + +function post_family_tweaks__9tripod_x3568_v4_udev_network_interfaces() { + display_alert "$BOARD" "Renaming interfaces" "info" + + mkdir -p $SDCARD/etc/udev/rules.d/ + cat <<- EOF > "${SDCARD}/etc/udev/rules.d/70-persistent-net.rules" + SUBSYSTEM=="net", ACTION=="add", KERNELS=="fe010000.ethernet", NAME:="eth0" + SUBSYSTEM=="net", ACTION=="add", KERNELS=="fe2a0000.ethernet", NAME:="eth1" + EOF +} + +function post_family_tweaks_bsp__9tripod_x3568_v4_enable_leds() { + display_alert "$BOARD" "Creating Board Support LED Config" "info" + cat <<- EOF > "$destination"/etc/armbian-leds.conf + [/sys/class/leds/stmmac-0:03:amber:lan] + trigger=netdev + interval=52 + link_10=1 + link_100=1 + link_1000=1 + tx=1 + rx=1 + device_name=eth1 + + [/sys/class/leds/stmmac-0:03:green:lan] + trigger=netdev + interval=52 + link_10=1 + link_100=1 + link_1000=1 + tx=0 + rx=0 + device_name=eth1 + + [/sys/class/leds/stmmac-1:02:amber:lan] + trigger=netdev + interval=52 + link_10=1 + link_100=1 + link_1000=1 + tx=1 + rx=1 + device_name=eth0 + + [/sys/class/leds/stmmac-1:02:green:lan] + trigger=netdev + interval=52 + link_10=1 + link_100=1 + link_1000=1 + tx=0 + rx=0 + device_name=eth0 + EOF +} diff --git a/config/boards/README.md b/config/boards/README.md index 4e21e13cf..f89ef57b2 100644 --- a/config/boards/README.md +++ b/config/boards/README.md @@ -63,6 +63,11 @@ If you are unsure about the documentation then invoke `$ grep -r -A5 -B5 "BUILD_ - Values: - yes: Include (default) - no: Do NO include +- **POWER_MANAGEMENT_FEATURES** (boolean): Controls whether system sleep functionality (suspend, hibernate, hybrid sleep) is allowed on the built image. + - Values: + - yes: Enable power-management sleep features (allow systemd sleep modes) + - no: Disable all sleep modes (default), as suspend/hibernate are unstable + on most single-board computers - **HAS_VIDEO_OUTPUT** ( boolean ): defines whether the system has video output such as eye candy, bootsplash, etc.. - Values: - yes: Enable video-related configuration diff --git a/config/boards/armsom-forge1.csc b/config/boards/armsom-forge1.csc index 8434b6406..4000f419a 100644 --- a/config/boards/armsom-forge1.csc +++ b/config/boards/armsom-forge1.csc @@ -1,7 +1,7 @@ # Rockchip RK3506J triple core 512MB SoC 2x100MBe NAND USB2 BOARD_NAME="ArmSoM Forge1" BOARDFAMILY="rockchip" -BOOTCONFIG="generic-rk3506_defconfig" +BOOTCONFIG="forge1-rk3506b_defconfig" BOARD_MAINTAINER="amazingfate" KERNEL_TARGET="vendor" BOOT_FDT_FILE="rk3506b-armsom-forge1.dtb" diff --git a/config/boards/bananapim5pro.conf b/config/boards/bananapim5pro.conf index 3230e9b5c..ecfdd24b7 100644 --- a/config/boards/bananapim5pro.conf +++ b/config/boards/bananapim5pro.conf @@ -4,6 +4,7 @@ BOARD_NAME="Banana Pi M5 Pro" BOARD_MAINTAINER="efectn" BOOTCONFIG="bananapi-m5-pro-rk3576_defconfig" BOOT_FDT_FILE="rockchip/rk3576-bananapi-m5-pro.dtb" -# Those are included in armsom-sige5.csc, but this file is parsed directly by the JSON matrix generator and thus those need to be in here +# Those are included in armsom-sige5.csc, but this file is parsed directly +# by the JSON matrix generator and thus those need to be in here KERNEL_TARGET="edge,vendor" BOARDFAMILY="rk35xx" diff --git a/config/boards/bananapim7.conf b/config/boards/bananapim7.conf index 82317be80..d0ec62b94 100644 --- a/config/boards/bananapim7.conf +++ b/config/boards/bananapim7.conf @@ -3,7 +3,8 @@ source "${SRC}/config/boards/armsom-sige7.csc" BOARD_NAME="Banana Pi M7" BOARD_MAINTAINER="amazingfate" BOOT_FDT_FILE="rockchip/rk3588-bananapi-m7.dtb" -# Those are included in armsom-sige7.csc, but this file is parsed directly by the JSON matrix generator and thus those need to be in here +# Those are included in armsom-sige7.csc, but this file is parsed directly +# by the JSON matrix generator and thus those need to be in here KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" BOARDFAMILY="rockchip-rk3588" diff --git a/config/boards/beaglebone-ai64.conf b/config/boards/beaglebone-ai64.conf index 5b5fd5835..d83d71476 100644 --- a/config/boards/beaglebone-ai64.conf +++ b/config/boards/beaglebone-ai64.conf @@ -1,8 +1,9 @@ -# BeagleBone® AI-64 dual core 4GB GBE USB3 OSPI DisplayPort HDMI +# BeagleBone AI-64 Texas Instruments TDA4VM dual core 4GB GBE USB3 OSPI DisplayPort HDMI BOARD_NAME="BeagleBone AI-64" BOARDFAMILY="k3" BOARD_MAINTAINER="Grippy98" +BOOT_SOC="j721e" BOOTCONFIG="j721e_beagleboneai64_a72_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-j721e-beagleboneai64.dts" @@ -12,8 +13,8 @@ SYSFW_FILE="sysfw-j721e-gp-evm.itb" TISPL_FILE="tispl.bin_unsigned" UBOOT_FILE="u-boot.img_unsigned" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="generic" OPTEE_ARGS="" diff --git a/config/boards/beagleplay.conf b/config/boards/beagleplay.conf index 86fe9afb3..6a82c71fb 100644 --- a/config/boards/beagleplay.conf +++ b/config/boards/beagleplay.conf @@ -1,8 +1,9 @@ -# TI AM62 quad core 2GB DDR4 16GB eMMC 1xGBE 1xSPE HDMI +# BeaglePlay Texas Instruments AM62 quad core 2GB DDR4 eMMC GBE SPE HDMI BOARD_NAME="BeaglePlay" BOARDFAMILY="k3" BOARD_MAINTAINER="Grippy98" +BOOT_SOC="am62" BOOTCONFIG="am62x_beagleplay_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am625-beagleplay.dts" @@ -11,8 +12,8 @@ TIBOOT3_FILE="tiboot3-am62x-gp-evm.bin" TISPL_FILE="tispl.bin_unsigned" UBOOT_FILE="u-boot.img_unsigned" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="lite" OPTEE_ARGS="CFG_TEE_CORE_LOG_LEVEL=1" diff --git a/config/boards/beagley-ai.conf b/config/boards/beagley-ai.conf index 06de04ceb..45db99a9c 100644 --- a/config/boards/beagley-ai.conf +++ b/config/boards/beagley-ai.conf @@ -1,33 +1,19 @@ -# Texas Instruments AM67A quad core 4GB USB3 DDR4 4TOPS +# BeagleY-AI Texas Instruments AM67A quad core 4GB DDR4 USB3 4TOPS BOARD_NAME="BeagleY-AI" -BOARDFAMILY="k3" +BOARDFAMILY="k3-beagle" BOARD_MAINTAINER="Grippy98" +BOOT_SOC="j722s" BOOTCONFIG="am67a_beagley_ai_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="k3-am67a-beagley-ai.dts" TIBOOT3_BOOTCONFIG="am67a_beagley_ai_r5_defconfig" TIBOOT3_FILE="tiboot3-j722s-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="lite" OPTEE_ARGS="" OPTEE_PLATFORM="k3-am62x" CC33XX_SUPPORT="yes" - -# Use these branches until BeagleY-AI goes upstream -function post_family_config_branch_current__beagley_ai_use_beagle_kernel_uboot() { - display_alert "$BOARD" " Beagleboard U-Boot and kernel overrides for $BOARD / $BRANCH" "info" - - declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel - declare -g KERNEL_MAJOR_MINOR="6.6" - declare -g KERNELBRANCH="branch:v6.6.58-ti-arm64-r21" - declare -g LINUXFAMILY="k3-beagle" # Separate kernel package from the regular `k3` family - declare -g LINUXCONFIG="linux-k3-${BRANCH}" - - declare -g BOOTSOURCE="https://github.com/glneo/u-boot" # v2025.04-rc3 + BeagleY-AI support - declare -g BOOTBRANCH="branch:beagley-ai" - declare -g BOOTPATCHDIR="u-boot-beagle" -} diff --git a/config/boards/bestv-r3300-l.csc b/config/boards/bestv-r3300-l.csc new file mode 100644 index 000000000..6c1ceac39 --- /dev/null +++ b/config/boards/bestv-r3300-l.csc @@ -0,0 +1,53 @@ +# Amlogic S905L-B 1GB RAM 8GB eMMC microSD FE USB2 RTL8189FTV WiFi +BOARD_NAME="BesTV R3300-L" +BOARDFAMILY="meson-gxl" +BOARD_MAINTAINER="retro98boy" +BOOTCONFIG="bestv-r3300-l_defconfig" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +FULL_DESKTOP="yes" +SERIALCON="ttyAML0" +BOOT_LOGO="desktop" +BOOT_FDT_FILE="amlogic/meson-gxl-s905x-bestv-r3300-l.dtb" +PACKAGE_LIST_BOARD="alsa-ucm-conf" # Contain ALSA UCM top-level configuration file +BOOTBRANCH_BOARD="tag:v2025.04" +BOOTPATCHDIR="v2025.04" + +enable_extension "gxlimg" +enable_extension "amlogic-fip-blobs" + +function post_family_config__use_repacked_fip() { + declare -g UBOOT_TARGET_MAP="u-boot.bin" + unset write_uboot_platform + + function write_uboot_platform() { + dd if="$1/u-boot.bin" of="$2" bs=512 seek=1 conv=fsync,notrunc 2>&1 + } +} + +function post_uboot_custom_postprocess__repack_vendor_fip_with_mainline_uboot() { + gxlimg_repack_fip_with_new_uboot \ + "${SRC}/cache/sources/amlogic-fip-blobs/bestv-r3300-l/bootloader.PARTITION" \ + gxl +} + +function post_family_tweaks_bsp__bestv-r3300-l() { + display_alert "${BOARD}" "Installing ALSA UCM configuration files" "info" + + # Use ALSA UCM via CLI: + # alsactl init && alsaucm set _verb "HiFi" set _enadev "HDMI" + # or + # alsactl init && alsaucm set _verb "HiFi" set _enadev "Lineout" + # playback: aplay -D plughw:S905XP212,0 /usr/share/sounds/alsa/Front_Center.wav + + install -Dm644 "${SRC}/packages/bsp/S905X-P212/S905X-P212-HiFi.conf" \ + "${destination}/usr/share/alsa/ucm2/Amlogic/gx-sound-card/S905X-P212-HiFi.conf" + install -Dm644 "${SRC}/packages/bsp/S905X-P212/S905X-P212.conf" \ + "${destination}/usr/share/alsa/ucm2/Amlogic/gx-sound-card/S905X-P212.conf" + + if [ ! -d "${destination}/usr/share/alsa/ucm2/conf.d/gx-sound-card" ]; then + mkdir -p "${destination}/usr/share/alsa/ucm2/conf.d/gx-sound-card" + fi + ln -sfv /usr/share/alsa/ucm2/Amlogic/gx-sound-card/S905X-P212.conf \ + "${destination}/usr/share/alsa/ucm2/conf.d/gx-sound-card/S905X-P212.conf" +} diff --git a/config/boards/bigtreetech-cb2.conf b/config/boards/bigtreetech-cb2.conf index f28809e7a..bf89d0219 100644 --- a/config/boards/bigtreetech-cb2.conf +++ b/config/boards/bigtreetech-cb2.conf @@ -21,11 +21,10 @@ function post_family_config__bigtreetech-cb2_uboot_overrides() { DDR_BLOB="rk35/rk3566_ddr_1056MHz_v1.21.bin" BL31_BLOB="rk35/rk3568_bl31_v1.44.elf" # NOT a typo, bl31 is shared across 68 and 66 - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc + declare -g BOOTDELAY=1 declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2024.10" declare -g BOOTPATCHDIR="v2024.10/board_bigtreetech-cb2" - #declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -45,5 +44,3 @@ function post_family_config__bigtreetech-cb2_uboot_overrides() { flashcp "${extra_opts_flashcp[@]}" "${1}/u-boot-rockchip-spi.bin" /dev/mtd0 } } - -# vim: ft=bash diff --git a/config/boards/cainiao-cniot-core.csc b/config/boards/cainiao-cniot-core.csc index 92ede0850..797865880 100644 --- a/config/boards/cainiao-cniot-core.csc +++ b/config/boards/cainiao-cniot-core.csc @@ -11,9 +11,11 @@ SERIALCON="ttyAML0" BOOT_LOGO="desktop" BOOT_FDT_FILE="amlogic/meson-g12b-a311d-cainiao-cniot-core.dtb" PACKAGE_LIST_BOARD="alsa-ucm-conf" # Contain ALSA UCM top-level configuration file - BOOTBRANCH_BOARD="tag:v2025.04" -BOOTPATCHDIR="v2025.04" # This has a patch that adds support for CAINIAO CNIoT-CORE. +BOOTPATCHDIR="v2025.04" + +enable_extension "gxlimg" +enable_extension "amlogic-fip-blobs" function post_family_config__use_repacked_fip() { declare -g UBOOT_TARGET_MAP="u-boot.bin" @@ -25,55 +27,22 @@ function post_family_config__use_repacked_fip() { } function post_uboot_custom_postprocess__repack_vendor_fip_with_mainline_uboot() { - display_alert "${BOARD}" "Repacking vendor FIP with mainline u-boot.bin" "info" - - BLOBS_DIR="${SRC}/cache/sources/amlogic-fip-blobs/cainiao-cniot-core" - EXTRACT_DIR="${BLOBS_DIR}/extract" - - rm -rf "$EXTRACT_DIR" - mkdir "$EXTRACT_DIR" - run_host_command_logged gxlimg -e "${BLOBS_DIR}/DDR.USB" "$EXTRACT_DIR" - - mv u-boot.bin raw-u-boot.bin - rm -f "${EXTRACT_DIR}/bl33.enc" - run_host_command_logged gxlimg \ - -t bl3x \ - -s raw-u-boot.bin \ - "${EXTRACT_DIR}/bl33.enc" - run_host_command_logged gxlimg \ - -t fip \ - --bl2 "${EXTRACT_DIR}/bl2.sign" \ - --ddrfw "${EXTRACT_DIR}/ddr4_1d.fw" \ - --ddrfw "${EXTRACT_DIR}/ddr4_2d.fw" \ - --ddrfw "${EXTRACT_DIR}/ddr3_1d.fw" \ - --ddrfw "${EXTRACT_DIR}/piei.fw" \ - --ddrfw "${EXTRACT_DIR}/lpddr4_1d.fw" \ - --ddrfw "${EXTRACT_DIR}/lpddr4_2d.fw" \ - --ddrfw "${EXTRACT_DIR}/diag_lpddr4.fw" \ - --ddrfw "${EXTRACT_DIR}/aml_ddr.fw" \ - --ddrfw "${EXTRACT_DIR}/lpddr3_1d.fw" \ - --bl30 "${EXTRACT_DIR}/bl30.enc" \ - --bl31 "${EXTRACT_DIR}/bl31.enc" \ - --bl33 "${EXTRACT_DIR}/bl33.enc" \ - --rev v3 u-boot.bin - - if [ ! -s u-boot.bin ]; then - display_alert "${BOARD}" "FIP repack produced empty u-boot.bin" "err" - exit 1 - fi + gxlimg_repack_fip_with_new_uboot \ + "${SRC}/cache/sources/amlogic-fip-blobs/cainiao-cniot-core/DDR.USB" \ + g12b } function post_family_tweaks_bsp__cainiao-cniot-core() { display_alert "${BOARD}" "Installing ALSA UCM configuration files" "info" - # Use ALSA UCM via GUI: Install a desktop environment such as GNOME, PipeWire, and WirePlumber. - # Use ALSA UCM via CLI: alsactl init && alsaucm set _verb "HiFi" set _enadev "HDMI" set _enadev "Speaker" # playback via HDMI: aplay -D plughw:cainiaocniotcor,0 /usr/share/sounds/alsa/Front_Center.wav # playback via internal speaker: aplay -D plughw:cainiaocniotcor,1 /usr/share/sounds/alsa/Front_Center.wav - install -Dm644 "${SRC}/packages/bsp/cainiao-cniot-core/cainiao-cniot-core-HiFi.conf" "${destination}/usr/share/alsa/ucm2/Amlogic/axg-sound-card/cainiao-cniot-core-HiFi.conf" - install -Dm644 "${SRC}/packages/bsp/cainiao-cniot-core/cainiao-cniot-core.conf" "${destination}/usr/share/alsa/ucm2/Amlogic/axg-sound-card/cainiao-cniot-core.conf" + install -Dm644 "${SRC}/packages/bsp/cainiao-cniot-core/cainiao-cniot-core-HiFi.conf" \ + "${destination}/usr/share/alsa/ucm2/Amlogic/axg-sound-card/cainiao-cniot-core-HiFi.conf" + install -Dm644 "${SRC}/packages/bsp/cainiao-cniot-core/cainiao-cniot-core.conf" \ + "${destination}/usr/share/alsa/ucm2/Amlogic/axg-sound-card/cainiao-cniot-core.conf" if [ ! -d "${destination}/usr/share/alsa/ucm2/conf.d/axg-sound-card" ]; then mkdir -p "${destination}/usr/share/alsa/ucm2/conf.d/axg-sound-card" diff --git a/config/boards/cherryba-m1.csc b/config/boards/cherryba-m1.csc index f4fbfe3d0..0e67d6c41 100644 --- a/config/boards/cherryba-m1.csc +++ b/config/boards/cherryba-m1.csc @@ -4,7 +4,7 @@ BOARDFAMILY="sun50iw9" BOOTCONFIG="cherryba-m1_defconfig" BOOT_LOGO="desktop" KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current,edge" # in case different then kernel target +KERNEL_TEST_TARGET="current,edge" FORCE_BOOTSCRIPT_UPDATE="yes" BOOTBRANCH_BOARD="tag:v2025.04" BOOTPATCHDIR="v2025.04" diff --git a/config/boards/cm3588-nas.csc b/config/boards/cm3588-nas.csc index 185731d3c..4070206ad 100644 --- a/config/boards/cm3588-nas.csc +++ b/config/boards/cm3588-nas.csc @@ -41,11 +41,11 @@ function post_family_tweaks__cm3588_nas_udev_naming_network_interfaces() { function post_family_config__cm3588_nas_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot - declare -g BOOTBRANCH="tag:v2025.01" - declare -g BOOTPATCHDIR="v2025.01" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2026.01-rc2" + declare -g BOOTPATCHDIR="v2026.01" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # Disable stuff from rockchip64_common; we're using binman here which does all the work @@ -80,12 +80,15 @@ function pre_config_uboot_target__cm3588_patch_rockchip_common_boot_order() { function post_config_uboot_target__extra_configs_for_cm3588-nas_uboot() { display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable preboot & flash user LED in preboot" "info" run_host_command_logged scripts/config --enable CONFIG_USE_PREBOOT - run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led led-1 on; sleep 0.1; led led-1 off'" # double quotes required due to run_host_command_logged's quirks + run_host_command_logged scripts/config --set-str CONFIG_PREBOOT "'led green on; sleep 0.1; led green off'" # double quotes required due to run_host_command_logged's quirks display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable EFI debugging commands" "info" run_host_command_logged scripts/config --enable CMD_EFIDEBUG run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info" run_host_command_logged scripts/config --enable CONFIG_LZO run_host_command_logged scripts/config --enable CONFIG_BZIP2 diff --git a/config/boards/coolpi-genbook.csc b/config/boards/coolpi-genbook.csc index 14175dca0..36500022c 100644 --- a/config/boards/coolpi-genbook.csc +++ b/config/boards/coolpi-genbook.csc @@ -18,7 +18,7 @@ IMAGE_PARTITION_TABLE="gpt" function post_family_config__coolpi-genbook_use_mainline_uboot() { display_alert "$BOARD" "mainline (next branch) u-boot overrides for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" unset BOOTBRANCH declare -g BOOTPATCHDIR="v2025.01-rc3-coolpi-cm5" declare -g BOOTBRANCH_BOARD="tag:v2025.04" diff --git a/config/boards/dshanpi-r1.csc b/config/boards/dshanpi-r1.csc index 819d62407..c5bccc0a8 100644 --- a/config/boards/dshanpi-r1.csc +++ b/config/boards/dshanpi-r1.csc @@ -13,13 +13,12 @@ IMAGE_PARTITION_TABLE="gpt" function post_family_config__dshanpi-r1_use_mainline_uboot() { display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - unset BOOTFS_TYPE # fixes armbian-install and unneeded for modern uboot anyway declare -g BOOTCONFIG="dshanpi-r1-rk3568_defconfig" declare -g BOOTDELAY=1 declare -g BOOTSOURCE="https://github.com/u-boot/u-boot" declare -g BOOTBRANCH="tag:v2024.10" declare -g BOOTPATCHDIR="v2024.10" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/espressobin.eos b/config/boards/espressobin.conf similarity index 78% rename from config/boards/espressobin.eos rename to config/boards/espressobin.conf index e6adb61b4..b82c91f41 100644 --- a/config/boards/espressobin.eos +++ b/config/boards/espressobin.conf @@ -1,7 +1,8 @@ # Marvell Armada 37x 512MB-2GB RAM SoC 1xmPCIe 1xSATA 3xGBE USB3.0 eMMC SPI BOARD_NAME="Espressobin" BOARDFAMILY="mvebu64" -BOARD_MAINTAINER="" +BOARD_MAINTAINER="igorpecovnik" BOOTCONFIG="mvebu_espressobin-88f3720_defconfig" HAS_VIDEO_OUTPUT="no" KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" diff --git a/config/boards/helios64.conf b/config/boards/helios64.conf index bafbd9cc1..9bd8b63b3 100644 --- a/config/boards/helios64.conf +++ b/config/boards/helios64.conf @@ -9,10 +9,15 @@ KERNEL_TEST_TARGET="current" MODULES="lm75 ledtrig-netdev" MODULES_LEGACY="lm75" FULL_DESKTOP="yes" -PACKAGE_LIST_BOARD="mdadm i2c-tools fancontrol" +PACKAGE_LIST_BOARD="mdadm i2c-tools fancontrol watchdog" PACKAGE_LIST_BOARD_REMOVE="fake-hwclock" CPUMAX="1800000" +if [[ "$ROOTFS_TYPE" =~ btrfs|f2fs|nilfs2|nfs|xfs ]]; then + BOOTFS_TYPE=${BOOTFS_TYPE:-ext4} + BOOTPART_REQUIRED=${BOOTPART_REQUIRED:-yes} +fi + function post_family_tweaks__helios64_enable_heartbeat() { display_alert "$BOARD" "Installing board tweaks" "info" @@ -41,6 +46,9 @@ function post_family_tweaks_bsp__helios64() { install -m 644 $SRC/packages/bsp/helios64/fancontrol.service.pid-override $destination/etc/systemd/system/fancontrol.service.d/pid.conf + # helios64 points fancontrol to /dev symlinks created by helios64 udev rules to sysfs hwmon and thermal directories + install -m 644 $SRC/packages/bsp/helios64/fancontrol.service.privatedevices-override $destination/etc/systemd/system/fancontrol.service.d/privatedevices.conf + # copy fancontrol config install -m 644 $SRC/packages/bsp/helios64/fancontrol.conf $destination/etc/fancontrol diff --git a/config/boards/inovato-quadra.conf b/config/boards/inovato-quadra.conf index 074034346..643199895 100644 --- a/config/boards/inovato-quadra.conf +++ b/config/boards/inovato-quadra.conf @@ -7,9 +7,6 @@ CRUSTCONFIG="tanix_tx6_defconfig" BOOT_FDT_FILE="allwinner/sun50i-h6-inovato-quadra.dtb" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current" -#BOOTBRANCH="tag:v2025.04" -#BOOTPATCHDIR="v2025-sunxi" -#OVERLAY_PREFIX="sun50i-h6" BOOT_LOGO="desktop" FULL_DESKTOP="yes" SRC_EXTLINUX="yes" diff --git a/config/boards/jethubj200.conf b/config/boards/jethubj200.conf index 72da7e2a4..7ff97b100 100644 --- a/config/boards/jethubj200.conf +++ b/config/boards/jethubj200.conf @@ -10,4 +10,3 @@ PACKAGE_LIST_BOARD="libubootenv-tool apparmor rfkill bluetooth bluez bluez-tools MODULES_BLACKLIST="simpledrm" # SimpleDRM conflicts with Panfrost FULL_DESKTOP="yes" SERIALCON="ttyAML0" -#BOOT_LOGO="desktop" diff --git a/config/boards/jetson-nano.csc b/config/boards/jetson-nano.csc index edd2d1c9f..04b6df7d7 100644 --- a/config/boards/jetson-nano.csc +++ b/config/boards/jetson-nano.csc @@ -4,9 +4,7 @@ declare -g BOARDFAMILY="uefi-arm64" declare -g BOARD_MAINTAINER="" declare -g KERNEL_TARGET="current,edge" declare -g KERNEL_TEST_TARGET="current" - declare -g BOOT_LOGO=desktop - declare -g GRUB_CMDLINE_LINUX_DEFAULT="efi=noruntime console=ttyS0,115200n8" declare -g BOOT_FDT_FILE="nvidia/tegra210-p3450-0000.dtb" enable_extension "grub-with-dtb" diff --git a/config/boards/khadas-edge2.conf b/config/boards/khadas-edge2.conf index b7068d504..0428c4bf3 100644 --- a/config/boards/khadas-edge2.conf +++ b/config/boards/khadas-edge2.conf @@ -6,7 +6,6 @@ declare -g BOOT_SOC="rk3588" # Just to avoid errors in rockchip64_commmon declare -g KERNEL_TARGET="current,edge,vendor" declare -g KERNEL_TEST_TARGET="vendor,current" declare -g IMAGE_PARTITION_TABLE="gpt" -declare -g KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1" declare -g BOOT_FDT_FILE="rockchip/rk3588s-khadas-edge2.dtb" # Specific to this board declare -g BLUETOOTH_HCIATTACH_PARAMS="-s 115200 /dev/ttyS9 bcm43xx 1500000" # For the bluetooth-hciattach extension @@ -15,6 +14,8 @@ enable_extension "bluetooth-hciattach" # E declare -g KHADAS_OOWOW_BOARD_ID="Edge2" # for use with EXT=output-image-oowow declare -g UEFI_EDK2_BOARD_ID="edge2" # This _only_ used for uefi-edk2-rk3588 extension +declare -g BL32_BLOB='rk35/rk3588_bl32_v1.15.bin' + function post_family_tweaks__kedge2_naming_audios() { display_alert "$BOARD" "Renaming khadas-edge2 audios" "info" @@ -26,10 +27,12 @@ function post_family_tweaks__kedge2_naming_audios() { return 0 } -declare -g BL32_BLOB='rk35/rk3588_bl32_v1.15.bin' - # for the kedge2, we're counting on the blobs+u-boot in SPI working, as it comes from factory. It does not support bootscripts. function post_family_config__uboot_kedge2() { + if [[ $BRANCH == "edge" || $BRANCH == "current" ]]; then + return + fi + display_alert "$BOARD" "Configuring ($BOARD) u-boot" "info" declare -g BOOTSOURCE='https://github.com/khadas/u-boot.git' @@ -38,3 +41,21 @@ function post_family_config__uboot_kedge2() { declare -g BOOTCONFIG="khadas-edge2-rk3588s_defconfig" declare -g SRC_EXTLINUX="yes" # For now, use extlinux. Thanks Monka } + +# Mainline U-Boot for current kernel +function post_family_config__kedge2_use_mainline_uboot() { + if [[ $BRANCH == "vendor" ]]; then + return + fi + + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" + + declare -g BOOTCONFIG="khadas-edge2-rk3588s_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" + unset uboot_custom_postprocess # disable stuff from rockchip64_common; we're using binman here which does all the work already +} diff --git a/config/boards/khadas-vim3l.conf b/config/boards/khadas-vim3l.conf index 4f8f07853..c6c1bf84e 100644 --- a/config/boards/khadas-vim3l.conf +++ b/config/boards/khadas-vim3l.conf @@ -12,8 +12,8 @@ BOOT_LOGO="desktop" BOOT_FDT_FILE="amlogic/meson-sm1-khadas-vim3l.dtb" ASOUND_STATE="asound.state.khadas-vim3l" -BOOTBRANCH_BOARD="tag:v2024.01" -BOOTPATCHDIR="v2024.01" # this has 'board_khadas-vim3' which has a patch to boot USB/NVMe/SCSI first +BOOTBRANCH_BOARD="tag:v2026.01-rc2" +BOOTPATCHDIR="v2026.01" # this has 'board_khadas-vim3' which has a patch to boot USB/NVMe/SCSI first declare -g KHADAS_OOWOW_BOARD_ID="VIM3L" # for use with EXT=output-image-oowow @@ -44,15 +44,30 @@ function post_uboot_custom_postprocess__khadas_vim3l_uboot() { # Enable extra u-boot .config options, this way we avoid patching defconfig function post_config_uboot_target__extra_configs_for_khadas_vim3l() { + display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info" + run_host_command_logged scripts/config --enable CMD_EFIDEBUG + run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI + + display_alert "u-boot for ${BOARD}" "u-boot: enable I2C support" "info" + run_host_command_logged scripts/config --enable CONFIG_DM_I2C + run_host_command_logged scripts/config --enable CONFIG_SYS_I2C_MESON + run_host_command_logged scripts/config --enable CONFIG_CMD_I2C + + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info" run_host_command_logged scripts/config --enable CONFIG_LZO run_host_command_logged scripts/config --enable CONFIG_BZIP2 run_host_command_logged scripts/config --enable CONFIG_ZSTD + display_alert "u-boot for ${BOARD}" "u-boot: enable kaslrseed support" "info" run_host_command_logged scripts/config --enable CONFIG_CMD_KASLRSEED + display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info" run_host_command_logged scripts/config --enable CONFIG_LED run_host_command_logged scripts/config --enable CONFIG_LED_GPIO + display_alert "u-boot for ${BOARD}" "u-boot: enable networking cmds" "info" run_host_command_logged scripts/config --enable CONFIG_CMD_NFS run_host_command_logged scripts/config --enable CONFIG_CMD_WGET diff --git a/config/boards/lckfb-taishanpi.csc b/config/boards/lckfb-taishanpi.csc index 002192ed6..42fe8d3f2 100644 --- a/config/boards/lckfb-taishanpi.csc +++ b/config/boards/lckfb-taishanpi.csc @@ -17,7 +17,7 @@ function post_family_config__tspi_use_radxa_vendor() { BOOTSOURCE="https://github.com/u-boot/u-boot" BOOTBRANCH="tag:v2025.04" BOOTPATCHDIR="v2025.04" - BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + BOOTDIR="u-boot-${BOARD}" UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/longanpi-3h.csc b/config/boards/longanpi-3h.csc index d0ab4ee7d..40e2c9d08 100644 --- a/config/boards/longanpi-3h.csc +++ b/config/boards/longanpi-3h.csc @@ -5,7 +5,7 @@ BOARD_MAINTAINER="" BOOTCONFIG="longanpi_3h_defconfig" BOOTBRANCH="tag:v2024.10" BOOTPATCHDIR="v2024.10" -BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory +BOOTDIR="u-boot-${BOARD}" BOOT_LOGO="desktop" OVERLAY_PREFIX="sun50i-h616" KERNEL_TARGET="current,edge" diff --git a/config/boards/lubancat2.csc b/config/boards/lubancat2.csc index 4a6404617..8244869e3 100644 --- a/config/boards/lubancat2.csc +++ b/config/boards/lubancat2.csc @@ -15,7 +15,7 @@ IMAGE_PARTITION_TABLE="gpt" function post_family_config_branch_edge__lubancat_2_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2025.04" declare -g BOOTPATCHDIR="v2025.04" # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency diff --git a/config/boards/luckfox-lyra-plus.csc b/config/boards/luckfox-lyra-plus.csc new file mode 100644 index 000000000..05cdeb09f --- /dev/null +++ b/config/boards/luckfox-lyra-plus.csc @@ -0,0 +1,15 @@ +# Rockchip RK3506G2 triple core 128MB SoC 1x100MBe NAND SD USB2 +BOARD_NAME="Luckfox Lyra Plus" +BOARDFAMILY="rockchip" +BOOTCONFIG="luckfox-lyra-rk3506_defconfig" +BOARD_MAINTAINER="vidplace7" +KERNEL_TARGET="vendor" +BOOT_FDT_FILE="rk3506g-luckfox-lyra-plus-sd.dtb" +BOOT_SCENARIO="spl-blobs" +IMAGE_PARTITION_TABLE="gpt" +SERIALCON="ttyFIQ0" +BOOT_SOC="rk3506" +DDR_BLOB="rk35/rk3506_ddr_750MHz_v1.06.bin" + +# Board only has 128MB RAM; use 'lowmem' extension to optimize for this. +enable_extension "lowmem" diff --git a/config/boards/luckfox-lyra-ultra-w.csc b/config/boards/luckfox-lyra-ultra-w.csc new file mode 100644 index 000000000..5ec2044ad --- /dev/null +++ b/config/boards/luckfox-lyra-ultra-w.csc @@ -0,0 +1,14 @@ +# Rockchip RK3506B triple core 512MB SoC 1x100MBe WIFI/BT EMMC USB2 +BOARD_NAME="Luckfox Lyra Ultra W" +BOARDFAMILY="rockchip" +BOOTCONFIG="luckfox-lyra-ultra-rk3506b_defconfig" +BOARD_MAINTAINER="vidplace7" +KERNEL_TARGET="vendor" +BOOT_FDT_FILE="rk3506b-luckfox-lyra-ultra-w.dtb" +BOOT_SCENARIO="spl-blobs" +IMAGE_PARTITION_TABLE="gpt" +enable_extension "radxa-aic8800" +AIC8800_TYPE="usb" +BOOT_SOC="rk3506" +DDR_BLOB="rk35/rk3506b_ddr_750MHz_v1.06.bin" +PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools" diff --git a/config/boards/luckfox-pico-max.csc b/config/boards/luckfox-pico-max.csc new file mode 100644 index 000000000..a1e6048f8 --- /dev/null +++ b/config/boards/luckfox-pico-max.csc @@ -0,0 +1,12 @@ +# Rockchip RV1106 single core 128-256MB SoC 1x100MBe NAND USB2 +BOARD_NAME="Luckfox Pico Pro / Pico Max" +BOARDFAMILY="rockchip-rv1106" +BOOTCONFIG="luckfox_rv1106_uboot_defconfig" +BOARD_MAINTAINER="" +KERNEL_TARGET="vendor" +BOOT_FDT_FILE="rv1106g-luckfox-pico-pro-max.dtb" +IMAGE_PARTITION_TABLE="gpt" +BOOT_SOC="rv1106" + +# Board has 128MB - 256MB RAM; use 'lowmem' extension to optimize for this. +enable_extension "lowmem" diff --git a/config/boards/luckfox-pico-mini.csc b/config/boards/luckfox-pico-mini.csc new file mode 100644 index 000000000..77e64610c --- /dev/null +++ b/config/boards/luckfox-pico-mini.csc @@ -0,0 +1,16 @@ +# Rockchip RV1103 single core 64MB SoC 1x100MBe NAND USB2 +BOARD_NAME="Luckfox Pico Mini" +BOARDFAMILY="rockchip-rv1106" +BOOTCONFIG="luckfox_rv1106_uboot_defconfig" +BOARD_MAINTAINER="vidplace7" +KERNEL_TARGET="vendor" +BOOT_FDT_FILE="rv1103g-luckfox-pico-mini.dtb" +IMAGE_PARTITION_TABLE="gpt" +# RV1103 but uses RV1106 blobs (doesn't work with RV1103 blobs) +BOOT_SOC="rv1103" +DDR_BLOB="rv11/rv1106_ddr_924MHz_v1.15.bin" +TEE_BLOB="rv11/rv1106_tee_ta_v1.13.bin" +USBPLUG_BLOB="rv11/rv1106_usbplug_v1.09.bin" + +# Board only has 64MB RAM; use 'lowmem' extension to optimize for this. +enable_extension "lowmem" diff --git a/config/boards/mba8mpxl-ras314.conf b/config/boards/mba8mpxl-ras314.conf index 78058c0ad..e97a206f5 100644 --- a/config/boards/mba8mpxl-ras314.conf +++ b/config/boards/mba8mpxl-ras314.conf @@ -16,7 +16,11 @@ ASOUND_STATE="asound.state.tqma" function post_family_tweaks_bsp__mba8mpxl-ras314() { # Wifi & Bluetooth (use firmware from NXP) - wget https://github.com/nxp-imx/imx-firmware/raw/lf-6.6.3_1.0.0/nxp/FwImage_8997/pcieuart8997_combo_v4.bin + curl -fLOJ https://github.com/nxp-imx/imx-firmware/raw/lf-6.6.3_1.0.0/nxp/FwImage_8997/pcieuart8997_combo_v4.bin || { + echo "download of pcieuart8997_combo_v4.bin failed" + rm -f pcieuart8997_combo_v4.bin + exit 1 + } run_host_command_logged mkdir -pv --mode=755 "$destination/lib/firmware/" || exit_with_error "Unable to mkdir firmware" run_host_command_logged mkdir -v --mode=775 "$destination/lib/firmware/mrvl/" || exit_with_error "Unable to mkdir mrvl" run_host_command_logged mv -v "pcieuart8997_combo_v4.bin" "$destination/lib/firmware/mrvl/" || exit_with_error "Unable to copy mrvl firmware" diff --git a/config/boards/mekotronics-r58-4x4.conf b/config/boards/mekotronics-r58-4x4.conf new file mode 100644 index 000000000..17b8fef51 --- /dev/null +++ b/config/boards/mekotronics-r58-4x4.conf @@ -0,0 +1,14 @@ +# Rockchip RK3588 SoC octa core 4-16GB SoC 2x1GBe eMMC USB3 NVMe SATA WiFi/BT HDMI DP HDMI-In RS232 RS485 +declare -g BOARD_NAME="Mekotronics R58-4X4" +declare -g BOARDFAMILY="rockchip-rk3588" +declare -g BOARD_MAINTAINER="150balbes" +declare -g KERNEL_TARGET="vendor" +declare -g BOOTCONFIG="mekotronics_r58x-rk3588_defconfig" # vendor u-boot; with NVMe and a DTS +declare -g BOOT_FDT_FILE="rockchip/rk3588-r58-4x4.dtb" # Specific to this board +declare -g UEFI_EDK2_BOARD_ID="r58-4x4" # This _only_ used for uefi-edk2-rk3588 extension +declare -g DISPLAY_MANAGER="wayland" +declare -g ASOUND_STATE="asound.state.rk3588hd" + +# Source vendor-specific configuration +source "${SRC}/config/sources/vendors/mekotronics/mekotronics-rk3588.conf.sh" + diff --git a/config/boards/mixtile-blade3.csc b/config/boards/mixtile-blade3.csc index fe33502b3..de6493bd5 100644 --- a/config/boards/mixtile-blade3.csc +++ b/config/boards/mixtile-blade3.csc @@ -36,13 +36,13 @@ function post_family_config__blade3_use_mainline_uboot() { declare -g BOOTCONFIG="mixtile-blade3-rk3588_defconfig" # MAINLINE U-BOOT OVERRIDE - declare -g BOOTDELAY=1 # Wait for UART interrupt + declare -g BOOTDELAY=1 BOOTSOURCE="https://github.com/u-boot/u-boot.git" - BOOTBRANCH="tag:v2025.10-rc3" + BOOTBRANCH="tag:v2025.10" BOOTPATCHDIR="v2025.10" # with 000.patching_config.yaml - no patching, straight .dts/defconfigs et al - BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + BOOTDIR="u-boot-${BOARD}" UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" # NOT u-boot-rockchip-spi.bin unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/mixtile-edge2.csc b/config/boards/mixtile-edge2.csc index c984d2975..db310cb06 100644 --- a/config/boards/mixtile-edge2.csc +++ b/config/boards/mixtile-edge2.csc @@ -20,8 +20,8 @@ function post_family_config__h96_max_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTCONFIG="generic-rk3568_defconfig" # Use generic defconfig which should boot all RK3568 boards - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTCONFIG="generic-rk3568_defconfig" + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2024.07" declare -g BOOTPATCHDIR="v2024.07/board_${BOARD}" declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory diff --git a/config/boards/mksklipad50.conf b/config/boards/mksklipad50.conf index 63d43835f..534c3efd1 100644 --- a/config/boards/mksklipad50.conf +++ b/config/boards/mksklipad50.conf @@ -15,5 +15,5 @@ BOOTBRANCH='tag:v2025.01' BOOTPATCHDIR='v2025.01' function post_family_config__uboot_config() { - BOOTDELAY=1 # Wait for UART + BOOTDELAY=1 } diff --git a/config/boards/nanopct6.conf b/config/boards/nanopct6.conf index 2dc95c3cd..5db22920e 100644 --- a/config/boards/nanopct6.conf +++ b/config/boards/nanopct6.conf @@ -40,11 +40,11 @@ function post_family_config__nanopct6_use_mainline_uboot() { prepare_boot_configuration declare -g BOOTCONFIG="nanopc-t6-rk3588_defconfig" - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline - declare -g BOOTBRANCH="tag:v2025.04" - declare -g BOOTPATCHDIR="v2025.04" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2026.01-rc2" + declare -g BOOTPATCHDIR="v2026.01" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -70,16 +70,13 @@ function pre_config_uboot_target__nanoptc6_patch_uboot_dtsi_for_ums() { [[ "${BRANCH}" == "vendor" ]] && return 0 # Not for 'vendor' branch, which uses 2017.09 vendor u-boot from Radxa display_alert "u-boot for ${BOARD}" "u-boot: add to u-boot dtsi for UMS" "info" # avoid a patch, just append to the dtsi file - cat <<- EOD >> arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi # Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode + # Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode + cat <<- EOD >> arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi &u2phy0 { status = "okay"; }; &u2phy0_otg { status = "okay"; }; &usbdp_phy0 { status = "okay"; }; &usb_host0_xhci { dr_mode = "peripheral"; maximum-speed = "high-speed"; status = "okay"; }; EOD - # Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode - # Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode - # Append to the t6 u-boot dtsi file with stuff for enabling gadget/otg/peripheral mode - } # "rockchip-common: boot SD card first, then NVMe, then mmc" @@ -115,6 +112,9 @@ function post_config_uboot_target__extra_configs_for_nanopct6_mainline_environme run_host_command_logged scripts/config --enable CMD_EFIDEBUG run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info" run_host_command_logged scripts/config --enable CONFIG_LZO run_host_command_logged scripts/config --enable CONFIG_BZIP2 diff --git a/config/boards/nanopi-m5.conf b/config/boards/nanopi-m5.conf index f47f35b14..06d4e9d7a 100644 --- a/config/boards/nanopi-m5.conf +++ b/config/boards/nanopi-m5.conf @@ -8,7 +8,6 @@ ASOUND_STATE="asound.state.nanopi-m5" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3576-nanopi-m5.dtb" BOOT_SCENARIO="spl-blobs" -SERIALCON="ttyS0" BOOT_SUPPORT_SPI="yes" BOOT_SPI_RKSPI_LOADER="yes" IMAGE_PARTITION_TABLE="gpt" diff --git a/config/boards/nanopi-m6.conf b/config/boards/nanopi-m6.conf index abf93a6f6..e7e1d906b 100644 --- a/config/boards/nanopi-m6.conf +++ b/config/boards/nanopi-m6.conf @@ -16,11 +16,6 @@ BOOT_SPI_RKSPI_LOADER="yes" DEFAULT_OVERLAYS="nanopi-m6-display-dsi1-yx35" # Enable YX35 LCD -function post_family_config__nanopi_m6_support_spi_boot() { - UBOOT_TARGET_MAP="nanopi-m6-rk3588s_defconfig BL31=$RKBIN_DIR/$BL31_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb -nanopi-m6-spi-rk3588s_defconfig BL31=$RKBIN_DIR/$BL31_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;rkspi_loader.img" -} - function post_family_tweaks__nanopim6_naming_udev_audios() { display_alert "$BOARD" "Renaming NanoPi M6 HDMI audio" "info" @@ -39,3 +34,53 @@ function post_family_tweaks__nanopim6_naming_udev_network_interfaces() { SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNELS=="fe1c0000.ethernet", NAME:="lan" EOF } + +function pre_config_uboot_target__nanopi_m6_patch_uboot_bootconfig_hack_for_spi() { + display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for spi image" "info" + + if [[ $target_make == *"nanopi-m6-spi-rk3588s_defconfig"* ]]; then + BOOTCONFIG="nanopi-m6-spi-rk3588s_defconfig" + target_make=${target_make/nanopi-m6-spi-rk3588s_defconfig/} + else + BOOTCONFIG="nanopi-m6-rk3588s_defconfig" + target_make=${target_make/nanopi-m6-rk3588s_defconfig/} + fi +} + +function post_config_uboot_target__nanopi_m6_keep_spi_bootconfig() { + display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for spi image" "info" + + if [[ $BOOTCONFIG == "nanopi-m6-spi-rk3588s_defconfig" ]]; then + cp .config ${uboottempdir}/.config.spi + fi +} + +function pre_package_uboot_image__nanopi_m6_copy_spiconfig_to_package() { + if [[ -f "${uboottempdir}/.config.spi" ]]; then + run_host_command_logged cp ${uboottempdir}/.config.spi "$uboottempdir/usr/lib/u-boot/nanopi-m6-spi-rk3588s_defconfig" + run_host_command_logged rm ${uboottempdir}/.config.spi + fi +} + + +function post_family_config__nanopi_m6_use_mainline_uboot() { + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" + + declare -g BOOTCONFIG="nanopi-m6-rk3588s_defconfig" + declare -g BOOTCONFIG_SPI="nanopi-m6-spi-rk3588s_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG_SPI;;u-boot-rockchip-spi.bin + BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG;;u-boot-rockchip.bin" + unset uboot_custom_postprocess # disable stuff from rockchip64_common; we're using binman here which does all the work already +} + +function pre_config_uboot_target__nanopi_m6_patch_rockchip_common_boot_order() { + declare -a rockchip_uboot_targets=("mmc0" "nvme" "mmc1" "scsi" "usb" "pxe" "dhcp" "spi") # for future make-this-generic delight + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info" + sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h + regular_git diff -u include/configs/rockchip-common.h || true +} diff --git a/config/boards/nanopi-r3s-lts.conf b/config/boards/nanopi-r3s-lts.conf index e7c637bd3..fef9fdf18 100644 --- a/config/boards/nanopi-r3s-lts.conf +++ b/config/boards/nanopi-r3s-lts.conf @@ -9,16 +9,13 @@ BOOT_FDT_FILE="rockchip/rk3566-nanopi-r3s-lts.dtb" IMAGE_PARTITION_TABLE="gpt" BOOT_SCENARIO="spl-blobs" - function post_family_config__use_mainline_uboot() { - if [[ "$BRANCH" != "current" && "$BRANCH" != "edge" ]]; then - return 0 - fi - unset BOOTFS_TYPE # mainline u-boot can boot ext4 directly + + unset BOOTFS_TYPE BOOTCONFIG="nanopi-r3s-lts-rk3566_defconfig" BOOTSOURCE="https://github.com/u-boot/u-boot" - BOOTBRANCH="tag:v2025.04" - BOOTPATCHDIR="v2025.04" + BOOTBRANCH="tag:v2025.10" + BOOTPATCHDIR="v2025.10" UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" diff --git a/config/boards/nanopi-r3s.csc b/config/boards/nanopi-r3s.csc index dd66cde63..aa7d66c22 100644 --- a/config/boards/nanopi-r3s.csc +++ b/config/boards/nanopi-r3s.csc @@ -12,11 +12,12 @@ BOOT_SCENARIO="spl-blobs" function post_family_config__use_mainline_uboot() { - if [[ "$BRANCH" != "current" && "$BRANCH" != "edge" ]]; then + if [[ "$BRANCH" == "vendor" ]]; then return 0 fi + unset BOOT_FDT_FILE # boot.scr will use whatever u-boot detects and sets 'fdtfile' to - unset BOOTFS_TYPE # mainline u-boot can boot ext4 directly + unset BOOTFS_TYPE BOOTCONFIG="nanopi-r3s-rk3566_defconfig" BOOTSOURCE="https://github.com/u-boot/u-boot" BOOTBRANCH="tag:v2025.04" diff --git a/config/boards/nanopi-r6c.csc b/config/boards/nanopi-r6c.csc index 5ca64499c..876136ac4 100644 --- a/config/boards/nanopi-r6c.csc +++ b/config/boards/nanopi-r6c.csc @@ -37,8 +37,8 @@ function post_family_config__nanopi_r6c_use_mainline_uboot() { declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot - declare -g BOOTBRANCH="tag:v2025.01" - declare -g BOOTPATCHDIR="v2025.01" + declare -g BOOTBRANCH="tag:v2026.01-rc2" + declare -g BOOTPATCHDIR="v2026.01" declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -89,6 +89,9 @@ function post_config_uboot_target__extra_configs_for_r6c_mainline() { run_host_command_logged scripts/config --enable CMD_EFIDEBUG run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more compression support" "info" run_host_command_logged scripts/config --enable CONFIG_LZO run_host_command_logged scripts/config --enable CONFIG_BZIP2 diff --git a/config/boards/nanopi-r6s.conf b/config/boards/nanopi-r6s.conf index 7c636404b..499519e13 100644 --- a/config/boards/nanopi-r6s.conf +++ b/config/boards/nanopi-r6s.conf @@ -38,11 +38,11 @@ function post_family_tweaks__nanopir6s_naming_udev_network_interfaces() { function post_family_config__nanopi_r6s_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot - declare -g BOOTBRANCH="tag:v2025.01" - declare -g BOOTPATCHDIR="v2025.01" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/nanopi-r76s.conf b/config/boards/nanopi-r76s.conf index 471c5c63c..ce1974ff3 100644 --- a/config/boards/nanopi-r76s.conf +++ b/config/boards/nanopi-r76s.conf @@ -7,7 +7,6 @@ FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3576-nanopi-r76s.dtb" BOOT_SCENARIO="spl-blobs" -SERIALCON="ttyS0" IMAGE_PARTITION_TABLE="gpt" BOARD_MAINTAINER="SuperKali" diff --git a/config/boards/nanopim4v2.conf b/config/boards/nanopim4v2.conf index 949288283..8de245d16 100644 --- a/config/boards/nanopim4v2.conf +++ b/config/boards/nanopim4v2.conf @@ -1,6 +1,6 @@ # Rockchip RK3399 hexa core 4GB RAM SoC GBE eMMC USB3 USB-C WiFi/BT BOARD_NAME="NanoPi M4V2" -BOARDFAMILY="rockchip64" # Used to be rk3399 +BOARDFAMILY="rockchip64" BOARD_MAINTAINER="igorpecovnik" BOOTCONFIG="nanopi-m4v2-rk3399_defconfig" KERNEL_TARGET="current,edge" diff --git a/config/boards/odroidhc4.conf b/config/boards/odroidhc4.conf index 3fe378c70..f0c03aa82 100644 --- a/config/boards/odroidhc4.conf +++ b/config/boards/odroidhc4.conf @@ -12,8 +12,8 @@ BOOT_FDT_FILE="amlogic/meson-sm1-odroid-hc4.dtb" PACKAGE_LIST_BOARD="lm-sensors fancontrol" # SPI, sensors, manual fan control via 'pwmconfig' # Newer u-boot for the HC4. There's patches in `board_odroidhc4` for the defconfigs used in the UBOOT_TARGET_MAP below. -BOOTBRANCH_BOARD="tag:v2025.04" -BOOTPATCHDIR="v2025.04" +BOOTBRANCH_BOARD="tag:v2026.01-rc2" +BOOTPATCHDIR="v2026.01" # We build u-boot twice: C4 config for SD cards, and HC4 (with SATA/PCI/SPI) config for SPI. UBOOT_TARGET_MAP=" @@ -59,6 +59,9 @@ function post_config_uboot_target__extra_configs_for_odroid_hc4() { run_host_command_logged scripts/config --enable CONFIG_SYS_I2C_MESON run_host_command_logged scripts/config --enable CONFIG_CMD_I2C + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info" run_host_command_logged scripts/config --enable CONFIG_LZO run_host_command_logged scripts/config --enable CONFIG_BZIP2 diff --git a/config/boards/odroidm1.conf b/config/boards/odroidm1.conf index 08a9e2cea..5d5abd7af 100644 --- a/config/boards/odroidm1.conf +++ b/config/boards/odroidm1.conf @@ -12,18 +12,18 @@ IMAGE_PARTITION_TABLE="gpt" FULL_DESKTOP="yes" BOOT_LOGO="desktop" -BOOTBRANCH_BOARD="tag:v2025.01" -BOOTPATCHDIR="v2025.01" # but all changes are done in this board file, not patches +BOOTBRANCH_BOARD="tag:v2025.10" +BOOTPATCHDIR="v2025.10" # but all changes are done in this board file, not patches BOOTCONFIG="odroid-m1-rk3568_defconfig" -BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory +BOOTDIR="u-boot-${BOARD}" # The overlays for this board are prefixed by 'rockchip-rk3568-hk' (see for example patch/kernel/archive/rockchip64-6.6/overlay/rockchip-rk3568-hk-i2c0.dts) OVERLAY_PREFIX="rockchip-rk3568-hk" function post_family_config__uboot_config() { display_alert "$BOARD" "u-boot ${BOOTBRANCH_BOARD} overrides" "info" - BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc + BOOTDELAY=1 UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/$BL31_BLOB ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin u-boot.itb idbloader.img idbloader-spi.img" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -126,6 +126,9 @@ function post_config_uboot_target__extra_configs_for_odroid-m1() { run_host_command_logged scripts/config --enable CONFIG_BZIP2 run_host_command_logged scripts/config --enable CONFIG_ZSTD + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info" run_host_command_logged scripts/config --enable CONFIG_LED run_host_command_logged scripts/config --enable CONFIG_LED_GPIO diff --git a/config/boards/odroidm1s.csc b/config/boards/odroidm1s.csc new file mode 100644 index 000000000..39de27c58 --- /dev/null +++ b/config/boards/odroidm1s.csc @@ -0,0 +1,102 @@ +# Rockchip RK3566 quad core 4GB-8GB GBE USB3 NVMe eMMC +BOARD_NAME="ODROID M1S" +BOARDFAMILY="rk35xx" +BOARD_MAINTAINER="" +BOOT_SOC="rk3566" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +BOOT_FDT_FILE="rockchip/rk3566-odroid-m1s.dtb" +SRC_EXTLINUX="no" +ASOUND_STATE="asound.state.station-m2" +IMAGE_PARTITION_TABLE="gpt" +FULL_DESKTOP="yes" +BOOT_LOGO="desktop" + +# Mainline U-Boot +function post_family_config__odroid_m1s_use_mainline_uboot() { + display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" + + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTCONFIG="odroid-m1s-rk3566_defconfig" + declare -g BOOTDIR="u-boot-${BOARD}" + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" + unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already + + # Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go + function write_uboot_platform() { + dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none + } +} + +# add a network rule to rename default name +function post_family_tweaks__odroidm1s_rename_gmac_eth0() { + display_alert "Creating network rename rule for Odroid M1S" + mkdir -p "${SDCARD}"/etc/udev/rules.d/ + cat <<- EOF > "${SDCARD}"/etc/udev/rules.d/70-rename-lan.rules + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="end*", NAME="eth0" + EOF + +} + +function pre_config_uboot_target__odroidm1s_patch_uboot_dtsi_for_ums() { + display_alert "u-boot for ${BOARD}" "u-boot: add to u-boot dtsi for UMS" "info" # avoid a patch, just append to the dtsi file + cat <<- UBOOT_BOARD_DTSI_OTG >> arch/arm/dts/rk3566-odroid-m1s-u-boot.dtsi + &usb_host0_xhci { dr_mode = "otg"; }; + UBOOT_BOARD_DTSI_OTG +} + +# "rockchip-common: boot SD card first, then NVMe, then SATA, then USB, then mmc" +# On odroidm1, mmc0 is the eMMC, mmc1 is the SD card slot +function pre_config_uboot_target__odroidm1s_patch_rockchip_common_boot_order() { + declare -a rockchip_uboot_targets=("mmc1" "nvme" "scsi" "usb" "mmc0" "pxe" "dhcp") # for future make-this-generic delight + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info" + sed -i -e "s/#define BOOT_TARGETS.*/#define BOOT_TARGETS \"${rockchip_uboot_targets[*]}\"/" include/configs/rockchip-common.h + regular_git diff -u include/configs/rockchip-common.h || true +} + +# A better equivalent to patching a defconfig, do changes to .config via code. +# For UMS/RockUSB to work in u-boot, &usb_host0_xhci { dr_mode = "otg" } is required. See 0002-board-rockchip-ODROID-M1S-override-kernel-DT-for-xhci-otg-dr_mode.patch +function post_config_uboot_target__extra_configs_for_odroidm1s() { + [[ "${BRANCH}" == "edge" || "${BRANCH}" == "current" ]] || return 0 + + display_alert "u-boot for ${BOARD}" "u-boot: enable EFI debugging command" "info" + run_host_command_logged scripts/config --enable CMD_EFIDEBUG + run_host_command_logged scripts/config --enable CMD_NVEDIT_EFI + + display_alert "u-boot for ${BOARD}" "u-boot: enable more compression support" "info" + run_host_command_logged scripts/config --enable CONFIG_LZO + run_host_command_logged scripts/config --enable CONFIG_BZIP2 + run_host_command_logged scripts/config --enable CONFIG_ZSTD + + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enable more filesystems support" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_BTRFS + + display_alert "u-boot for ${BOARD}" "u-boot: enable gpio LED support" "info" + run_host_command_logged scripts/config --enable CONFIG_LED + run_host_command_logged scripts/config --enable CONFIG_LED_GPIO + + display_alert "u-boot for ${BOARD}" "u-boot: enable networking cmds" "info" + run_host_command_logged scripts/config --enable CONFIG_CMD_NFS + run_host_command_logged scripts/config --enable CONFIG_CMD_WGET + run_host_command_logged scripts/config --enable CONFIG_CMD_DNS + run_host_command_logged scripts/config --enable CONFIG_PROT_TCP + run_host_command_logged scripts/config --enable CONFIG_PROT_TCP_SACK + + display_alert "u-boot for ${BOARD}" "u-boot: enable more cmdline commands" "info" # for extra compat with eg HAOS + run_host_command_logged scripts/config --enable CONFIG_CMD_SQUASHFS + run_host_command_logged scripts/config --enable CONFIG_CMD_SETEXPR + run_host_command_logged scripts/config --enable CONFIG_CMD_FILEENV # added via cmd-fileenv-read-string-from-file-into-env.patch + run_host_command_logged scripts/config --enable CONFIG_CMD_CAT + run_host_command_logged scripts/config --enable CONFIG_CMD_XXD + + display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: enabling UMS/RockUSB Gadget functionality" "info" + declare -a enable_configs=("CONFIG_CMD_USB_MASS_STORAGE" "CONFIG_USB_GADGET" "USB_GADGET_DOWNLOAD" "CONFIG_USB_FUNCTION_ROCKUSB" "CONFIG_USB_FUNCTION_ACM" "CONFIG_CMD_ROCKUSB" "CONFIG_CMD_USB_MASS_STORAGE") + for config in "${enable_configs[@]}"; do + run_host_command_logged scripts/config --enable "${config}" + done + # Auto-enabled by the above, force off... + run_host_command_logged scripts/config --disable USB_FUNCTION_FASTBOOT +} diff --git a/config/boards/odroidn2.conf b/config/boards/odroidn2.conf index 19f52bd10..0be455bfb 100644 --- a/config/boards/odroidn2.conf +++ b/config/boards/odroidn2.conf @@ -8,6 +8,7 @@ MODULES_BLACKLIST="simpledrm" # SimpleDRM conflicts with Panfrost FULL_DESKTOP="yes" FORCE_BOOTSCRIPT_UPDATE="yes" BOOT_LOGO="desktop" +BOOTFS_TYPE="ext4" BOOTCONFIG="odroid-n2_defconfig" # For mainline uboot # Newer u-boot for the N2/N2+, less patches: a single boot order patch diff --git a/config/boards/orangepi3b.csc b/config/boards/orangepi3b.csc index cea568fb6..33c2e9b74 100644 --- a/config/boards/orangepi3b.csc +++ b/config/boards/orangepi3b.csc @@ -16,12 +16,10 @@ BOOT_SPI_RKSPI_LOADER="yes" function post_family_config__orangepi3b_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2024.10" declare -g BOOTPATCHDIR="v2024.10" - # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency - - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc + declare -g BOOTDELAY=1 declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin u-boot.itb idbloader.img idbloader-spi.img" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/orangepi5-max.csc b/config/boards/orangepi5-max.csc index 714d43b57..01335d57a 100644 --- a/config/boards/orangepi5-max.csc +++ b/config/boards/orangepi5-max.csc @@ -19,13 +19,13 @@ BCMDHD_TYPE="sdio" # Mainline U-Boot for edge kernel function post_family_config_branch_edge__orangepi5max_use_mainline_uboot() { display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - unset BOOT_FDT_FILE # boot.scr will use whatever u-boot detects and sets 'fdtfile' to - declare -g BOOTCONFIG="orangepi-5-max-rk3588_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ mainline U-Boot + unset BOOT_FDT_FILE + declare -g BOOTCONFIG="orangepi-5-max-rk3588_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2025.04" declare -g BOOTPATCHDIR="v2025.04" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/orangepi5-plus.conf b/config/boards/orangepi5-plus.conf index f2aa79cb1..5ba914e7f 100644 --- a/config/boards/orangepi5-plus.conf +++ b/config/boards/orangepi5-plus.conf @@ -13,7 +13,6 @@ BOOT_SCENARIO="spl-blobs" BOOT_SUPPORT_SPI="yes" BOOT_SPI_RKSPI_LOADER="yes" IMAGE_PARTITION_TABLE="gpt" -KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1" declare -g UEFI_EDK2_BOARD_ID="orangepi-5plus" # This _only_ used for uefi-edk2-rk3588 extension function post_family_tweaks__orangepi5plus_naming_audios() { @@ -28,39 +27,18 @@ function post_family_tweaks__orangepi5plus_naming_audios() { return 0 } -# Mainline U-Boot for edge kernel -function post_family_config_branch_edge__orangepi5plus_use_mainline_uboot() { + +function post_family_config__orangepi5plus_use_mainline_uboot() { + [[ "${BRANCH}" == "vendor" ]] && return 0 # skip for vendor branch + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - declare -g BOOTCONFIG="orangepi-5-plus-rk3588_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ mainline U-Boot - declare -g BOOTBRANCH="tag:v2024.10-rc3" - declare -g BOOTPATCHDIR="v2024.10" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory - declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" - unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already - - # Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go - function write_uboot_platform() { - dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none - } - - function write_uboot_platform_mtd() { - flashcp -v -p "$1/u-boot-rockchip-spi.bin" /dev/mtd0 - } -} - -# Mainline U-Boot for current kernel -function post_family_config_branch_current__orangepi5plus_use_mainline_uboot() { - display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - - declare -g BOOTCONFIG="orangepi-5-plus-rk3588_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ mainline U-Boot - declare -g BOOTBRANCH="tag:v2024.10-rc3" - declare -g BOOTPATCHDIR="v2024.10" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTCONFIG="orangepi-5-plus-rk3588_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -75,11 +53,11 @@ function post_family_config_branch_current__orangepi5plus_use_mainline_uboot() { } function post_config_uboot_target__extra_configs_for_rock5b_mainline_environment_in_spi() { - [[ "${BRANCH}" != "edge" && "${BRANCH}" != "current" ]] && return 0 + [[ "${BRANCH}" == "vendor" ]] && return 0 display_alert "$BOARD" "u-boot configs for ${BOOTBRANCH} u-boot config BRANCH=${BRANCH}" "info" run_host_command_logged scripts/config --set-val CONFIG_BOARD_RNG_SEED "y" - run_host_command_logged scripts/config --set-val ARMV8_CRYPTO "n" #broken as per 2024.10-rc3 - run_host_command_logged scripts/config --set-val ARMV8_CE_SHA1 "n" #broken as per 2024.10-rc3 - run_host_command_logged scripts/config --set-val ARMV8_CE_SHA256 "n" #broken as per 2024.10-rc3 + run_host_command_logged scripts/config --set-val ARMV8_CRYPTO "y" + run_host_command_logged scripts/config --set-val ARMV8_CE_SHA1 "y" + run_host_command_logged scripts/config --set-val ARMV8_CE_SHA256 "y" } diff --git a/config/boards/orangepi5.conf b/config/boards/orangepi5.conf index 5bf5bf6b1..9775772db 100644 --- a/config/boards/orangepi5.conf +++ b/config/boards/orangepi5.conf @@ -19,30 +19,21 @@ declare -g UEFI_EDK2_BOARD_ID="orangepi-5" # This _only_ used for uefi-edk2-rk35 declare -g BLUETOOTH_HCIATTACH_PARAMS="-s 115200 /dev/ttyS9 bcm43xx 1500000" # For the bluetooth-hciattach extension enable_extension "bluetooth-hciattach" # Enable the bluetooth-hciattach extension -# Mainline U-Boot for current kernel function post_family_config__orangepi5_use_mainline_uboot() { - if [[ $BRANCH == "vendor" ]]; then - return - fi - display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - declare -g BOOTCONFIG="orangepi-5-rk3588s_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ mainline U-Boot - declare -g BOOTBRANCH="tag:v2025.07" - declare -g BOOTPATCHDIR="v2025.07" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTCONFIG="orangepi-5-rk3588s_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG_SATA;;u-boot-rockchip-spi-sata.bin BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB} $BOOTCONFIG;;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess # disable stuff from rockchip64_common; we're using binman here which does all the work already } function pre_config_uboot_target__orangepi5_patch_uboot_bootconfig_hack_for_sata() { - if [[ $BRANCH == "vendor" ]]; then - return - fi - display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for sata spi image" "info" if [[ $target_make == *"orangepi-5-sata-rk3588s_defconfig"* ]]; then @@ -54,12 +45,7 @@ function pre_config_uboot_target__orangepi5_patch_uboot_bootconfig_hack_for_sata fi } - function post_config_uboot_target__orangepi5_keep_sata_bootconfig() { - if [[ $BRANCH == "vendor" ]]; then - return - fi - display_alert "u-boot for ${BOARD}" "u-boot: hack bootconfig for sata spi image" "info" if [[ $BOOTCONFIG == "orangepi-5-sata-rk3588s_defconfig" ]]; then @@ -68,10 +54,6 @@ function post_config_uboot_target__orangepi5_keep_sata_bootconfig() { } function pre_package_uboot_image__orangepi5_copy_sataconfig_to_package() { - if [[ $BRANCH == "vendor" ]]; then - return - fi - if [[ -f "${uboottempdir}/.config.sata" ]]; then run_host_command_logged cp ${uboottempdir}/.config.sata "$uboottempdir/usr/lib/u-boot/orangepi-5-sata-rk3588s_defconfig" run_host_command_logged rm ${uboottempdir}/.config.sata @@ -118,34 +100,3 @@ function post_family_tweaks__orangepi5_naming_audios() { return 0 } - -function post_family_config__orangepi5_uboot_add_sata_target() { - if [[ $BRANCH == "edge" || $BRANCH == "current" ]]; then - return - fi - - display_alert "$BOARD" "Configuring ($BOARD) standard and sata uboot target map" "info" - # Note: whitespace/newlines are significant; BOOT_SUPPORT_SPI & BOOT_SPI_RKSPI_LOADER influence the postprocess step that runs for _every_ target and produces rkspi_loader.img - UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB $BOOTCONFIG spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb rkspi_loader.img - BL31=$RKBIN_DIR/$BL31_BLOB $BOOTCONFIG_SATA spl/u-boot-spl.bin u-boot.dtb u-boot.itb;; rkspi_loader_sata.img" -} - -function post_uboot_custom_postprocess__create_sata_spi_image() { - if [[ $BRANCH == "edge" || $BRANCH == "current" ]]; then - return - fi - - display_alert "$BOARD" "Create rkspi_loader_sata.img" "info" - - dd if=/dev/zero of=rkspi_loader_sata.img bs=1M count=0 seek=16 - /sbin/parted -s rkspi_loader_sata.img mklabel gpt - /sbin/parted -s rkspi_loader_sata.img unit s mkpart idbloader 64 7167 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart vnvm 7168 7679 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart reserved_space 7680 8063 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart reserved1 8064 8127 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart uboot_env 8128 8191 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart reserved2 8192 16383 - /sbin/parted -s rkspi_loader_sata.img unit s mkpart uboot 16384 32734 - dd if=idbloader.img of=rkspi_loader_sata.img seek=64 conv=notrunc - dd if=u-boot.itb of=rkspi_loader_sata.img seek=16384 conv=notrunc -} diff --git a/config/boards/orangepi5pro.csc b/config/boards/orangepi5pro.csc index 34bdb62e1..719eec30d 100644 --- a/config/boards/orangepi5pro.csc +++ b/config/boards/orangepi5pro.csc @@ -83,7 +83,7 @@ function pre_customize_image__orangepi5pro_add_phy_driver() { # Create directory and download .deb (Not installing due to chroot issue with dkms and kernel headers) chroot_sdcard mkdir -p /usr/local/share/eth-driver - chroot_sdcard wget "https://github.com/dante1613/Motorcomm-YT6801/raw/main/tuxedo-yt6801/${deb_file}" -O "/usr/local/share/eth-driver/${deb_file}" + chroot_sdcard curl -fL "https://github.com/dante1613/Motorcomm-YT6801/raw/main/tuxedo-yt6801/${deb_file}" -o "/usr/local/share/eth-driver/${deb_file}" # Make script to Auto-Install Ethernet Driver Only on first boot cat << 'EOF' > "${SDCARD}/usr/local/bin/install-eth-driver.sh" @@ -196,4 +196,4 @@ function post_family_config__orangepi5pro_use_vendor_uboot() { BOOTSOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git' BOOTBRANCH='branch:v2017.09-rk3588' BOOTPATCHDIR="legacy" -} \ No newline at end of file +} diff --git a/config/boards/pinebook-pro.csc b/config/boards/pinebook-pro.csc index 3a251f2bb..49037e8ca 100644 --- a/config/boards/pinebook-pro.csc +++ b/config/boards/pinebook-pro.csc @@ -1,7 +1,7 @@ # Rockchip RK3399 hexa core 2G/4GB SoC Laptop eMMC USB3 WiFi BOARD_NAME="Pinebook Pro" BOARDFAMILY="rockchip64" -BOARD_MAINTAINER="TRSx80 ahoneybun" +BOARD_MAINTAINER="ahoneybun" BOOTCONFIG="pinebook-pro-rk3399_defconfig" BOOT_FDT_FILE="rockchip/rk3399-pinebook-pro.dtb" KERNEL_TARGET="current,edge" diff --git a/config/boards/pocketbeagle2.conf b/config/boards/pocketbeagle2.conf index 7428abeb5..7bf3a0ab1 100644 --- a/config/boards/pocketbeagle2.conf +++ b/config/boards/pocketbeagle2.conf @@ -1,52 +1,19 @@ -#Texas Instruments AM62 dual core 1GB USB2 DDR4 +# PocketBeagle 2 Texas Instruments AM62 dual core 512MB USB2 DDR4 BOARD_NAME="PocketBeagle 2" -BOARDFAMILY="k3" +BOARDFAMILY="k3-beagle" BOARD_MAINTAINER="Grippy98" +BOOT_SOC="am62" BOOTCONFIG="am6232_pocketbeagle2_a53_defconfig" BOOTFS_TYPE="fat" TIBOOT3_BOOTCONFIG="am6232_pocketbeagle2_r5_defconfig" TIBOOT3_FILE="tiboot3-am62x-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="edge" -KERNEL_TEST_TARGET="edge" +KERNEL_TARGET="vendor,vendor-rt" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2,ttyGS0" ATF_BOARD="lite" SRC_EXTLINUX="yes" SRC_CMDLINE="root=/dev/mmcblk1p2 rootwait console=ttyS2,115200n8 console=ttyGS0,115200n8 modules-load=dwc2,g_cdc" -BOOT_FDT_FILE="ti/k3-am6232-pocketbeagle2.dtb" +BOOT_FDT_FILE="ti/k3-am6232-pocketbeagle2.dts" #Name changed in upstream OPTEE_PLATFORM="k3-am62x" - -function current_beagle_kernel_uboot() { - declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel - declare -g KERNEL_MAJOR_MINOR="6.12" - declare -g KERNELBRANCH="branch:v6.12.24-ti-arm64-r43" - declare -g LINUXFAMILY="k3-beagle" # Separate kernel package from the regular `k3` family - - declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot - declare -g BOOTBRANCH="branch:v2025.07-am6232-pocketbeagle2" -} - -#Until PB2 goes upstream, use this branch -function post_family_config_branch_current__pocketbeagle2_use_beagle_kernel_uboot() { - display_alert "$BOARD" " beagleboard (current branch) u-boot and kernel overrides for $BOARD / $BRANCH" "info" - current_beagle_kernel_uboot -} - -function post_family_config_branch_current-rt__pocketbeagle2_use_beagle_kernel_uboot() { - display_alert "$BOARD" " beagleboard (current-rt branch) u-boot and kernel overrides for $BOARD / $BRANCH" "info" - current_beagle_kernel_uboot -} - -#Until PB2 goes upstream, use this branch -function post_family_config_branch_edge__pocketbeagle2_use_beagle_kernel_uboot() { - display_alert "$BOARD" " beagleboard (next branch) u-boot and kernel overrides for $BOARD / $BRANCH" "info" - - declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel - declare -g KERNEL_MAJOR_MINOR="6.12" - declare -g KERNELBRANCH="branch:v6.12.24-ti-arm64-r43" - declare -g LINUXFAMILY="k3-beagle" # Separate kernel package from the regular `k3` family - - declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot - declare -g BOOTBRANCH="branch:v2025.07-am6232-pocketbeagle2" -} diff --git a/config/boards/qemu-uefi-x86.conf b/config/boards/qemu-uefi-x86.csc similarity index 94% rename from config/boards/qemu-uefi-x86.conf rename to config/boards/qemu-uefi-x86.csc index 1f13b7728..26247ec8d 100644 --- a/config/boards/qemu-uefi-x86.conf +++ b/config/boards/qemu-uefi-x86.csc @@ -13,7 +13,7 @@ # declare -g BOARD_NAME="UEFI x86 (QEMU)" declare -g BOARDFAMILY="uefi-x86" -declare -g BOARD_MAINTAINER="davidandreoletti" +declare -g BOARD_MAINTAINER="" declare -g KERNEL_TARGET="current,edge,legacy" declare -g SERIALCON="tty1,ttyS0" diff --git a/config/boards/quartz64a.csc b/config/boards/quartz64a.csc index b4a5b265d..0ebfff089 100644 --- a/config/boards/quartz64a.csc +++ b/config/boards/quartz64a.csc @@ -15,10 +15,10 @@ IMAGE_PARTITION_TABLE="gpt" function post_family_config__quartz64_a_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2025.04" declare -g BOOTPATCHDIR="v2025.04" - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc + declare -g BOOTDELAY=1 declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" diff --git a/config/boards/quartz64b.csc b/config/boards/quartz64b.csc index 91c5c4759..84fd47d73 100644 --- a/config/boards/quartz64b.csc +++ b/config/boards/quartz64b.csc @@ -15,11 +15,9 @@ IMAGE_PARTITION_TABLE="gpt" function post_family_config__quartz64_b_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2024.07" declare -g BOOTPATCHDIR="v2024.07/board_${BOARD}" - # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency - declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" # Disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/radxa-e54c.csc b/config/boards/radxa-e54c.csc new file mode 100644 index 000000000..8dfb86a2f --- /dev/null +++ b/config/boards/radxa-e54c.csc @@ -0,0 +1,61 @@ +# Rockchip RK3582 SoC +BOARD_NAME="Radxa E54C" +BOARDFAMILY="rockchip-rk3588" +BOARD_MAINTAINER="kamilsaigol" +BOOTCONFIG="radxa-e54c-rk3588s_defconfig" +KERNEL_TARGET="vendor" +BOOT_FDT_FILE="rockchip/rk3588s-radxa-e54c.dtb" +BOOT_SCENARIO="spl-blobs" +BOOT_SOC="rk3588" +IMAGE_PARTITION_TABLE="gpt" + +# Enable system and network LEDs +function post_family_tweaks_bsp__radxa_e54c_enable_leds() { + display_alert "$BOARD" "Creating Board Support LED Config" "info" + cat <<- EOF > "${destination}"/etc/armbian-leds.conf + [/sys/class/leds/lan1-led] + trigger=netdev + interval=52 + brightness=1 + link=1 + tx=0 + rx=1 + device_name=lan1@end1 + + [/sys/class/leds/lan2-led] + trigger=netdev + interval=52 + brightness=1 + link=1 + tx=0 + rx=1 + device_name=lan2@end1 + + [/sys/class/leds/lan3-led] + trigger=netdev + interval=52 + brightness=1 + link=1 + tx=0 + rx=1 + device_name=lan3@end1 + + [/sys/class/leds/wan-led] + trigger=netdev + interval=52 + brightness=1 + link=1 + tx=0 + rx=1 + device_name=wan@end1 + + [/sys/class/leds/mmc0::] + trigger=mmc0 + brightness=0 + + [/sys/class/leds/sys-led] + trigger=heartbeat + brightness=0 + invert=0 + EOF +} diff --git a/config/boards/radxa-zero.conf b/config/boards/radxa-zero.conf index c2a1e61eb..681a36119 100644 --- a/config/boards/radxa-zero.conf +++ b/config/boards/radxa-zero.conf @@ -1,7 +1,7 @@ # Amlogic S905Y2 512MB/1GB/2GB/4GB RAM eMMC USB3 WiFi BT BOARD_NAME="Radxa Zero" BOARDFAMILY="meson-g12a" -BOARD_MAINTAINER="clee engineer-80" +BOARD_MAINTAINER="engineer-80" BOOTCONFIG="radxa-zero_config" CPUMIN=6660000 CPUMAX=1800000 @@ -15,6 +15,5 @@ ASOUND_STATE="asound.state.radxa-zero" BOOT_FDT_FILE="amlogic/meson-g12a-radxa-zero.dtb" OVERLAY_PREFIX="meson-g12a" -# Newer u-boot for the Zero BOOTBRANCH_BOARD="tag:v2023.07.02" BOOTPATCHDIR="v2023.07.02" diff --git a/config/boards/radxa-zero2.csc b/config/boards/radxa-zero2.csc index bc81349cd..098878ae6 100644 --- a/config/boards/radxa-zero2.csc +++ b/config/boards/radxa-zero2.csc @@ -11,8 +11,5 @@ BOOT_LOGO="desktop" ASOUND_STATE="asound.state.radxa-zero2" BOOT_FDT_FILE="amlogic/meson-g12b-radxa-zero2.dtb" -# Newer u-boot for the Zero2 -# 2022.10: Radxa's patches with new DT, Makefile and defconfig in v2022.10/board_radxa-zero2 dir; common to 22.10's meson64 boot-usb-first -# v2023.10: board-specific boot-usb-first patch; zero2 landed in upstream u-boot v2023.07-rc1 BOOTBRANCH_BOARD="tag:v2024.07" BOOTPATCHDIR="v2024.07" diff --git a/config/boards/radxa-zero3.csc b/config/boards/radxa-zero3.csc index ec08dbc6f..1c4665282 100644 --- a/config/boards/radxa-zero3.csc +++ b/config/boards/radxa-zero3.csc @@ -1,17 +1,15 @@ -# Rockchip RK3566 quad core +# Rockchip RK3566 quad core 1/2/4/8GB RAM WiFi/BT or GBE HDMI USB-C BOARD_NAME="Radxa ZERO 3" BOARDFAMILY="rk35xx" BOARD_MAINTAINER="" BOOTCONFIG="radxa-zero3-rk3566_defconfig" KERNEL_TARGET="vendor,current,edge" -KERNEL_TEST_TARGET="vendor" +KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3566-radxa-zero3.dtb" IMAGE_PARTITION_TABLE="gpt" BOOT_SCENARIO="spl-blobs" -BOOTFS_TYPE="fat" # Only for vendor/legacy - PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools" # add for OBEX file transfer: @@ -19,6 +17,34 @@ PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools" AIC8800_TYPE="sdio" enable_extension "radxa-aic8800" +function post_family_config__use_mainline_uboot() { + + # boot.scr will use whatever u-boot detects and sets 'fdtfile' to. + # This however this doesn't work with Rockchip bsp based kernels since naming differs. + # So leave decision to u-boot ONLY when mainline kernel is used. + if [[ "${BRANCH}" != "vendor" ]]; then + unset BOOT_FDT_FILE + fi + + BOOTCONFIG="radxa-zero-3-rk3566_defconfig" + BOOTSOURCE="https://github.com/u-boot/u-boot" + BOOTBRANCH="tag:v2025.10" + BOOTPATCHDIR="v2025.10" + + UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" + ## For binman-atf-mainline: setting BOOT_SCENARIO at the top would break branch=vendor, so we don't enable it globally. + # We cannot set BOOT_SOC=rk3566 due to side effects in Armbian scripts; ATF_TARGET_MAP is the safer override. + # ATF does not currently separate rk3566 from rk3568. + #ATF_TARGET_MAP="M0_CROSS_COMPILE=arm-linux-gnueabi- PLAT=rk3568 bl31;;build/rk3568/release/bl31/bl31.elf:bl31.elf" + #UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" + + unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd + + function write_uboot_platform() { + dd if=$1/u-boot-rockchip.bin of=$2 seek=64 conv=notrunc status=none + } +} + function post_family_tweaks_bsp__aic8800_wireless() { display_alert "$BOARD" "Installing AIC8800 Tweaks" "info" mkdir -p "${destination}"/etc/modprobe.d @@ -54,45 +80,4 @@ function post_family_tweaks__enable_aic8800_bluetooth_service() { else display_alert "$BOARD" "aic-bluetooth.service not found in image; skipping enable" "warn" fi -} - -function post_family_config__use_mainline_uboot_except_vendor() { - # use mainline u-boot for _current_ and _edge_ - if [[ "$BRANCH" != "current" && "$BRANCH" != "edge" ]]; then - return 0 - fi - unset BOOT_FDT_FILE # boot.scr will use whatever u-boot detects and sets 'fdtfile' to - unset BOOTFS_TYPE # mainline u-boot can boot ext4 directly - BOOTCONFIG="radxa-zero-3-rk3566_defconfig" - BOOTSOURCE="https://github.com/u-boot/u-boot" - BOOTBRANCH="tag:v2025.10-rc2" - BOOTPATCHDIR="v2025.10" - - UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" - ## For binman-atf-mainline: setting BOOT_SCENARIO at the top would break branch=vendor, so we don't enable it globally. - # We cannot set BOOT_SOC=rk3566 due to side effects in Armbian scripts; ATF_TARGET_MAP is the safer override. - # ATF does not currently separate rk3566 from rk3568. - #ATF_TARGET_MAP="M0_CROSS_COMPILE=arm-linux-gnueabi- PLAT=rk3568 bl31;;build/rk3568/release/bl31/bl31.elf:bl31.elf" - #UBOOT_TARGET_MAP="BL31=bl31.elf ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" - - unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd - - function write_uboot_platform() { - dd if=$1/u-boot-rockchip.bin of=$2 seek=64 conv=notrunc status=none - } -} - -# Override family config for this board; let's avoid conditionals in family config. -function post_family_config_branch_vendor__radxa-zero3_use_vendor_uboot() { - BOOTSOURCE='https://github.com/radxa/u-boot.git' - BOOTBRANCH='branch:rk35xx-2024.01' - BOOTPATCHDIR="u-boot-radxa-latest" - - UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB ROCKCHIP_TPL=$RKBIN_DIR/$DDR_BLOB;;u-boot-rockchip.bin" - - unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd - - function write_uboot_platform() { - dd if=$1/u-boot-rockchip.bin of=$2 seek=64 conv=notrunc status=none - } -} +} \ No newline at end of file diff --git a/config/boards/rock-3a.conf b/config/boards/rock-3a.conf index 9eba21ef9..401894fa5 100644 --- a/config/boards/rock-3a.conf +++ b/config/boards/rock-3a.conf @@ -22,18 +22,15 @@ function post_family_config__rock-3a_use_mainline_uboot_except_vendor_and_add_sa BL31=$RKBIN_DIR/$BL31_BLOB $BOOTCONFIG_SATA spl/u-boot-spl.bin u-boot.dtb u-boot.itb;; rkspi_loader_sata.img" # use mainline uboot for _current_ and _edge_ - if [[ "$BRANCH" != "current" && "$BRANCH" != "edge" ]]; then - return 0 - fi + [[ "${BRANCH}" == "vendor" ]] && return 0 display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - unset BOOTFS_TYPE # fixes armbian-install and unneeded for modern uboot anyway declare -g BOOTCONFIG="rock-3a-rk3568_defconfig" declare -g BOOTDELAY=1 declare -g BOOTSOURCE="https://github.com/u-boot/u-boot" - declare -g BOOTBRANCH="tag:v2025.04" - declare -g BOOTPATCHDIR="v2025.04" - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/rock-5b-plus.conf b/config/boards/rock-5b-plus.conf index b07401a5b..653d89c7a 100644 --- a/config/boards/rock-5b-plus.conf +++ b/config/boards/rock-5b-plus.conf @@ -27,20 +27,17 @@ function post_family_tweaks__rock5b_naming_audios() { return 0 } -# Mainline u-boot tree -# see rock-5b.conf and https://github.com/armbian/build/pull/7135 -function post_family_config_branch_edge__rock-5b_use_mainline_uboot() { - display_alert "$BOARD" "mainline (next branch) u-boot overrides for $BOARD / $BRANCH" "info" +# Mainline u-boot tree - use post_family_config hook to override family config +function post_family_config__rock5b_plus_use_mainline_uboot() { + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" - # temporary override until DT in armbian/rockchip-linux is renamed - declare -g BOOT_FDT_FILE="rockchip/rk3588-rock-5b-plus.dtb" # With 6.16 its available upstream - - declare -g BOOTCONFIG="rock5b-rk3588_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline tree - declare -g BOOTBRANCH="tag:v2025.04" # - declare -g BOOTPATCHDIR="v2025.04" # empty; defconfig changes are done in hook below - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOT_FDT_FILE="rockchip/rk3588-rock-5b-plus.dtb" + declare -g BOOTCONFIG="rock5b-rk3588_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -54,9 +51,8 @@ function post_family_config_branch_edge__rock-5b_use_mainline_uboot() { } } -function post_config_uboot_target__extra_configs_for_rock5b_mainline_environment_in_spi() { - [[ "${BRANCH}" != "edge" ]] && return 0 +function post_config_uboot_target__extra_configs_for_rock5b_mainline_environment_in_spi() { display_alert "$BOARD" "u-boot configs for ${BOOTBRANCH} u-boot config BRANCH=${BRANCH}" "info" run_host_command_logged scripts/config --set-val CONFIG_ENV_IS_NOWHERE "n" run_host_command_logged scripts/config --set-val CONFIG_ENV_IS_IN_SPI_FLASH "y" diff --git a/config/boards/rock-5b.conf b/config/boards/rock-5b.conf index 46da1f0c2..d37dc444b 100644 --- a/config/boards/rock-5b.conf +++ b/config/boards/rock-5b.conf @@ -31,12 +31,12 @@ function post_family_tweaks__rock5b_naming_audios() { function post_family_config_branch_edge__rock-5b_use_mainline_uboot() { display_alert "$BOARD" "mainline (next branch) u-boot overrides for $BOARD / $BRANCH" "info" - declare -g BOOTCONFIG="rock5b-rk3588_defconfig" # override the default for the board/family - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/Kwiboo/u-boot-rockchip.git" # We ❤️ Kwiboo's tree - declare -g BOOTBRANCH="branch:rk3xxx-2024.04" # commit:31522fe7b3c7733313e1c5eb4e340487f6000196 as of 2024-04-01 - declare -g BOOTPATCHDIR="v2024.04-rock5b-radxa" # empty; defconfig changes are done in hook below - declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g BOOTCONFIG="rock5b-rk3588_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/Kwiboo/u-boot-rockchip.git" + declare -g BOOTBRANCH="branch:rk3xxx-2024.04" # commit:31522fe7b3c7733313e1c5eb4e340487f6000196 as of 2024-04-01 + declare -g BOOTPATCHDIR="v2024.04-rock5b-radxa" + declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/rock-5t.conf b/config/boards/rock-5t.conf index 600aba21a..76c8345f8 100644 --- a/config/boards/rock-5t.conf +++ b/config/boards/rock-5t.conf @@ -15,7 +15,7 @@ IMAGE_PARTITION_TABLE="gpt" declare -g UEFI_EDK2_BOARD_ID="rock-5t" # This _only_ used for uefi-edk2-rk3588 extension function post_family_tweaks__rock5b_naming_audios() { - display_alert "$BOARD" "Renaming rock5b audios" "info" + display_alert "$BOARD" "Renaming rock5t audios" "info" mkdir -p $SDCARD/etc/udev/rules.d/ echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-hdmi1-sound", ENV{SOUND_DESCRIPTION}="HDMI1 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules @@ -25,4 +25,39 @@ function post_family_tweaks__rock5b_naming_audios() { echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-es8316-sound", ENV{SOUND_DESCRIPTION}="ES8316 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules return 0 -} \ No newline at end of file +} + +# Mainline u-boot tree - use post_family_config hook to override family config +function post_family_config__rock5t_use_mainline_uboot() { + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" + + declare -g BOOT_FDT_FILE="rockchip/rk3588-rock-5t.dtb" + declare -g BOOTCONFIG="rock5t-rk3588_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.04" + declare -g BOOTPATCHDIR="v2025.04" + declare -g BOOTDIR="u-boot-${BOARD}" + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" + unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already + + # Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go + function write_uboot_platform() { + dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none + } + + function write_uboot_platform_mtd() { + flashcp -v -p "$1/u-boot-rockchip-spi.bin" /dev/mtd0 + } +} + + +function post_config_uboot_target__extra_configs_for_rock5b_mainline_environment_in_spi() { + display_alert "$BOARD" "u-boot configs for ${BOOTBRANCH} u-boot config BRANCH=${BRANCH}" "info" + run_host_command_logged scripts/config --set-val CONFIG_ENV_IS_NOWHERE "n" + run_host_command_logged scripts/config --set-val CONFIG_ENV_IS_IN_SPI_FLASH "y" + run_host_command_logged scripts/config --set-val CONFIG_ENV_SECT_SIZE_AUTO "y" + run_host_command_logged scripts/config --set-val CONFIG_ENV_OVERWRITE "y" + run_host_command_logged scripts/config --set-val CONFIG_ENV_SIZE "0x20000" + run_host_command_logged scripts/config --set-val CONFIG_ENV_OFFSET "0xc00000" +} diff --git a/config/boards/rock-s0.conf b/config/boards/rock-s0.conf index 74b69ef1b..e503ce046 100644 --- a/config/boards/rock-s0.conf +++ b/config/boards/rock-s0.conf @@ -1,5 +1,4 @@ # Rockchip RK3308 quad core 512MB SoC WiFi -# https://radxa.com/products/rocks/s0 BOARD_NAME="Rock S0" BOARDFAMILY="rockchip64" diff --git a/config/boards/rock64.conf b/config/boards/rock64.csc similarity index 90% rename from config/boards/rock64.conf rename to config/boards/rock64.csc index e6d7a1d06..5bb3676a8 100644 --- a/config/boards/rock64.conf +++ b/config/boards/rock64.csc @@ -1,7 +1,7 @@ # Rockchip RK3328 quad core 1GB-4GB GBE eMMC USB3 SPI BOARD_NAME="Rock 64" BOARDFAMILY="rockchip64" -BOARD_MAINTAINER="clee" +BOARD_MAINTAINER="" BOOTCONFIG="rock64-rk3328_defconfig" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current" diff --git a/config/boards/rockpi-4a.csc b/config/boards/rockpi-4a.csc index d30f11753..ca25b26c1 100644 --- a/config/boards/rockpi-4a.csc +++ b/config/boards/rockpi-4a.csc @@ -1,7 +1,7 @@ # Rockchip RK3399 hexa core 1-4GB SoC GBe eMMC USB3 BOARD_NAME="Rockpi 4A" BOARDFAMILY="rockchip64" -BOARD_MAINTAINER="clee" +BOARD_MAINTAINER="" BOOTCONFIG="rock-pi-4-rk3399_defconfig" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current" diff --git a/config/boards/rockpi-s.conf b/config/boards/rockpi-s.conf index 807d6e4ff..90c15e2ee 100644 --- a/config/boards/rockpi-s.conf +++ b/config/boards/rockpi-s.conf @@ -1,5 +1,4 @@ # Rockchip RK3308 quad core 256-512MB SoC WiFi -# https://radxa.com/products/rockpi/pis BOARD_NAME="Rockpi S" BOARDFAMILY="rockchip64" diff --git a/config/boards/rpi4b.conf b/config/boards/rpi4b.conf index 9c4406a8b..d991e9524 100644 --- a/config/boards/rpi4b.conf +++ b/config/boards/rpi4b.conf @@ -5,4 +5,4 @@ declare -g BOARD_MAINTAINER="PanderMusubi teknoid" declare -g KERNEL_TARGET="current,edge,legacy" declare -g ASOUND_STATE="asound.state.rpi" declare -g KERNEL_TEST_TARGET="current" -declare -g MODULES="i2c_dev" +declare -g MODULES="i2c_dev" \ No newline at end of file diff --git a/config/boards/sk-am62b.conf b/config/boards/sk-am62b.conf index fbd923331..96a030386 100644 --- a/config/boards/sk-am62b.conf +++ b/config/boards/sk-am62b.conf @@ -1,16 +1,17 @@ -# TI AM62 quad core 2GB 2xGBE OSPI HDMI +# Texas Instruments AM62 quad core 2GB 2xGBE OSPI HDMI BOARD_NAME="SK-AM62B" BOARDFAMILY="k3" -BOARD_MAINTAINER="glneo" +BOARD_MAINTAINER="jonaswood01" +BOOT_SOC="am62" BOOTCONFIG="am62x_evm_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am625-sk.dts" TIBOOT3_BOOTCONFIG="am62x_evm_r5_defconfig" TIBOOT3_FILE="tiboot3-am62x-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="lite" OPTEE_ARGS="CFG_TEE_CORE_LOG_LEVEL=1" diff --git a/config/boards/sk-am62p.conf b/config/boards/sk-am62p.conf index 860357b69..b2cf7d701 100644 --- a/config/boards/sk-am62p.conf +++ b/config/boards/sk-am62p.conf @@ -1,16 +1,17 @@ -# TI AM62P quad core 8GB 2xGBE OSPI HDMI +# Texas Instruments AM62P quad core 8GB 2xGBE OSPI HDMI BOARD_NAME="SK-AM62P" BOARDFAMILY="k3" -BOARD_MAINTAINER="Grippy98" +BOARD_MAINTAINER="jonaswood01" +BOOT_SOC="am62p" BOOTCONFIG="am62px_evm_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am62p5-sk.dts" TIBOOT3_BOOTCONFIG="am62px_evm_r5_defconfig" TIBOOT3_FILE="tiboot3-am62px-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="lite" OPTEE_ARGS="CFG_TEE_CORE_LOG_LEVEL=1" diff --git a/config/boards/sk-am64b.conf b/config/boards/sk-am64b.conf index 153f34c1b..67ca011e4 100644 --- a/config/boards/sk-am64b.conf +++ b/config/boards/sk-am64b.conf @@ -1,8 +1,9 @@ -# TI AM64 dual core 2GB 2xGBE USB3 WiFi OSPI +# Texas Instruments AM64 dual core 2GB 2xGBE USB3 WiFi OSPI BOARD_NAME="SK-AM64B" BOARDFAMILY="k3" -BOARD_MAINTAINER="glneo" +BOARD_MAINTAINER="jonaswood01" +BOOT_SOC="am64" BOOTCONFIG="am64x_evm_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am642-sk.dts" @@ -10,8 +11,8 @@ TIBOOT3_BOOTCONFIG="am64x_evm_r5_defconfig" TIBOOT3_FILE="tiboot3-am64x_sr2-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" HAS_VIDEO_OUTPUT="no" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="lite" OPTEE_ARGS="" diff --git a/config/boards/sk-am68.conf b/config/boards/sk-am68.conf index dada63fac..3f8adac0f 100644 --- a/config/boards/sk-am68.conf +++ b/config/boards/sk-am68.conf @@ -1,16 +1,17 @@ -# TI SK-AM68 dual core 16GB 8TOPS GBE USB3 OSPI DisplayPort HDMI +# Texas Instruments AM68 dual core 16GB 8TOPS GBE USB3 OSPI DisplayPort HDMI BOARD_NAME="SK-AM68" BOARDFAMILY="k3" BOARD_MAINTAINER="glneo" +BOOT_SOC="j721s2" BOOTCONFIG="j721s2_evm_a72_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am68-sk-base-board.dts" TIBOOT3_BOOTCONFIG="j721s2_evm_r5_defconfig" TIBOOT3_FILE="tiboot3-j721s2-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="generic" ATF_K3_USART_OFFSET="K3_USART=0x8" diff --git a/config/boards/sk-am69.conf b/config/boards/sk-am69.conf index bb3eeda78..e34de73c6 100644 --- a/config/boards/sk-am69.conf +++ b/config/boards/sk-am69.conf @@ -1,16 +1,17 @@ -# TI SK-AM69 octa core 32GB 32TOPS GBE USB3 OSPI DisplayPort HDMI +# Texas Instruments AM69 octa core 32GB 32TOPS GBE USB3 OSPI DisplayPort HDMI BOARD_NAME="SK-AM69" BOARDFAMILY="k3" BOARD_MAINTAINER="glneo" +BOOT_SOC="j784s4" BOOTCONFIG="am69_sk_a72_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am69-sk.dts" TIBOOT3_BOOTCONFIG="am69_sk_r5_defconfig" TIBOOT3_FILE="tiboot3-j784s4-hs-fs-evm.bin" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="j784s4" ATF_K3_USART_OFFSET="K3_USART=0x8" diff --git a/config/boards/sk-tda4vm.conf b/config/boards/sk-tda4vm.conf index f3b834881..39dbf0080 100644 --- a/config/boards/sk-tda4vm.conf +++ b/config/boards/sk-tda4vm.conf @@ -1,8 +1,9 @@ -# TI TDA4VM dual core 4GB GBE USB3 OSPI DisplayPort HDMI +# Texas Instruments TDA4VM dual core 4GB GBE USB3 OSPI DisplayPort HDMI BOARD_NAME="SK-TDA4VM" BOARDFAMILY="k3" BOARD_MAINTAINER="glneo" +BOOT_SOC="j721e" BOOTCONFIG="j721e_evm_a72_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-j721e-sk.dts" @@ -12,8 +13,8 @@ SYSFW_FILE="sysfw-j721e-gp-evm.itb" TISPL_FILE="tispl.bin_unsigned" UBOOT_FILE="u-boot.img_unsigned" DEFAULT_CONSOLE="serial" -KERNEL_TARGET="current,edge" -KERNEL_TEST_TARGET="current" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge,edge" +KERNEL_TEST_TARGET="vendor" SERIALCON="ttyS2" ATF_BOARD="generic" OPTEE_ARGS="" diff --git a/config/boards/station-m1.csc b/config/boards/station-m1.csc index 8748f9e1e..6f46ee72d 100644 --- a/config/boards/station-m1.csc +++ b/config/boards/station-m1.csc @@ -21,11 +21,9 @@ function post_family_tweaks__station_m1() { function post_family_config__station_m1_use_mainline_uboot() { display_alert "$BOARD" "Using mainline U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" declare -g BOOTBRANCH="tag:v2024.07" declare -g BOOTPATCHDIR="v2024.07/board_${BOARD}" - # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency - declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" # Disable stuff from rockchip64_common; we're using binman here which does all the work already diff --git a/config/boards/thinkpad-x13s.conf b/config/boards/thinkpad-x13s.conf index 017e9bf12..d43424a3e 100644 --- a/config/boards/thinkpad-x13s.conf +++ b/config/boards/thinkpad-x13s.conf @@ -189,7 +189,8 @@ function x13s_obtain_firmware() { mkdir -p "${fw_target}/qcom/sc8280xp/LENOVO/21BX" # video acceleration firmware/interconnect stuff; get it from ironrobin's repo; - wget --output-document "${fw_target}/qcom/sc8280xp/LENOVO/21BX/qcvss8280.mbn" "https://raw.githubusercontent.com/ironrobin/x13s-alarm/trunk/x13s-firmware/qcvss8280.mbn" + curl -o "${fw_target}/qcom/sc8280xp/LENOVO/21BX/qcvss8280.mbn" \ + "https://raw.githubusercontent.com/ironrobin/x13s-alarm/trunk/x13s-firmware/qcvss8280.mbn" # add a link to audio fw (cd "${fw_target}/qcom/sc8280xp" && ln -s "LENOVO/21BX/audioreach-tplg.bin" "SC8280XP-LENOVO-X13S-tplg.bin") diff --git a/config/boards/tinkerboard-2.csc b/config/boards/tinkerboard-2.csc index d01674aae..963b7bd7a 100644 --- a/config/boards/tinkerboard-2.csc +++ b/config/boards/tinkerboard-2.csc @@ -11,6 +11,6 @@ BOOT_FDT_FILE="rockchip/rk3399-tinker-2.dtb" SERIALCON="ttyS2" BOOT_SCENARIO="binman" # 'blobless' also works; but some RAM issues found; see rk33/rk3399_ddr_800MHz_v1.27.bin in rockchip64_common.inc BOARD_FIRMWARE_INSTALL="-full" # Install full firmware, for rtl8822ce firmware and others -BOOTBRANCH="tag:v2025.04" # v2025.04 ... +BOOTBRANCH="tag:v2025.04" BOOTPATCHDIR='legacy/u-boot-tinkerboard2' # ... with _only_ the patches we need for TB2, not the default rockchip64 DDR_BLOB="rk33/rk3399_ddr_800MHz_v1.27.bin" # Different blob for TB2 diff --git a/config/boards/tmds62levm.conf b/config/boards/tmds62levm.conf new file mode 100644 index 000000000..517c855ae --- /dev/null +++ b/config/boards/tmds62levm.conf @@ -0,0 +1,20 @@ +# Texas Instruments AM62L dual core 2GB 2xGBE OSPI HDMI + +BOARD_NAME="TMDS62LEVM" +BOARDFAMILY="k3" +BOARD_MAINTAINER="jonaswood01" +BOOT_SOC="am62l" +BOOTCONFIG="am62lx_evm_defconfig" +BOOTFS_TYPE="fat" +BOOT_FDT_FILE="ti/k3-am62l3-evm.dts" +TIBOOT3_FILE="tiboot3.bin" +DEFAULT_CONSOLE="serial" +KERNEL_TARGET="vendor,vendor-rt,vendor-edge" +KERNEL_TEST_TARGET="vendor" +SERIALCON="ttyS2" +ATF_BOARD="am62l" +EXTRA_ATF_TARGETS="build/k3/am62l/release/bl1.bin:bl1.bin" +OPTEE_ARGS="CFG_TEE_CORE_LOG_LEVEL=1" +OPTEE_PLATFORM="k3-am62lx" +EXTRA_BOOT_ARGS="BL1=bl1.bin" +CC33XX_SUPPORT="yes" diff --git a/config/boards/xiaomi-elish.conf b/config/boards/xiaomi-elish.conf index 66ece1e2e..0d6a20c30 100644 --- a/config/boards/xiaomi-elish.conf +++ b/config/boards/xiaomi-elish.conf @@ -1,3 +1,4 @@ +# Octa-core 6/8GB 128/256GB lcd tablet # Generate kernel and rootfs image for Qcom ABL booting declare -g BOARD_NAME="Xiaomi Elish" declare -g BOARD_MAINTAINER="amazingfate" diff --git a/config/boards/youyeetoo-r1-v3.csc b/config/boards/youyeetoo-r1-v3.csc index 07867f6e3..a55f3db63 100644 --- a/config/boards/youyeetoo-r1-v3.csc +++ b/config/boards/youyeetoo-r1-v3.csc @@ -7,6 +7,7 @@ BOOT_SOC="rk3588" KERNEL_TARGET="vendor,current,edge" KERNEL_TEST_TARGET="vendor,edge" FULL_DESKTOP="yes" +ASOUND_STATE="asound.state.youyeetoo-r1" BOOT_LOGO="desktop" IMAGE_PARTITION_TABLE="gpt" BOOT_FDT_FILE="rockchip/rk3588s-youyeetoo-r1.dtb" @@ -17,7 +18,7 @@ function post_family_tweaks__youyeetoo_r1_naming_audios() { mkdir -p $SDCARD/etc/udev/rules.d/ echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-hdmi0-sound", ENV{SOUND_DESCRIPTION}="HDMI0 Audio"' > $SDCARD/etc/udev/rules.d/90-naming-audios.rules - echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-es8388-sound", ENV{SOUND_DESCRIPTION}="ES8388 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules + echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-es8323-sound", ENV{SOUND_DESCRIPTION}="ES8323 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules return 0 } @@ -31,17 +32,17 @@ function post_family_tweaks__youyeetoo_r1_naming_udev_network_interfaces() { EOF } -# Mainline U-Boot function post_family_config__youyeetoo_r1_use_mainline_uboot() { display_alert "$BOARD" "Using mainline (next branch) U-Boot for $BOARD / $BRANCH" "info" - declare -g BOOTCONFIG="youyeetoo-r1-rk3588s_defconfig" # Use generic defconfig which should boot all RK3588 boards - declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc - declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ Mainline U-Boot - declare -g BOOTBRANCH="tag:v2025.04" - declare -g BOOTPATCHDIR="v2025.04" - # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency + declare -g BOOTCONFIG="youyeetoo-r1-rk3588s_defconfig" + declare -g BOOTDELAY=1 + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" + declare -g BOOTBRANCH="tag:v2025.10" + declare -g BOOTPATCHDIR="v2025.10" + unset BOOT_FDT_FILE + # Don't set BOOTDIR, allow shared U-Boot source directory for disk space efficiency declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin" # Disable stuff from rockchip64_common; we're using binman here which does all the work already @@ -57,7 +58,7 @@ function post_family_config__youyeetoo_r1_use_mainline_uboot() { # include/configs/rockchip-common.h # -#define BOOT_TARGETS "mmc1 mmc0 nvme scsi usb pxe dhcp" # +#define BOOT_TARGETS "mmc0 nvme mmc1 scsi usb pxe dhcp" -# On youyeetoo R1, mmc0 is the SD card, mmc1 is the eMMC slot +# On Youyeetoo R1, mmc0 is the SD card, mmc1 is the eMMC slot function pre_config_uboot_target__youyeetoo_r1_patch_rockchip_common_boot_order() { declare -a rockchip_uboot_targets=("mmc0" "nvme" "mmc1" "scsi" "usb" "pxe" "dhcp") # for future make-this-generic delight display_alert "u-boot for ${BOARD}/${BRANCH}" "u-boot: adjust boot order to '${rockchip_uboot_targets[*]}'" "info" @@ -65,14 +66,17 @@ function pre_config_uboot_target__youyeetoo_r1_patch_rockchip_common_boot_order( regular_git diff -u include/configs/rockchip-common.h || true } +# Configure rtw89_8852be Wi-Fi driver to disable ASPM and power-save modes +# for improved stability on mainline builds; skipped for the 'vendor' branch. function post_family_tweaks__youyeetoo_r1 { - if [[ "${BRANCH}" != "vendor" ]]; then - display_alert "$BOARD" "Adjusting rtw89_8852be module" "info" - cat <<- EOF > "${SDCARD}/etc/modprobe.d/rtw8852be.conf" - options rtw89_pci disable_aspm_l1=y disable_aspm_l1ss=y - options rtw89pci disable_aspm_l1=y disable_aspm_l1ss=y - options rtw89_core disable_ps_mode=y - options rtw89core disable_ps_mode=y - EOF - fi + [[ "${BRANCH}" == "vendor" ]] && return 0 + + display_alert "$BOARD" "Adjusting rtw89_8852be module" "info" + + cat <<- EOF > "${SDCARD}/etc/modprobe.d/rtw8852be.conf" + options rtw89_pci disable_aspm_l1=y disable_aspm_l1ss=y + options rtw89pci disable_aspm_l1=y disable_aspm_l1ss=y + options rtw89_core disable_ps_mode=y + options rtw89core disable_ps_mode=y + EOF } diff --git a/config/bootenv/rk3506.txt b/config/bootenv/rk3506.txt new file mode 100644 index 000000000..e94d6053e --- /dev/null +++ b/config/bootenv/rk3506.txt @@ -0,0 +1,3 @@ +verbosity=1 +extraargs=coherent_pool=4M +bootlogo=false diff --git a/config/bootscripts/boot-generic.cmd.template b/config/bootscripts/boot-generic.cmd.template new file mode 100644 index 000000000..6c7dc181a --- /dev/null +++ b/config/bootscripts/boot-generic.cmd.template @@ -0,0 +1,537 @@ +# DO NOT EDIT THIS FILE +# +# Please edit /boot/armbianEnv.txt to set supported parameters +# + +# This bootscript was generated on ${BOOTSCRIPT_TEMPLATE__CREATE_DATE} + +# NOTE +# This file is the result of rendering a template using 'envsubst'. +# Any variable starting with 'BOOTSCRIPT_TEMPLATE__' is expected to be rendered. +# The build system will check if any variable is left after rendering and will +# exit with error if any unrendered variables are found. +# Check the following files for more details: +# lib/functions/bsp/armbian-bsp-cli-deb.sh +# lib/functions/rootfs/distro-agnostic.sh + +# NOTE +# If you intend to use 'outside' of 'global' variables from U-Boot, make sure that you do not change them! +# The boot logic will attempt a list of 'boot_targets' that all might rely on (environment) variables that +# have been set by U-Boot, either compile-time or as part of U-Boot's default 'bootcmd'. +# Any variable that this bootscript uses needs to be set explicitly and not conflict with any pre-set variables. +# Variables that we might change will be saved in preset_x and variables we use will be copied into l_x. + +# default environment variables +setenv align_overlap_oboe_avoidance "on" +setenv align_to "${BOOTSCRIPT_TEMPLATE__ALIGN_TO}" +setenv consoleargs_display "${BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE}" +setenv consoleargs_serial "${BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE}" +setenv console "both" +setenv docker_optimizations "on" +setenv earlycon "off" +setenv exit_on_critical_errors "on" +setenv family "${BOOTSCRIPT_TEMPLATE__BOARD_FAMILY}" +setenv fdt_extrasize "0x00010000" +setenv kver +setenv load_addr_calc +setenv overlay_error "false" +setenv preset_fdtdir "${fdtdir}" +setenv preset_fdtfile "${fdtfile}" +setenv preset_kernel_comp_addr_r "${kernel_comp_addr_r}" +setenv preset_kernel_comp_size "${kernel_comp_size}" +setenv rootdev "/dev/mmcblk${devnum}p${distro_bootpart}" +setenv rootfstype "${BOOTSCRIPT_TEMPLATE__ROOTFS_TYPE}" +setenv vendor "${BOOTSCRIPT_TEMPLATE__BOARD_VENDOR}" +setenv verbosity "1" + +# load addresses +setenv load_addr "${BOOTSCRIPT_TEMPLATE__LOAD_ADDR}" + +# NOTE +# No 'BOOTSCRIPT_TEMPLATE__' references beyond this point. + +# environment run variables +setenv func_align_addr_next ' + test "${align_overlap_oboe_avoidance}" = "on" && setexpr l_addr_next ${l_addr_next} + 1 ; + setexpr l_modulo ${l_addr_next} % ${align_to} ; + if itest ${l_modulo} -gt 0 ; then + setexpr l_addr_next ${l_addr_next} / ${align_to} ; + setexpr l_addr_next ${l_addr_next} + 1 ; + setexpr l_addr_next ${l_addr_next} * ${align_to} ; + fi' +setenv func_inform 'test "${verbosity}" = "" || itest ${verbosity} -gt 0 && echo "${l_message}"' +setenv func_warn 'echo "** WARNING: ${l_message}"' +setenv func_critical_error ' + echo "!! CRITICAL: ${l_message}" ; + if test "${exit_on_critical_errors}" = "on" ; then + false ; + else + true ; + fi' + +# set some defaults in case there are no pre-sets +if test "${envfile}" = "" ; then + setenv l_envfile 'armbianEnv.txt' +else + setenv l_envfile "${envfile}" +fi + +echo "Boot script loaded from ${devtype} ${devnum}:${distro_bootpart}." + +# load (merge) on-disk environment +setenv l_file "${prefix}${l_envfile}" +if test -e ${devtype} ${devnum}:${distro_bootpart} ${l_file} ; then + if load ${devtype} ${devnum}:${distro_bootpart} ${load_addr} ${l_file} ; then + if env import -t ${load_addr} ${filesize} ; then + setenv l_message "Loaded/imported environment ${l_file} to/from ${load_addr}." + run func_inform + else + setenv l_message "Could not import environment ${l_file} - using default environment!" + run func_warn + fi + else + setenv l_message "Could not load environment ${l_file} - using default environment!" + run func_warn + fi +fi + +# compose kernel commandline options (bootargs) +setenv consoleargs +if test "${console}" = "display" || test "${console}" = "both" ; then + if test -n "${consoleargs_display}" ; then + setenv consoleargs "${consoleargs_display} ${consoleargs}" + fi +fi +if test "${console}" = "serial" || test "${console}" = "both" ; then + if test -n "${consoleargs_serial}" ; then + setenv consoleargs "${consoleargs_serial} ${consoleargs}" + fi +fi +if test "${earlycon}" = "on" ; then + setenv consoleargs "earlycon ${consoleargs}" +fi +if test "${bootlogo}" = "true" ; then + setenv consoleargs "splash plymouth.ignore-serial-consoles ${consoleargs}" +else + setenv consoleargs "splash=verbose ${consoleargs}" +fi + +part uuid ${devtype} ${devnum}:${distro_bootpart} l_ubootpart + +setenv bootargs "root=${rootdev} rootfstype=${rootfstype} rootwait ${consoleargs} consoleblank=0 loglevel=${verbosity} ubootpart=${l_ubootpart} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}" + +if test "${docker_optimizations}" = "on" ; then + setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory" +fi + +if test "${vendor}" = "allwinner" ; then + if test "${disp_mem_reserves}" = "off" ; then + setenv bootargs "${bootargs} sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_fb_mem_reserve=16" + fi +fi +if test "${vendor}" = "marvell" ; then + # +fi +if test "${vendor}" = "rockchip" ; then + # +fi + +if test "${load_addr_calc}" = "" ; then + if setexpr load_addr_calc 1 + 1 ; then + setenv load_addr_calc 'on' + else + setenv load_addr_calc 'off' + fi +fi +if test "${load_addr_calc}" != "on" ; then + setenv load_addr_calc 'off' + + setenv l_message "Using fixed load addresses." + run func_inform + setenv l_message " fdt_addr_r: ${fdt_addr_r}" + run func_inform + setenv l_message " kernel_addr_r: ${kernel_addr_r}" + run func_inform + setenv l_message " ramdisk_addr_r: ${ramdisk_addr_r}" + run func_inform +fi + +if test "${kver}" != "" ; then + setenv l_message "Using version override ${kver} for image loading." + run func_inform +fi + +# set a default kernel image type in case 'setexpr' not available +if test "${cpu}" = "armv8" ; then + # aarch64 uses a flat kernel image + setenv l_kernel_image_type "flat" + setenv l_bootfile "Image${kver}" +else + if test "${cpu}" = "armv7" ; then + # aarch32 mostly uses compressed kernel image + setenv l_kernel_image_type "compressed" + setenv l_bootfile "zImage${kver}" + else + # per default use compressed kernel image + setenv l_kernel_image_type "compressed" + setenv l_bootfile "zImage${kver}" + fi +fi + +setenv l_ramdiskfile "uInitrd${kver}" + +# $fdtdir: +# some boards use "${prefix}dtb/" others use "${prefix}dtb/${vendor}/" as base location for the DT files +# user can also override by specifying an fdtdir=... in armbianEnv.txt +# try any U-Boot built-in (or pre-set) fdtdir as last resort +# $fdtfile: +# some boards use a "filename.dts" others use "${vendor}/filename.dts" +# user can also override by specifying an fdtfile=... in armbianEnv.txt +# strip any leading path components and try any U-Boot built-in (or pre-set) fdtfile as last resort + +setenv l_fdtfile_basename +setexpr l_fdtfile_basename sub ".*/" "" "${fdtfile}" +if test "${l_fdtfile_basename}" = "" ; then + setenv l_fdtfile_basename "${fdtfile}" +fi + +setenv l_fdtdir "${fdtdir}" +setenv l_fdtfile "${l_fdtfile_basename}" +if test -e ${devtype} ${devnum}:${distro_bootpart} "${l_fdtdir}/${l_fdtfile}" ; then + true +else + setenv l_fdtdir "${prefix}dtb${kver}/${vendor}" + setenv l_fdtfile "${l_fdtfile_basename}" + if test -e ${devtype} ${devnum}:${distro_bootpart} "${l_fdtdir}/${l_fdtfile}" ; then + true + else + setenv l_fdtdir "${prefix}dtb${kver}" + setenv l_fdtfile "${l_fdtfile_basename}" + if test -e ${devtype} ${devnum}:${distro_bootpart} "${l_fdtdir}/${l_fdtfile}" ; then + true + else + setenv l_fdtdir "${fdtdir}" + setenv l_fdtfile "${fdtfile}" + if test -e ${devtype} ${devnum}:${distro_bootpart} "${l_fdtdir}/${l_fdtfile}" ; then + true + else + setenv l_fdtdir "${preset_fdtdir}" + setenv l_fdtfile "${preset_fdtfile}" + if test -e ${devtype} ${devnum}:${distro_bootpart} "${l_fdtdir}/${l_fdtfile}" ; then + true + else + false + fi + fi + fi + fi +fi +if itest $? -ne 0 ; then + setenv l_message "Cannot find DT!" + run func_critical_error || exit +fi + +# load the device tree blob +setenv l_file "${l_fdtdir}/${l_fdtfile}" +if load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${l_file} ; then + setenv l_message "Loaded DT ${l_file} to ${fdt_addr_r}." + run func_inform + + setenv l_fdt_filesize ${filesize} + fdt addr ${fdt_addr_r} + fdt resize ${fdt_extrasize} +else + setenv l_message "Could not load DT ${l_file}!" + run func_critical_error || exit +fi + +# process "overlays=..." from $l_envfile +if test "${overlays}" != "" ; then + setenv l_message "Loading kernel provided DT overlay(s) from ${l_fdtdir}/overlay to ${load_addr} .." + run func_inform + + # as some families offer overlays with different (or no) prefixes, try to guess the most commonly seen ones + # just changing overlay_prefix= will not work for all available overlays, as some have prefixes and some do not + + setenv each_overlay + for each_overlay in ${overlays} ; do + setenv l_overlay_prefix "${overlay_prefix}" + setenv l_file "${l_fdtdir}/overlay/${l_overlay_prefix}-${each_overlay}.dtbo" + if test -e ${devtype} ${devnum}:${distro_bootpart} ${l_file} ; then + true + else + setenv l_overlay_prefix "${vendor}" + setenv l_file "${l_fdtdir}/overlay/${l_overlay_prefix}-${each_overlay}.dtbo" + if test -e ${devtype} ${devnum}:${distro_bootpart} ${l_file} ; then + setenv l_message "Found DT overlay ${l_overlay_prefix}-${each_overlay} instead of ${overlay_prefix}-${each_overlay} in ${l_fdtdir}/overlay!" + run func_warn + setenv l_message "Consider setting overlay_prefix=${l_overlay_prefix} in your ${l_envfile}." + run func_inform + true + else + setenv l_overlay_prefix "${vendor}-${soc}" + setenv l_file "${l_fdtdir}/overlay/${l_overlay_prefix}-${each_overlay}.dtbo" + if test -e ${devtype} ${devnum}:${distro_bootpart} ${l_file} ; then + setenv l_message "Found DT overlay ${l_overlay_prefix}-${each_overlay} instead of ${overlay_prefix}-${each_overlay} in ${l_fdtdir}/overlay!" + run func_warn + setenv l_message "Consider setting overlay_prefix=${l_overlay_prefix} in your ${l_envfile}." + run func_inform + true + else + false + fi + fi + fi + if itest $? -eq 0 ; then + if load ${devtype} ${devnum}:${distro_bootpart} ${load_addr} ${l_file} ; then + if fdt apply ${load_addr} ; then + setenv l_message "Applied DT overlay ${each_overlay} (${l_file})." + run func_inform + else + setenv overlay_error "true" + setenv l_message "Could NOT apply DT overlay ${each_overlay} (${l_file})!" + run func_warn + fi + else + setenv l_message "Could NOT load DT overlay ${each_overlay} (${l_file})!" + run func_warn + fi + else + setenv l_message "Could NOT find DT overlay ${each_overlay}!" + run func_warn + fi + done +fi + +# process "user_overlays=..." from $l_envfile +if test "${user_overlays}" != "" ; then + setenv l_message "Loading user provided DT overlay(s) from ${prefix}overlay-user to ${load_addr} .." + run func_inform + + setenv each_user_overlay + for each_user_overlay in ${user_overlays} ; do + setenv l_file "${prefix}overlay-user/${each_user_overlay}.dtbo" + if test -e ${devtype} ${devnum}:${distro_bootpart} ${l_file} ; then + if load ${devtype} ${devnum}:${distro_bootpart} ${load_addr} ${l_file} ; then + if fdt apply ${load_addr} ; then + setenv l_message "Applied user DT overlay ${each_user_overlay} (${l_file})." + run func_inform + else + setenv overlay_error "true" + setenv l_message "Could NOT apply user DT overlay ${each_user_overlay} (${l_file})!" + run func_warn + fi + else + setenv l_message "Could NOT load user DT overlay ${each_user_overlay} (${l_file})!" + run func_warn + fi + else + setenv l_message "Could NOT find user DT overlay ${each_user_overlay} (${l_file})!" + run func_warn + fi + done +fi +if test "${overlay_error}" = "true" ; then + setenv l_message "Could not apply DT overlays!" + run func_warn + + setenv l_file "${l_fdtdir}/${l_fdtfile}" + if load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${l_file} ; then + setenv l_message "Loaded original DT ${l_file} to ${fdt_addr_r}." + run func_inform + + setenv l_fdt_filesize ${filesize} + fdt addr ${fdt_addr_r} + fdt resize ${fdt_extrasize} + else + setenv l_message "Could not load original DT ${l_file}!" + run func_critical_error || exit + fi +else + # process any available DT fixup scripts + setenv l_fixup_scripts "${prefix}fixup.scr" + if test "${overlay_prefix}" != "" ; then + setenv l_fixup_scripts "${l_fdtdir}/overlay/${overlay_prefix}-fixup.scr ${l_fixup_scripts}" + fi + if test "${vendor}" != "" ; then + if test "${vendor}" != "${overlay_prefix}" ; then + setenv l_fixup_scripts "${l_fdtdir}/overlay/${vendor}-fixup.scr ${l_fixup_scripts}" + fi + fi + + setenv each_fixup_script + for each_fixup_script in ${l_fixup_scripts} ; do + if test -e ${devtype} ${devnum}:${distro_bootpart} ${each_fixup_script} ; then + if load ${devtype} ${devnum}:${distro_bootpart} ${load_addr} ${each_fixup_script} ; then + if source ${load_addr} ; then + setenv l_message "Loaded/sourced fixup script ${each_fixup_script} to/at ${load_addr}." + run func_inform + else + setenv l_message "Fixup script ${each_fixup_script} returned an error!" + run func_warn + fi + else + setenv l_message "Could not load fixup script ${each_fixup_script}!" + run func_warn + fi + fi + done +fi + +# resize (trim) device tree after all overlays have been applied and fixup scripts have been run +fdt resize + + +# determine the load address for the kernel image +if test "${load_addr_calc}" = "on" ; then + # get the total size of the DT + setenv l_fdt_totalsize + fdt header get l_fdt_totalsize totalsize + + if test "${l_fdt_totalsize}" = "" ; then + # could not get the total size of the DT so calculate it instead + setenv l_message "Calculating DT size." + run func_inform + + # 'fdt resize' will align upwards to 4k address boundary + setexpr l_fdt_totalsize ${l_fdt_filesize} / 0x1000 + setexpr l_fdt_totalsize ${l_fdt_totalsize} + 1 + setexpr l_fdt_totalsize ${l_fdt_totalsize} * 0x1000 + if test "${fdt_extrasize}" != "" ; then + setexpr l_fdt_totalsize ${l_fdt_totalsize} + ${fdt_extrasize} + fi + fi + + setexpr l_addr_next ${fdt_addr_r} + ${l_fdt_totalsize} + run func_align_addr_next + + setenv l_kernel_addr_r ${l_addr_next} +else + setenv l_kernel_addr_r ${kernel_addr_r} +fi + +setenv l_file "${prefix}${l_bootfile}" +if load ${devtype} ${devnum}:${distro_bootpart} ${l_kernel_addr_r} ${l_file} ; then + if test "${load_addr_calc}" = "on" ; then + setenv kernel_comp_size ${filesize} + fi + + setenv l_message "Loaded ${l_kernel_image_type} kernel image ${l_file} to ${l_kernel_addr_r}." + run func_inform +else + if test "${load_addr_calc}" = "on" ; then + setenv kernel_comp_addr_r "${preset_kernel_comp_addr_r}" + setenv kernel_comp_size "${preset_kernel_comp_size}" + fi + setenv l_message "Could not load ${l_kernel_image_type} kernel image ${l_file}!" + run func_critical_error || exit +fi + +# determine the load address for the initial ramdisk +if test "${load_addr_calc}" = "on" ; then + # vmlinux image + 0x38 contain magic (le-double) 'ARMd' + setexpr l_ptr ${l_kernel_addr_r} + 0x00000038 + setexpr.w l_magic_lsw *${l_ptr} + + setexpr l_ptr ${l_kernel_addr_r} + 0x0000003a + setexpr.w l_magic_msw *${l_ptr} + + if test "${l_magic_msw}${l_magic_lsw}" != "" && itest "${l_magic_msw}${l_magic_lsw}" -eq 0x644d5241 ; then + setenv l_kernel_image_type "flat" + else + setenv l_kernel_image_type "compressed" + fi + + if test "${l_kernel_image_type}" = "flat" ; then + # vmlinux image + 0x10 contains image_size + setexpr l_ptr ${l_kernel_addr_r} + 0x00000010 + setexpr.l l_image_size *${l_ptr} + + setenv l_message "Using ${l_kernel_image_type} kernel image image_size 0x${l_image_size} bytes to calculate initial ramdisk load address." + run func_inform + + # vmlinux image + 0x08 contains text_offset + setexpr l_ptr ${l_kernel_addr_r} + 0x00000008 + setexpr.l l_text_offset *${l_ptr} + + setenv l_message "Using ${l_kernel_image_type} kernel image text_offset 0x${l_text_offset} bytes to offset initial ramdisk load address." + run func_inform + + setexpr l_addr_next ${l_kernel_addr_r} + ${l_image_size} + run func_align_addr_next + + # take into account that U-Boot's booti_setup() might relocate the kernel image + setexpr l_addr_next ${l_addr_next} + ${l_text_offset} + else + setexpr l_addr_next ${l_kernel_addr_r} + ${filesize} + run func_align_addr_next + + setenv l_message "Using ${l_kernel_image_type} kernel image filesize 0x${filesize} bytes to calculate initial ramdisk load address." + run func_inform + fi + + setenv l_ramdisk_addr_r ${l_addr_next} +else + setenv l_ramdisk_addr_r ${ramdisk_addr_r} +fi + +setenv l_file "${prefix}${l_ramdiskfile}" +if load ${devtype} ${devnum}:${distro_bootpart} ${l_ramdisk_addr_r} ${l_file} ; then + if test "${load_addr_calc}" = "on" ; then + setexpr l_addr_next ${l_ramdisk_addr_r} + ${filesize} + run func_align_addr_next + + setenv kernel_comp_addr_r ${l_addr_next} + fi + + setenv l_message "Loaded initial ramdisk ${l_file} to ${l_ramdisk_addr_r}." + run func_inform +else + if test "${load_addr_calc}" = "on" ; then + setenv kernel_comp_addr_r "${preset_kernel_comp_addr_r}" + setenv kernel_comp_size "${preset_kernel_comp_size}" + fi + setenv l_message "Could not load initial ramdisk ${l_file}!" + run func_critical_error || exit +fi + +# attempt to prepare for kernel address space randomization +if kaslrseed ; then +else + setenv l_message "Not able to prepare for KASLR." + run func_inform +fi + +setenv l_message "Kernel commandline arguments:" +run func_inform + +setenv each_bootarg +for each_bootarg in ${bootargs} ; do + setenv l_message " ${each_bootarg}" + run func_inform +done + +if test "${l_kernel_image_type}" = "flat" ; then + booti ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r} +else + if test "${l_kernel_image_type}" = "compressed" ; then + bootz ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r} + else + # default booting command + bootz ${l_kernel_addr_r} ${l_ramdisk_addr_r} ${fdt_addr_r} + fi +fi + +# booting failed, restore environment variables that are not unique +# to this bootmeth +if test "${load_addr_calc}" = "on" ; then + # restore original presets + setenv kernel_comp_addr_r "${preset_kernel_comp_addr_r}" + setenv kernel_comp_size "${preset_kernel_comp_size}" +fi + +setenv l_message "Could not boot kernel!" +run func_critical_error || exit + +# Recompile with: +# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr diff --git a/config/bootscripts/boot-generic.cmd.template.md b/config/bootscripts/boot-generic.cmd.template.md new file mode 100644 index 000000000..bd1b44599 --- /dev/null +++ b/config/bootscripts/boot-generic.cmd.template.md @@ -0,0 +1,109 @@ +## Understanding the generic bootscript +The generic bootscript [template] attempts to [do all the things](http://www.quickmeme.com/img/55/55157deb762c88e8979fe0c515e68802cceaa45f0f35707af310059bae831ecd.jpg) found in the bootscripts of `sunxi`, `mvebu` and `rockchip64`. + +There are a number of functional blocks in the generic bootscript: + +1. Define U-Boot environment variables. +1. Load a U-Boot environment (`armbianEnv.txt` in our case). +1. Prepare kernel commandline parameters based on loaded environment settings. +1. Process device tree (DT). +1. Process the kernel image. +1. Process the initial ramdisk. +1. Load the initial ramdisk. +1. Boot the kernel with locations of the initial ramdisk and device tree. + +The DT is now loaded first, followed by the kernel image with the initial ramdisk last. + +When U-Boot has support for the command `setexpr` built in, the bootscript will calculate the load addresses of the kernel image and initial ramdisk. This ensures that no overlap issue will occur, which results in the kernel not starting or U-Boot not even trying to boot the kernel. + +In case `setexpr` is not available in U-Boot, the predefined load address `fdt_addr_r`, `kernel_addr_r` and `ramdisk_addr_r` will be used. These are either hardcoded in U-Boot, or are set in the default U-Boot environment for the board. + +### Templating +Differences and deviations in the actions or settings performed by these bootscript have been extracted and are now rendered as a template. Each board that uses the generic bootscript will have to provide input to fully render the template. +For example, they all have a serial console so all bootscripts contain actions to prepare the kernel to use the serial console. The actual console device is however not always the same. + +The following variables need to be defined on the board configuration to render the generic bootscript template: + +|Variable|Usage| +|-|-| +|`BOOTSCRIPT_TEMPLATE__ALIGN_TO`|For the calculation of load addresses by the generic bootscript, addresses need to be aligned for most CPU types. For example, for ARM64 CPUs, the start of the `Image` file to be aligned to a 2MiB (`0x00200000`) boundary. For most architectures, aligning these addresses to a 4KiB (`0x1000`) address boundary is good practice.| +|`BOOTSCRIPT_TEMPLATE__BOARD_FAMILY`|The CPU family, currently not used by the generic bootscript.| +|`BOOTSCRIPT_TEMPLATE__ROOTFS_TYPE`|The filesystem type of the root filesystem, e.g. `ext4` or `f2fs`.| +|`BOOTSCRIPT_TEMPLATE__BOARD_VENDOR`|The vendor of the board, e.g. `allwinner`, `rockchips64`.| +|`BOOTSCRIPT_TEMPLATE__LOAD_ADDR`|Some architectures/CPUs have a different load address that is used to load scripts or FDT files. Use the `loadaddr` that fits with your architecture, e.g. `0x00300000` for the Helios4 (`mvebu`) or `0x09000000` for the NanoPi R2s.| + +Two exceptions for templating are listed below: +|Variable|Usage| +|-|-| +|`BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE`|Leave this empty; it will be automatically determined (and overwritten) by `distro-agnostic.sh`. This will contain the combination of the variables `$DISPLAYCON` and `$SRC_CMDLINE`.| +|`BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE`|Leave this empty; it will be automatically determined (and overwritten) by `distro-agnostic.sh`. This will contain the combination of the variables `$SERIALCON` and `$SRC_CMDLINE`.| + +The generic bootscript template will be rendered during building. If any of the bootscript template variables are not defined, the build process will error out. + +Example of a board configuration file for the Orange Pi Zero: +``` +# Allwinner H2+ quad core 256/512MB RAM SoC WiFi SPI +BOARD_NAME="Orange Pi Zero" +BOARDFAMILY="sun8i" +BOARD_MAINTAINER="" +BOOTCONFIG="orangepi_zero_defconfig" +MODULES_CURRENT="g_serial" +MODULES_BLACKLIST="sunxi_cedrus" +DEFAULT_OVERLAYS="usbhost2 usbhost3 tve" +DEFAULT_CONSOLE="both" +HAS_VIDEO_OUTPUT="yes" +KERNEL_TARGET="legacy,current,edge" +KERNEL_TEST_TARGET="current" +CRUSTCONFIG="orangepi_zero_defconfig" + +DISPLAYCON='' +SERIALCON="ttyS0:115200,ttyGS0" + +BOOTSCRIPT='boot-generic.cmd.template:boot.cmd' +BOOTSCRIPT_TEMPLATE__ALIGN_TO='0x00001000' +BOOTSCRIPT_TEMPLATE__BOARD_FAMILY="${BOARDFAMILY:-sun8i}" +BOOTSCRIPT_TEMPLATE__BOARD_VENDOR='allwinner' +BOOTSCRIPT_TEMPLATE__LOAD_ADDR='0x45000000' +BOOTSCRIPT_TEMPLATE__ROOTFS_TYPE="${ROOTFS_TYPE:-ext4}" +BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE='' # leave empty here, use DISPLAYCON instead +BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE='' # leave empty here, use SERIALCON instead + +function orange_pi_zero_enable_xradio_workarounds() { + /usr/bin/systemctl enable xradio_unload.service +... +``` + +### Rendering of the template +The bootscript template is rendered in `lib/functions/rootfs/distro-agnostic.sh` by the function `render_bootscript_template`. + +As the display and serial console devices can be defined throughout the build process, the following functions will gather them all and process them accordingly: +- `bootscript_export_display_console` for `DISPLAYCON` +- `bootscript_export_serial_console` for `SERIALCON` + +Multiple console devices can be defined by separating them with a `,` (comma). Standard Linux kernel arguments are allowed: +``` +SERIALCON="ttyS0:115200,ttyGS0" +``` + +See [Linux kernel serial-console documentation](https://www.kernel.org/doc/html/latest/admin-guide/serial-console.html) for more information on the arguments and syntax. + +### Calculating the size of the device tree +For the device tree (DT) it depends on the U-Boot version if the bootscript can determine it's size. The `fdt` shell command has a subcommand `header get` that can return the size of the current DT in-memory. In case the size of the in-memory DT cannot be determined, the filesize of the FDT will be used - aligned to `${align_to}`. + +### Calculating the size of the linux kernel image +In case the image file is a `zImage`, the image size will be based on the filesize of the `zImage`. (Self-)extraction of the image will be done into a different area of memory. +In case the image file is an `Image`, the bootscript will use the filesize as stated inside the `Image` file's header. + +### Calculating the size of the initial ramdisk +The initial ramdisk size is based on the filesize of the ramdisk itself. The kernel will extract it to somewhere it deems appropriate. + +# References + +- [U-Boot shell commands](https://docs.u-boot.org/en/latest/usage/index.html#shell-commands). +- [U-Boot environment variables](https://docs.u-boot.org/en/latest/usage/environment.html). +- [FDT](https://www.kernel.org/doc/html/latest/devicetree/usage-model.html). +- Initial ramdisk [initrd](https://docs.kernel.org/admin-guide/initrd.html). +- Kernel image types [[1]](https://www.baeldung.com/linux/kernel-images) [[2]](https://unix.stackexchange.com/a/295142). +- [Helios4 doesn't boot after upgrading to linux-6.6.71 (linux-image-current-mvebu_25.2.0-trunk.343)](https://forum.armbian.com/topic/49440-helios4-doesnt-boot-after-upgrading-to-linux-6671-linux-image-current-mvebu_2520-trunk343/#findComment-217099). +- [[Bug]: mvebu/Helios4: Wrong Ramdisk Image Format, Ramdisk image is corrupt or invalid #8165](https://github.com/armbian/build/issues/8165). +- [[Bug]: U-Boot load address calculation bug and DT overlap oobe #8178](https://github.com/armbian/build/issues/8178). diff --git a/config/bootscripts/boot-rk3506.cmd b/config/bootscripts/boot-rk3506.cmd index c91a0c4c6..d3bdbfaff 100644 --- a/config/bootscripts/boot-rk3506.cmd +++ b/config/bootscripts/boot-rk3506.cmd @@ -4,6 +4,7 @@ # setenv load_addr "0x2000000" +setenv ramdisk_addr_r "0x02800000" setenv overlay_error "false" # default values setenv rootdev "/dev/mmcblk0p1" diff --git a/config/bootscripts/boot-rk3576.cmd b/config/bootscripts/boot-rk3576.cmd index d39734a76..cf1157a0e 100644 --- a/config/bootscripts/boot-rk3576.cmd +++ b/config/bootscripts/boot-rk3576.cmd @@ -26,7 +26,7 @@ fi if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi -if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyS2,1500000 ${consoleargs}"; fi +if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyS0,1500000 ${consoleargs}"; fi if test "${earlycon}" = "on"; then setenv consoleargs "earlycon ${consoleargs}"; fi if test "${bootlogo}" = "true"; then setenv consoleargs "splash plymouth.ignore-serial-consoles ${consoleargs}" diff --git a/config/cli/common/main/packages b/config/cli/common/main/packages index f820d1131..2d5eca20b 100644 --- a/config/cli/common/main/packages +++ b/config/cli/common/main/packages @@ -1,6 +1,7 @@ alsa-utils bash-completion bc +btrfs-progs console-setup cron curl diff --git a/config/cli/common/main/packages.additional b/config/cli/common/main/packages.additional index e08774ee9..d6a086a5b 100644 --- a/config/cli/common/main/packages.additional +++ b/config/cli/common/main/packages.additional @@ -4,7 +4,6 @@ aptitude automake avahi-autoipd bison -btrfs-progs build-essential command-not-found cracklib-runtime diff --git a/config/cli/forky b/config/cli/forky new file mode 120000 index 000000000..f0b7e3289 --- /dev/null +++ b/config/cli/forky @@ -0,0 +1 @@ +trixie \ No newline at end of file diff --git a/config/cli/noble/main/packages.additional b/config/cli/noble/main/packages.additional index b6e76bc7d..be0baa912 100644 --- a/config/cli/noble/main/packages.additional +++ b/config/cli/noble/main/packages.additional @@ -5,7 +5,6 @@ automake avahi-autoipd bash-completion bison -btrfs-progs build-essential cracklib-runtime dkms diff --git a/config/cli/questing b/config/cli/questing new file mode 120000 index 000000000..c44ffafd2 --- /dev/null +++ b/config/cli/questing @@ -0,0 +1 @@ +noble \ No newline at end of file diff --git a/config/cli/resolute b/config/cli/resolute new file mode 120000 index 000000000..c44ffafd2 --- /dev/null +++ b/config/cli/resolute @@ -0,0 +1 @@ +noble \ No newline at end of file diff --git a/config/cli/sid/main/packages.additional b/config/cli/sid/main/packages.additional index 81b81c81e..ec98fdade 100644 --- a/config/cli/sid/main/packages.additional +++ b/config/cli/sid/main/packages.additional @@ -5,7 +5,6 @@ automake avahi-autoipd bash-completion bison -btrfs-progs build-essential cracklib-runtime dkms diff --git a/config/cli/trixie/main/packages.additional b/config/cli/trixie/main/packages.additional index 81b81c81e..ec98fdade 100644 --- a/config/cli/trixie/main/packages.additional +++ b/config/cli/trixie/main/packages.additional @@ -5,7 +5,6 @@ automake avahi-autoipd bash-completion bison -btrfs-progs build-essential cracklib-runtime dkms diff --git a/config/desktop/forky b/config/desktop/forky new file mode 120000 index 000000000..f0b7e3289 --- /dev/null +++ b/config/desktop/forky @@ -0,0 +1 @@ +trixie \ No newline at end of file diff --git a/config/desktop/questing b/config/desktop/questing new file mode 120000 index 000000000..c44ffafd2 --- /dev/null +++ b/config/desktop/questing @@ -0,0 +1 @@ +noble \ No newline at end of file diff --git a/config/desktop/resolute b/config/desktop/resolute new file mode 120000 index 000000000..c44ffafd2 --- /dev/null +++ b/config/desktop/resolute @@ -0,0 +1 @@ +noble \ No newline at end of file diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/architectures b/config/desktop/trixie/environments/kde-plasma-mobile/architectures new file mode 100644 index 000000000..54b43c7a5 --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/architectures @@ -0,0 +1 @@ +arm64, amd64 diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/armbian/create_desktop_package.sh b/config/desktop/trixie/environments/kde-plasma-mobile/armbian/create_desktop_package.sh new file mode 100644 index 000000000..c3f348eb4 --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/armbian/create_desktop_package.sh @@ -0,0 +1,28 @@ +# install sddm greeter theme +mkdir -pv "${destination}"/usr/share/sddm/themes +cp -Rv "${SRC}"/packages/blobs/desktop/sddm/themes/plasma-chili/ "${destination}"/usr/share/sddm/themes + +# install default desktop settings +mkdir -pv "${destination}"/etc/skel +cp -Rv "${SRC}"/packages/blobs/desktop/skel/. "${destination}"/etc/skel + +# install wallpapers +mkdir -pv "${destination}"/usr/share/backgrounds/armbian/ +cp -v "${SRC}"/packages/blobs/desktop/desktop-wallpapers/*.jpg "${destination}"/usr/share/backgrounds/armbian + +# install logo for login screen +mkdir -pv "${destination}"/usr/share/pixmaps/armbian +cp -v "${SRC}"/packages/blobs/desktop/icons/armbian.png "${destination}"/usr/share/pixmaps/armbian + +# set default wallpaper +#echo " +#dbus-send --session --dest=org.kde.plasmashell --type=method_call /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string: +#var Desktops = desktops(); +#for (i=0;i "${destination}"/usr/share/backgrounds/armbian/set-armbian-wallpaper.sh diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages b/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages new file mode 100644 index 000000000..1cac26cc8 --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages @@ -0,0 +1,19 @@ +plasma-mobile-full +kde-full +task-kde-desktop +kde-config-screenlocker +qtwayland5 +konsole +qt6-virtualkeyboard-plugin +maliit-framework +maliit-keyboard +xinput +sddm-theme-breeze +pulseaudio +gstreamer1.0-pulseaudio +pamix +pasystray +pavucontrol +pavucontrol-qt +pulseaudio-module-bluetooth +chromium diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages.uninstall b/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages.uninstall new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/config_base/packages.uninstall @@ -0,0 +1 @@ + diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/debian/postinst b/config/desktop/trixie/environments/kde-plasma-mobile/debian/postinst new file mode 100755 index 000000000..c4570e623 --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/debian/postinst @@ -0,0 +1,22 @@ +# overwrite stock lightdm greeter configuration + #if [ -d /etc/armbian/lightdm ]; then cp -R /etc/armbian/lightdm /etc/; fi +#if [ -f /etc/lightdm/slick-greeter.conf ]; then sed -i 's/armbian03-Dre0x-Minum-dark-blurred-3840x2160.jpg/armbian-4k-black-psycho-gauss.jpg/g' /etc/lightdm/slick-greeter.conf; fi + +# Disable Pulseaudio timer scheduling which does not work with sndhdmi driver +if [ -f /etc/pulse/default.pa ]; then sed "s/load-module module-udev-detect$/& tsched=0/g" -i /etc/pulse/default.pa; fi + +# enable pulse audio +systemctl preset pulseaudio.service + +#configure sddm +mkdir -p /etc/sddm.conf.d +cat <<- EOF > /etc/sddm.conf.d/armbian.conf + [Theme] + Current=breeze + [General] + InputMethod=qtvirtualkeyboard + [X11] + DisplayCommand=/usr/share/sddm/scripts/Xsetup + [Wayland] + CompositorCommand=weston --shell=kiosk # @TODO figure out how to rotate with weston and wayland +EOF diff --git a/config/desktop/trixie/environments/kde-plasma-mobile/support b/config/desktop/trixie/environments/kde-plasma-mobile/support new file mode 100644 index 000000000..7da76439d --- /dev/null +++ b/config/desktop/trixie/environments/kde-plasma-mobile/support @@ -0,0 +1 @@ +csc \ No newline at end of file diff --git a/config/distributions/bookworm/support b/config/distributions/bookworm/support index a23e5fb94..03cd47015 100644 --- a/config/distributions/bookworm/support +++ b/config/distributions/bookworm/support @@ -1 +1 @@ -supported +csc diff --git a/config/distributions/forky/architectures b/config/distributions/forky/architectures new file mode 100644 index 000000000..6103381d1 --- /dev/null +++ b/config/distributions/forky/architectures @@ -0,0 +1 @@ +arm64,armhf,riscv64,amd64 diff --git a/config/distributions/forky/name b/config/distributions/forky/name new file mode 100644 index 000000000..caff591ed --- /dev/null +++ b/config/distributions/forky/name @@ -0,0 +1 @@ +Debian 14 Forky diff --git a/config/distributions/forky/order b/config/distributions/forky/order new file mode 100644 index 000000000..f599e28b8 --- /dev/null +++ b/config/distributions/forky/order @@ -0,0 +1 @@ +10 diff --git a/config/distributions/forky/support b/config/distributions/forky/support new file mode 100644 index 000000000..03cd47015 --- /dev/null +++ b/config/distributions/forky/support @@ -0,0 +1 @@ +csc diff --git a/config/distributions/forky/upgrade b/config/distributions/forky/upgrade new file mode 100644 index 000000000..038d718da --- /dev/null +++ b/config/distributions/forky/upgrade @@ -0,0 +1 @@ +testing diff --git a/config/distributions/plucky/order b/config/distributions/plucky/order index 45a4fb75d..ec635144f 100644 --- a/config/distributions/plucky/order +++ b/config/distributions/plucky/order @@ -1 +1 @@ -8 +9 diff --git a/config/distributions/questing/architectures b/config/distributions/questing/architectures new file mode 100644 index 000000000..6103381d1 --- /dev/null +++ b/config/distributions/questing/architectures @@ -0,0 +1 @@ +arm64,armhf,riscv64,amd64 diff --git a/config/distributions/questing/name b/config/distributions/questing/name new file mode 100644 index 000000000..c14c294d0 --- /dev/null +++ b/config/distributions/questing/name @@ -0,0 +1 @@ +Ubuntu questing 25.10 diff --git a/config/distributions/questing/order b/config/distributions/questing/order new file mode 100644 index 000000000..b4de39476 --- /dev/null +++ b/config/distributions/questing/order @@ -0,0 +1 @@ +11 diff --git a/config/distributions/questing/support b/config/distributions/questing/support new file mode 100644 index 000000000..03cd47015 --- /dev/null +++ b/config/distributions/questing/support @@ -0,0 +1 @@ +csc diff --git a/config/distributions/questing/upgrade b/config/distributions/questing/upgrade new file mode 100644 index 000000000..621e94f0e --- /dev/null +++ b/config/distributions/questing/upgrade @@ -0,0 +1 @@ +none diff --git a/config/distributions/resolute/architectures b/config/distributions/resolute/architectures new file mode 100644 index 000000000..6103381d1 --- /dev/null +++ b/config/distributions/resolute/architectures @@ -0,0 +1 @@ +arm64,armhf,riscv64,amd64 diff --git a/config/distributions/resolute/name b/config/distributions/resolute/name new file mode 100644 index 000000000..e39c80aee --- /dev/null +++ b/config/distributions/resolute/name @@ -0,0 +1 @@ +Ubuntu resolute 26.04 diff --git a/config/distributions/resolute/order b/config/distributions/resolute/order new file mode 100644 index 000000000..48082f72f --- /dev/null +++ b/config/distributions/resolute/order @@ -0,0 +1 @@ +12 diff --git a/config/distributions/resolute/support b/config/distributions/resolute/support new file mode 100644 index 000000000..03cd47015 --- /dev/null +++ b/config/distributions/resolute/support @@ -0,0 +1 @@ +csc diff --git a/config/distributions/resolute/upgrade b/config/distributions/resolute/upgrade new file mode 100644 index 000000000..621e94f0e --- /dev/null +++ b/config/distributions/resolute/upgrade @@ -0,0 +1 @@ +none diff --git a/config/distributions/sid/order b/config/distributions/sid/order index ec635144f..b1bd38b62 100644 --- a/config/distributions/sid/order +++ b/config/distributions/sid/order @@ -1 +1 @@ -9 +13 diff --git a/config/distributions/trixie/upgrade b/config/distributions/trixie/upgrade index 038d718da..2f5d6d578 100644 --- a/config/distributions/trixie/upgrade +++ b/config/distributions/trixie/upgrade @@ -1 +1 @@ -testing +forky,testing diff --git a/config/kernel/linux-arm64-sc8280xp.config b/config/kernel/linux-arm64-sc8280xp.config index 658c374bf..2c7a21d35 100644 --- a/config/kernel/linux-arm64-sc8280xp.config +++ b/config/kernel/linux-arm64-sc8280xp.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.17 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -688,6 +689,12 @@ CONFIG_PARPORT_1284=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -748,7 +755,7 @@ CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_SAS_LIBSAS=m CONFIG_SCSI_SAS_ATA=y -# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ISCSI_TCP=m CONFIG_SCSI_DH=y CONFIG_SCSI_DH_RDAC=m CONFIG_SCSI_DH_HP_SW=m @@ -2333,6 +2340,10 @@ CONFIG_NFS_FS=m CONFIG_NFS_V2=m CONFIG_NFS_V4=m CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y CONFIG_CEPH_FS=m CONFIG_CIFS=m CONFIG_SMB_SERVER=m diff --git a/config/kernel/linux-bcm2711-current.config b/config/kernel/linux-bcm2711-current.config index 5ba76dadb..0a647c40e 100644 --- a/config/kernel/linux-bcm2711-current.config +++ b/config/kernel/linux-bcm2711-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -539,6 +540,12 @@ CONFIG_MTD_SPI_NOR=m CONFIG_MTD_UBI=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y @@ -1254,7 +1261,6 @@ CONFIG_VIDEO_EM28XX_V4L2=m CONFIG_VIDEO_EM28XX_ALSA=m CONFIG_VIDEO_EM28XX_DVB=m CONFIG_MEDIA_PCI_SUPPORT=y -CONFIG_MEDIA_PCI_HAILO=m CONFIG_RADIO_SAA7706H=m CONFIG_RADIO_SHARK=m CONFIG_RADIO_SHARK2=m diff --git a/config/kernel/linux-bcm2711-edge.config b/config/kernel/linux-bcm2711-edge.config index 66ee4f7d1..bccd4899d 100644 --- a/config/kernel/linux-bcm2711-edge.config +++ b/config/kernel/linux-bcm2711-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -50,6 +51,7 @@ CONFIG_ARM64_ERRATUM_2441009=y # CONFIG_CAVIUM_ERRATUM_27456 is not set CONFIG_ARM64_VA_BITS_48=y CONFIG_NR_CPUS=256 +CONFIG_HOTPLUG_CPU=y CONFIG_PARAVIRT=y CONFIG_COMPAT=y CONFIG_ARMV8_DEPRECATED=y @@ -216,18 +218,22 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_HMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m @@ -324,19 +330,9 @@ CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=y -CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -351,24 +347,14 @@ CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m @@ -537,13 +523,18 @@ CONFIG_MTD_SPI_NOR=m CONFIG_MTD_UBI=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y -CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_UBLK=m @@ -555,6 +546,7 @@ CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m CONFIG_VMWARE_VMCI=m CONFIG_BCM_VK=m +CONFIG_MISC_RP1=y CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y @@ -715,6 +707,14 @@ CONFIG_CARL9170=m CONFIG_ATH6KL=m CONFIG_ATH6KL_USB=m CONFIG_AR5523=m +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_AHB=y +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m # CONFIG_B43_PHY_N is not set @@ -776,7 +776,6 @@ CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_GPIO=m -CONFIG_KEYBOARD_TCA6416=m CONFIG_KEYBOARD_TCA8418=m CONFIG_KEYBOARD_MATRIX=m CONFIG_KEYBOARD_CAP11XX=m @@ -877,7 +876,7 @@ CONFIG_SPI_SLAVE=y CONFIG_PPS_CLIENT_LDISC=m CONFIG_PPS_CLIENT_GPIO=m CONFIG_PINCTRL_MCP23S08=m -CONFIG_PINCTRL_RP1=y +CONFIG_PINCTRL_BRCMSTB=y CONFIG_PINCTRL_BCM2712=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_BCM_VIRT=y @@ -1242,7 +1241,6 @@ CONFIG_RADIO_SHARK2=m CONFIG_RADIO_SI4713=m CONFIG_RADIO_TEA5764=m CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -1294,7 +1292,6 @@ CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV7640=m CONFIG_VIDEO_OV772X=m @@ -1407,18 +1404,18 @@ CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m CONFIG_SND_SERIAL_U16550=m CONFIG_SND_MPU401=m -CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m CONFIG_SND_HDA_CODEC_SIGMATEL=m CONFIG_SND_HDA_CODEC_VIA=m -CONFIG_SND_HDA_CODEC_HDMI=m -CONFIG_SND_HDA_CODEC_CIRRUS=m -CONFIG_SND_HDA_CODEC_CS8409=m CONFIG_SND_HDA_CODEC_CONEXANT=m CONFIG_SND_HDA_CODEC_CA0110=m CONFIG_SND_HDA_CODEC_CA0132=m CONFIG_SND_HDA_CODEC_CMEDIA=m CONFIG_SND_HDA_CODEC_SI3054=m +CONFIG_SND_HDA_CODEC_REALTEK=m +CONFIG_SND_HDA_CODEC_CIRRUS=m +CONFIG_SND_HDA_CODEC_CS8409=m +CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m @@ -1781,6 +1778,7 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_DWCMSHC=m CONFIG_MMC_SDHCI_IPROC=y CONFIG_MMC_SPI=m +CONFIG_MMC_BCM2835=y CONFIG_MMC_LITEX=m CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_MULTICOLOR=m @@ -1825,7 +1823,6 @@ CONFIG_RTC_DRV_ISL12022=m CONFIG_RTC_DRV_ISL12026=m CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_PCF8523=m -CONFIG_RTC_DRV_PCF85063=m CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_PCF8563=m CONFIG_RTC_DRV_PCF8583=m @@ -1853,6 +1850,7 @@ CONFIG_RTC_DRV_MAX6902=m CONFIG_RTC_DRV_PCF2123=m CONFIG_RTC_DRV_DS3232=m CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_PCF85063=m CONFIG_RTC_DRV_RV3029C2=m CONFIG_RTC_DRV_NTXEC=m CONFIG_DMADEVICES=y @@ -1914,11 +1912,11 @@ CONFIG_SND_BCM2835=m CONFIG_VIDEO_BCM2835=m CONFIG_VIDEO_CODEC_BCM2835=m CONFIG_VIDEO_ISP_BCM2835=m -CONFIG_COMMON_CLK_RP1=y CONFIG_COMMON_CLK_RP1_SDIO=m CONFIG_CLK_RASPBERRYPI=y CONFIG_MAILBOX=y CONFIG_BCM2835_MBOX=y +CONFIG_BCM2712_IOMMU=y CONFIG_LITEX_SOC_CONTROLLER=m CONFIG_RASPBERRYPI_POWER=y CONFIG_IIO_BUFFER_CB=m @@ -2172,9 +2170,9 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y @@ -2354,7 +2352,6 @@ CONFIG_CRYPTO_ADIANTUM=m CONFIG_CRYPTO_HCTR2=m CONFIG_CRYPTO_CHACHA20POLY1305=m CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SM3_GENERIC=m CONFIG_CRYPTO_WP512=m diff --git a/config/kernel/linux-bcm2711-legacy.config b/config/kernel/linux-bcm2711-legacy.config index 9a49cbe5b..ab2ac310e 100644 --- a/config/kernel/linux-bcm2711-legacy.config +++ b/config/kernel/linux-bcm2711-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-d1-edge.config b/config/kernel/linux-d1-edge.config index 3484186fe..3058b3317 100644 --- a/config/kernel/linux-d1-edge.config +++ b/config/kernel/linux-d1-edge.config @@ -2404,6 +2404,7 @@ CONFIG_ATH10K_USB=m CONFIG_ATH10K_DEBUGFS=y # CONFIG_ATH10K_SPECTRAL is not set # CONFIG_ATH10K_TRACING is not set +CONFIG_ATH12K=m CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set # CONFIG_WLAN_VENDOR_ATMEL is not set diff --git a/config/kernel/linux-filogic-current.config b/config/kernel/linux-filogic-current.config index e260307e2..0738a1609 100644 --- a/config/kernel/linux-filogic-current.config +++ b/config/kernel/linux-filogic-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -737,7 +738,6 @@ CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY_DMESG_RESTRICT=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y -CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" CONFIG_INIT_STACK_NONE=y CONFIG_LIST_HARDENED=y CONFIG_CRYPTO_USER=m diff --git a/config/kernel/linux-filogic-edge.config b/config/kernel/linux-filogic-edge.config index 7c75e53a9..7f29cb2db 100644 --- a/config/kernel/linux-filogic-edge.config +++ b/config/kernel/linux-filogic-edge.config @@ -1,7 +1,6 @@ # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -# CONFIG_CROSS_MEMORY_ATTACH is not set CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y @@ -9,7 +8,6 @@ CONFIG_BPF_JIT=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y -# CONFIG_CPU_ISOLATION is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -19,28 +17,30 @@ CONFIG_CGROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_PIDS=y -CONFIG_CGROUP_RDMA=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y CONFIG_NAMESPACES=y -# CONFIG_TIME_NS is not set CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y -# CONFIG_INITRAMFS_PRESERVE_MTIME is not set CONFIG_EXPERT=y -# CONFIG_RSEQ is not set -# CONFIG_CACHESTAT_SYSCALL is not set +CONFIG_PERF_EVENTS=y CONFIG_ARCH_MEDIATEK=y # CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_AMPERE_ERRATUM_AC04_CPU_23 is not set # CONFIG_ARM64_ERRATUM_826319 is not set # CONFIG_ARM64_ERRATUM_827319 is not set # CONFIG_ARM64_ERRATUM_824069 is not set # CONFIG_ARM64_ERRATUM_819472 is not set # CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_1742098 is not set +# CONFIG_ARM64_ERRATUM_845719 is not set +# CONFIG_ARM64_ERRATUM_843419 is not set # CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set # CONFIG_ARM64_ERRATUM_1165522 is not set # CONFIG_ARM64_ERRATUM_1319367 is not set # CONFIG_ARM64_ERRATUM_1530923 is not set @@ -68,17 +68,19 @@ CONFIG_ARCH_MEDIATEK=y # CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set # CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set # CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3568002 is not set # CONFIG_ROCKCHIP_ERRATUM_3588001 is not set # CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set CONFIG_ARM64_VA_BITS_48=y CONFIG_SCHED_MC=y CONFIG_NR_CPUS=4 CONFIG_HZ_100=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_COMPAT=y # CONFIG_ARM64_HW_AFDBM is not set # CONFIG_ARM64_USE_LSE_ATOMICS is not set # CONFIG_ARM64_RAS_EXTN is not set +# CONFIG_ARM64_CNP is not set # CONFIG_ARM64_PTR_AUTH is not set # CONFIG_ARM64_AMU_EXTN is not set # CONFIG_ARM64_TLB_RANGE is not set @@ -87,68 +89,76 @@ CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_MTE is not set # CONFIG_ARM64_EPAN is not set # CONFIG_ARM64_POE is not set -# CONFIG_ARM64_SVE is not set -# CONFIG_RELOCATABLE is not set -# CONFIG_SUSPEND is not set -CONFIG_PM=y +CONFIG_RANDOMIZE_BASE=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_ENERGY_MODEL=y CONFIG_CPU_IDLE=y CONFIG_ARM_PSCI_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=m +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_VIRT=m CONFIG_ARM_MEDIATEK_CPUFREQ=y -# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set -CONFIG_JUMP_LABEL=y -# CONFIG_STACKPROTECTOR_STRONG is not set +CONFIG_ARM_MEDIATEK_CPUFREQ_HW=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_COMPRESS=y CONFIG_MODULE_COMPRESS_ZSTD=y CONFIG_MODULE_DECOMPRESS=y -# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set CONFIG_BLK_DEV_THROTTLING=y -# CONFIG_BLK_DEBUG_FS is not set CONFIG_PARTITION_ADVANCED=y -# CONFIG_MQ_IOSCHED_DEADLINE is not set -# CONFIG_MQ_IOSCHED_KYBER is not set -# CONFIG_IOSCHED_BFQ is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_FREELIST_HARDENED=y -# CONFIG_COMPAT_BRK is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_SECRETMEM is not set -CONFIG_LRU_GEN=y -CONFIG_LRU_GEN_ENABLED=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +CONFIG_TLS_TOE=y CONFIG_XFRM_USER=m CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m CONFIG_INET_ESPINTCP=y -# CONFIG_INET_DIAG is not set +CONFIG_INET_IPCOMP=m +CONFIG_INET_UDP_DIAG=m CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_IPV6_SIT is not set +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y @@ -159,16 +169,18 @@ CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m CONFIG_NETFILTER_NETLINK_HOOK=m -CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y -# CONFIG_NF_CT_PROTO_DCCP is not set -# CONFIG_NF_CT_PROTO_SCTP is not set -# CONFIG_NF_CT_PROTO_UDPLITE is not set +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m @@ -208,6 +220,7 @@ CONFIG_NFT_REJECT_NETDEV=m CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m CONFIG_NF_FLOW_TABLE_PROCFS=y +CONFIG_NETFILTER_XTABLES_COMPAT=y CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -289,6 +302,7 @@ CONFIG_IP_VS=m CONFIG_IP_VS_PROTO_TCP=y CONFIG_IP_VS_PROTO_UDP=y CONFIG_IP_VS_RR=m +CONFIG_IP_VS_MH_TAB_INDEX=10 CONFIG_IP_VS_NFCT=y CONFIG_IP_NF_IPTABLES_LEGACY=y CONFIG_NFT_DUP_IPV4=m @@ -341,17 +355,26 @@ CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_IP_SCTP=m CONFIG_RDS=m CONFIG_RDS_TCP=m +CONFIG_RDS_DEBUG=y CONFIG_TIPC=m CONFIG_L2TP=m CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_NET_DSA=y CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_FQ_CODEL=y +CONFIG_NET_SCH_CAKE=m CONFIG_NET_SCH_INGRESS=m CONFIG_NET_SCH_DEFAULT=y CONFIG_DEFAULT_FQ_CODEL=y @@ -360,7 +383,6 @@ CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=m CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_FLOWER=m @@ -369,12 +391,24 @@ CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_U32=m CONFIG_NET_EMATCH_IPT=m CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_SAMPLE=y +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m CONFIG_NET_ACT_VLAN=m CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m +CONFIG_NET_ACT_SKBMOD=m +CONFIG_NET_ACT_TUNNEL_KEY=m +CONFIG_NET_ACT_CT=m +CONFIG_NETLINK_DIAG=y CONFIG_CGROUP_NET_PRIO=y CONFIG_BT=m CONFIG_CFG80211=m @@ -382,24 +416,26 @@ CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -# CONFIG_LWTUNNEL_BPF is not set +CONFIG_RFKILL=m CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y CONFIG_PCIEASPM_PERFORMANCE=y CONFIG_PCI_DEBUG=y -# CONFIG_VGA_ARB is not set +CONFIG_PCIE_MEDIATEK=y CONFIG_PCIE_MEDIATEK_GEN3=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DEVTMPFS_SAFE=y CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -# CONFIG_ARM_SMCCC_SOC_ID is not set CONFIG_MTD=y CONFIG_MTD_PARSER_TRX=y CONFIG_MTD_BLOCK=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y @@ -409,13 +445,11 @@ CONFIG_MTD_NAND_MTK=y CONFIG_MTD_SPI_NAND=y CONFIG_MTD_NAND_ECC_MEDIATEK=y CONFIG_MTD_SPI_NOR=y -# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set CONFIG_MTD_UBI=y CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_NVMEM=y CONFIG_OF_OVERLAY=y -CONFIG_ZRAM=y +CONFIG_ZRAM=m CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y @@ -429,39 +463,52 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_NVME=y -CONFIG_EEPROM_AT24=m +CONFIG_NVME_HWMON=y +CONFIG_SRAM=y +CONFIG_EEPROM_AT24=y +CONFIG_SCSI=y CONFIG_BLK_DEV_SD=m -# CONFIG_BLK_DEV_BSG is not set +CONFIG_CHR_DEV_ST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPI3MR=m CONFIG_ATA=m -# CONFIG_ATA_VERBOSE_ERROR is not set -# CONFIG_ATA_FORCE is not set CONFIG_NETDEVICES=y CONFIG_BONDING=m CONFIG_DUMMY=m CONFIG_WIREGUARD=m +CONFIG_OVPN=m CONFIG_IFB=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_IPVTAP=m CONFIG_VXLAN=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_TUN=m CONFIG_VETH=m CONFIG_NETKIT=y +CONFIG_MHI_NET=m CONFIG_NET_DSA_MT7530=y -# CONFIG_NET_VENDOR_ASIX is not set -# CONFIG_NET_VENDOR_ENGLEDER is not set -# CONFIG_NET_VENDOR_FUNGIBLE is not set -# CONFIG_NET_VENDOR_LITEX is not set CONFIG_NET_VENDOR_MEDIATEK=y CONFIG_NET_MEDIATEK_SOC=y -# CONFIG_NET_VENDOR_MICROSOFT is not set -# CONFIG_NET_VENDOR_VERTEXCOM is not set -# CONFIG_NET_VENDOR_WANGXUN is not set +CONFIG_LED_TRIGGER_PHY=y CONFIG_SFP=m -CONFIG_AQUANTIA_PHY=m -CONFIG_ICPLUS_PHY=m +CONFIG_AIR_EN8811H_PHY=m +CONFIG_AQUANTIA_PHY=y +CONFIG_ICPLUS_PHY=y CONFIG_MARVELL_PHY=m CONFIG_MARVELL_10G_PHY=m CONFIG_MARVELL_88Q2XXX_PHY=m @@ -470,6 +517,7 @@ CONFIG_MAXLINEAR_GPHY=m CONFIG_MEDIATEK_2P5GE_PHY=m CONFIG_REALTEK_PHY=m CONFIG_REALTEK_PHY_HWMON=y +CONFIG_PCS_AIROHA=m CONFIG_PCS_MTK_USXGMII=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -480,26 +528,33 @@ CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=m CONFIG_PPPOL2TP=m CONFIG_PPP_ASYNC=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_NET_QMI_WWAN=m # CONFIG_WLAN_VENDOR_ADMTEK is not set -# CONFIG_WLAN_VENDOR_ATH is not set +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_AHB=y +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m -# CONFIG_WLAN_VENDOR_BROADCOM is not set -# CONFIG_WLAN_VENDOR_INTEL is not set -# CONFIG_WLAN_VENDOR_INTERSIL is not set -# CONFIG_WLAN_VENDOR_MARVELL is not set CONFIG_MT7601U=m CONFIG_MT76x0U=m CONFIG_MT76x2U=m CONFIG_MT7663U=m CONFIG_MT7915E=m +CONFIG_MT798X_WMAC=y CONFIG_MT7921E=m CONFIG_MT7921U=m CONFIG_MT7996E=m CONFIG_MT7925E=m CONFIG_MT7925U=m -# CONFIG_WLAN_VENDOR_MICROCHIP is not set -# CONFIG_WLAN_VENDOR_PURELIFI is not set -# CONFIG_WLAN_VENDOR_RALINK is not set CONFIG_RTL8XXXU=m CONFIG_RTW88=m CONFIG_RTW88_8822BE=m @@ -514,81 +569,55 @@ CONFIG_RTW89_8852AE=m CONFIG_RTW89_8852BE=m CONFIG_RTW89_8852CE=m CONFIG_RTW89_8922AE=m -# CONFIG_WLAN_VENDOR_RSI is not set -# CONFIG_WLAN_VENDOR_SILABS is not set -# CONFIG_WLAN_VENDOR_ST is not set -# CONFIG_WLAN_VENDOR_TI is not set CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m -# CONFIG_WLAN_VENDOR_ZYDAS is not set -# CONFIG_WLAN_VENDOR_QUANTENNA is not set +CONFIG_WWAN=m +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +CONFIG_MTK_T7XX=m CONFIG_ISDN=y -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_LEGACY_TIOCSTI is not set +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_MISC=y CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -# CONFIG_SERIAL_8250_EXAR is not set CONFIG_SERIAL_8250_NR_UARTS=3 CONFIG_SERIAL_8250_RUNTIME_UARTS=3 CONFIG_SERIAL_8250_MT6577=y -# CONFIG_SERIAL_8250_PERICOM is not set CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_DEV_BUS=y CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set -# CONFIG_DEVMEM is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=m CONFIG_I2C_MUX_PCA954x=m -# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_GPIO=y CONFIG_I2C_MT65XX=y CONFIG_SPI=y CONFIG_SPI_MT65XX=y +CONFIG_SPI_MTK_NOR=y CONFIG_SPI_MTK_SNFI=y -CONFIG_PPS=m -# CONFIG_PTP_1588_CLOCK is not set -# CONFIG_PINCTRL_MT2712 is not set -# CONFIG_PINCTRL_MT6765 is not set -# CONFIG_PINCTRL_MT6779 is not set -# CONFIG_PINCTRL_MT6795 is not set -# CONFIG_PINCTRL_MT6797 is not set -# CONFIG_PINCTRL_MT7622 is not set -# CONFIG_PINCTRL_MT8167 is not set -# CONFIG_PINCTRL_MT8173 is not set -# CONFIG_PINCTRL_MT8183 is not set -# CONFIG_PINCTRL_MT8186 is not set -# CONFIG_PINCTRL_MT8188 is not set -# CONFIG_PINCTRL_MT8192 is not set -# CONFIG_PINCTRL_MT8195 is not set -# CONFIG_PINCTRL_MT8365 is not set -# CONFIG_PINCTRL_MT8516 is not set +CONFIG_PPS_CLIENT_KTIMER=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m +CONFIG_PPS_GENERATOR=m +CONFIG_PINCTRL_SINGLE=y CONFIG_GPIO_SYSFS=y -# CONFIG_GPIO_CDEV_V1 is not set +CONFIG_W1=m CONFIG_POWER_RESET_SYSCON=y -# CONFIG_POWER_SUPPLY_HWMON is not set CONFIG_SENSORS_PWM_FAN=m CONFIG_THERMAL=y CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_CPU_THERMAL=y -# CONFIG_CPU_FREQ_THERMAL is not set +CONFIG_THERMAL_EMULATION=y CONFIG_MTK_THERMAL=y CONFIG_MTK_SOC_THERMAL=y CONFIG_MTK_LVTS_THERMAL=y -CONFIG_MTK_LVTS_THERMAL_DEBUGFS=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_SYSFS=y CONFIG_WATCHDOG_PRETIMEOUT_GOV=y -# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set -CONFIG_GPIO_WATCHDOG=y -CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MT6380=y CONFIG_REGULATOR_RT5190A=y @@ -596,8 +625,11 @@ CONFIG_SOUND=m CONFIG_SND=m CONFIG_USB=m CONFIG_USB_XHCI_HCD=m -CONFIG_USB_XHCI_PLATFORM=m CONFIG_USB_XHCI_MTK=m +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_ACM=m CONFIG_USB_STORAGE=m CONFIG_USB_STORAGE_DATAFAB=m CONFIG_USB_STORAGE_FREECOM=m @@ -610,6 +642,12 @@ CONFIG_USB_STORAGE_ALAUDA=m CONFIG_USB_STORAGE_KARMA=m CONFIG_USB_STORAGE_CYPRESS_ATACB=m CONFIG_USB_UAS=m +CONFIG_USB_CDNS_SUPPORT=m +CONFIG_USB_CDNS3=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_OPTION=m CONFIG_MMC=y CONFIG_MMC_MTK=y CONFIG_NEW_LEDS=y @@ -617,107 +655,104 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_MULTICOLOR=y CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y CONFIG_LEDS_GPIO=m -CONFIG_LEDS_PWM=y +CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_NETDEV=y -CONFIG_LEDS_TRIGGER_PATTERN=y CONFIG_RTC_CLASS=y -# CONFIG_RTC_NVMEM is not set -CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_MT7622=y CONFIG_DMADEVICES=y CONFIG_MTK_HSDMA=y CONFIG_DMATEST=y CONFIG_STAGING=y -# CONFIG_SURFACE_PLATFORMS is not set -# CONFIG_COMMON_CLK_MT2712 is not set -# CONFIG_COMMON_CLK_MT6765 is not set -# CONFIG_COMMON_CLK_MT6779 is not set -# CONFIG_COMMON_CLK_MT6795 is not set -# CONFIG_COMMON_CLK_MT6797 is not set -# CONFIG_COMMON_CLK_MT7622 is not set -# CONFIG_COMMON_CLK_MT8167 is not set -# CONFIG_COMMON_CLK_MT8173 is not set -# CONFIG_COMMON_CLK_MT8183 is not set -# CONFIG_COMMON_CLK_MT8186 is not set -# CONFIG_COMMON_CLK_MT8188 is not set -# CONFIG_COMMON_CLK_MT8192 is not set -# CONFIG_COMMON_CLK_MT8195 is not set -# CONFIG_COMMON_CLK_MT8365 is not set -# CONFIG_COMMON_CLK_MT8516 is not set -# CONFIG_FSL_ERRATUM_A008585 is not set -# CONFIG_HISILICON_ERRATUM_161010101 is not set -# CONFIG_IOMMU_SUPPORT is not set +CONFIG_COMMON_CLK_MT7622_ETHSYS=y +CONFIG_COMMON_CLK_MT7622_HIFSYS=y +CONFIG_COMMON_CLK_MT7622_AUDSYS=y CONFIG_MTK_PMIC_WRAP=y -# CONFIG_MTK_MMSYS is not set -# CONFIG_MTK_SOCINFO is not set CONFIG_PM_DEVFREQ=y CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=y -CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_IIO=y CONFIG_PWM=y CONFIG_PWM_MEDIATEK=y -# CONFIG_MST_IRQ is not set CONFIG_RESET_TI_SYSCON=y CONFIG_PHY_MTK_XFI_TPHY=y CONFIG_PHY_MTK_TPHY=y CONFIG_PHY_MTK_UFS=y CONFIG_PHY_MTK_XSPHY=y +CONFIG_LIBNVDIMM=m CONFIG_NVMEM_MTK_EFUSE=y +CONFIG_HTE=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_F2FS_FS=m CONFIG_F2FS_FS_SECURITY=y -# CONFIG_F2FS_IOSTAT is not set -# CONFIG_DNOTIFY is not set CONFIG_FANOTIFY=y +CONFIG_QUOTA=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m CONFIG_AUTOFS_FS=y CONFIG_FUSE_FS=m CONFIG_CUSE=m -CONFIG_VIRTIO_FS=m -CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS_XINO_AUTO=y CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y CONFIG_UDF_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_EXFAT_FS=m -CONFIG_NTFS3_FS_POSIX_ACL=y CONFIG_NTFS_FS=m -# CONFIG_PROC_PAGE_MONITOR is not set CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y CONFIG_CONFIGFS_FS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_SUMMARY=y CONFIG_JFFS2_FS_XATTR=y CONFIG_JFFS2_COMPRESSION_OPTIONS=y -# CONFIG_JFFS2_ZLIB is not set -CONFIG_UBIFS_FS=y -CONFIG_SQUASHFS=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU=y -# CONFIG_SQUASHFS_ZLIB is not set CONFIG_SQUASHFS_XZ=y CONFIG_SQUASHFS_EMBEDDED=y CONFIG_PSTORE=y +# CONFIG_PSTORE_COMPRESS is not set CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_RAM=y CONFIG_EROFS_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_NFS_USE_LEGACY_DNS=y CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_NFSD_SCSILAYOUT=y +CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_CIFS=m +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y CONFIG_SMB_SERVER=m CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_852=y CONFIG_NLS_CODEPAGE_936=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_15=y CONFIG_UNICODE=m CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=y @@ -727,46 +762,87 @@ CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" CONFIG_INIT_STACK_NONE=y CONFIG_FORTIFY_SOURCE=y CONFIG_HARDENED_USERCOPY=y -CONFIG_LIST_HARDENED=y CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_PCRYPT=y CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_KRB5ENC=m +CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECRDSA=m +CONFIG_CRYPTO_CURVE25519=m +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SM4_GENERIC=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_HCTR2=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_ESSIV=m +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_GHASH_ARM64_CE=m CONFIG_CRYPTO_SHA1_ARM64_CE=m -CONFIG_CRYPTO_SHA512_ARM64=m -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_SM4_ARM64_CE_CCM=y -CONFIG_CRYPTO_SM4_ARM64_CE_GCM=y -CONFIG_CRYPTO_DEV_SAFEXCEL=m +CONFIG_CRYPTO_SHA512_ARM64_CE=m +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_NEON=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64=m +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_SM4_ARM64_CE=m +CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=m +CONFIG_CRYPTO_SM4_ARM64_CE_CCM=m +CONFIG_CRYPTO_SM4_ARM64_CE_GCM=m # CONFIG_XZ_DEC_X86 is not set # CONFIG_XZ_DEC_POWERPC is not set -# CONFIG_XZ_DEC_ARM is not set -# CONFIG_XZ_DEC_ARMTHUMB is not set -# CONFIG_XZ_DEC_ARM64 is not set # CONFIG_XZ_DEC_SPARC is not set # CONFIG_XZ_DEC_RISCV is not set CONFIG_PRINTK_TIME=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO_DWARF5=y -CONFIG_DEBUG_INFO_REDUCED=y +CONFIG_DEBUG_INFO_BTF=y +CONFIG_FRAME_WARN=1024 CONFIG_STRIP_ASM_SYMS=y -# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y -# CONFIG_MAGIC_SYSRQ_SERIAL is not set CONFIG_DEBUG_FS=y -# CONFIG_SLUB_DEBUG is not set -CONFIG_SCHED_STACK_END_CHECK=y CONFIG_PANIC_ON_OOPS=y -CONFIG_PANIC_TIMEOUT=1 +CONFIG_PANIC_TIMEOUT=10 CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_TRACE is not set -# CONFIG_FTRACE is not set +CONFIG_FTRACE_SYSCALLS=y +# CONFIG_STRICT_DEVMEM is not set diff --git a/config/kernel/linux-genio-collabora.config b/config/kernel/linux-genio-collabora.config index 086ba6059..49f94851e 100644 --- a/config/kernel/linux-genio-collabora.config +++ b/config/kernel/linux-genio-collabora.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.14 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="localhost" CONFIG_SYSVIPC=y @@ -82,8 +83,6 @@ CONFIG_ARM64_ERRATUM_1542419=y # CONFIG_ARM64_ERRATUM_2077057 is not set CONFIG_ARM64_ERRATUM_2441009=y CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y CONFIG_NR_CPUS=8 CONFIG_NUMA=y CONFIG_HZ_1000=y @@ -596,7 +595,11 @@ CONFIG_MTD_NAND_ECC_MEDIATEK=y CONFIG_MTD_SPI_NOR=y CONFIG_OF_OVERLAY=y CONFIG_ZRAM=y +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y @@ -1578,8 +1581,6 @@ CONFIG_RPMSG_QCOM_GLINK_SMEM=m CONFIG_RPMSG_QCOM_SMD=y CONFIG_SOUNDWIRE=m CONFIG_SOUNDWIRE_QCOM=m -# CONFIG_APPLE_MAILBOX is not set -# CONFIG_APPLE_SART is not set CONFIG_FSL_RCPM=y CONFIG_MTK_CMDQ=y CONFIG_MTK_DEVAPC=m @@ -1617,7 +1618,6 @@ CONFIG_OWL_PM_DOMAINS=y CONFIG_QCOM_CPR=y CONFIG_QCOM_RPMHPD=y CONFIG_QCOM_RPMPD=y -CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y @@ -1721,7 +1721,6 @@ CONFIG_OF_FPGA_REGION=m CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_MUX_MMIO=y -CONFIG_SLIM_QCOM_CTRL=m CONFIG_SLIM_QCOM_NGD_CTRL=m CONFIG_INTERCONNECT_MTK=y CONFIG_INTERCONNECT_QCOM=y @@ -1735,7 +1734,7 @@ CONFIG_INTERCONNECT_QCOM_SM8250=m CONFIG_INTERCONNECT_QCOM_SM8350=m CONFIG_HTE=y CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y +CONFIG_EXT4_FS=m CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_BTRFS_FS=m @@ -1815,7 +1814,6 @@ CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_ARIA=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_ARC4=y diff --git a/config/kernel/linux-imx6-current.config b/config/kernel/linux-imx6-current.config index 92be004eb..57fcef06c 100644 --- a/config/kernel/linux-imx6-current.config +++ b/config/kernel/linux-imx6-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_LZ4=y CONFIG_DEFAULT_INIT="3" diff --git a/config/kernel/linux-imx6-edge.config b/config/kernel/linux-imx6-edge.config index be51d4104..241661bb7 100644 --- a/config/kernel/linux-imx6-edge.config +++ b/config/kernel/linux-imx6-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.15 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_LZ4=y CONFIG_DEFAULT_INIT="3" @@ -813,6 +814,12 @@ CONFIG_MTD_UBI=m CONFIG_OF_OVERLAY=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m @@ -1347,6 +1354,7 @@ CONFIG_WCN36XX=m CONFIG_ATH11K=m CONFIG_ATH11K_AHB=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set CONFIG_B43=m CONFIG_B43_SDIO=y diff --git a/config/kernel/linux-k3-beagle-edge.config b/config/kernel/linux-k3-beagle-edge.config index 6a156e103..95176fc8c 100644 --- a/config/kernel/linux-k3-beagle-edge.config +++ b/config/kernel/linux-k3-beagle-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -118,14 +119,14 @@ CONFIG_IPV6=m CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m CONFIG_NETFILTER_NETLINK_HOOK=m -CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_TABLES=y +CONFIG_NF_TABLES=m CONFIG_NF_TABLES_INET=y CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m @@ -170,6 +171,7 @@ CONFIG_NETFILTER_XT_TARGET_NOTRACK=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -233,8 +235,8 @@ CONFIG_IP_VS_NFCT=y CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m @@ -242,7 +244,7 @@ CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_SECURITY=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -327,6 +329,9 @@ CONFIG_PCI_IOV=y CONFIG_PCI_PASID=y CONFIG_HOTPLUG_PCI=y CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_J721E_HOST=y +CONFIG_PCIE_DW_PLAT_HOST=y +CONFIG_PCI_KEYSTONE_HOST=y CONFIG_PCI_ENDPOINT=y CONFIG_PCI_ENDPOINT_CONFIGFS=y CONFIG_PCI_EPF_TEST=m @@ -358,8 +363,13 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_UBI=m CONFIG_MTD_HYPERBUS=m CONFIG_HBMC_AM654=m -CONFIG_OF_OVERLAY=y -CONFIG_ZRAM=m +CONFIG_ZRAM=y +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -441,6 +451,9 @@ CONFIG_R8169=m # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_TI_K3_AM65_CPSW_NUSS=y +CONFIG_TI_K3_AM65_CPSW_SWITCHDEV=y +CONFIG_TI_K3_AM65_CPTS=y +CONFIG_TI_AM65_CPSW_QOS=y CONFIG_TI_ICSSG_PRUETH=m # CONFIG_NET_VENDOR_VERTEXCOM is not set # CONFIG_NET_VENDOR_VIA is not set @@ -494,7 +507,6 @@ CONFIG_IWLMVM=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_PCIE=m -CONFIG_MT7601U=m CONFIG_MT7921E=m CONFIG_RSI_91X=m CONFIG_WL18XX=m @@ -503,7 +515,6 @@ CONFIG_WWAN=m CONFIG_MHI_WWAN_CTRL=m CONFIG_MHI_WWAN_MBIM=m CONFIG_INPUT_MATRIXKMAP=y -CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_ADC=m CONFIG_KEYBOARD_GPIO=y @@ -515,6 +526,7 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=m CONFIG_TOUCHSCREEN_GOODIX=m CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m +CONFIG_TOUCHSCREEN_ILI210X=m CONFIG_TOUCHSCREEN_ELAN=m CONFIG_TOUCHSCREEN_EDT_FT5X06=m CONFIG_INPUT_MISC=y @@ -528,7 +540,8 @@ CONFIG_SERIO_AMBAKMI=y CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=12 +CONFIG_SERIAL_8250_RUNTIME_UARTS=12 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_OMAP=y @@ -551,9 +564,7 @@ CONFIG_TCG_TIS_SPI=m CONFIG_TCG_TIS_SPI_CR50=y CONFIG_TCG_TIS_I2C_CR50=m CONFIG_TCG_TIS_I2C_INFINEON=y -CONFIG_I2C=y CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_DESIGNWARE_CORE=y # CONFIG_I2C_DESIGNWARE_PLATFORM is not set @@ -566,7 +577,6 @@ CONFIG_SPI_OMAP24XX=m CONFIG_SPI_SPIDEV=m CONFIG_PINCTRL=y CONFIG_PINCTRL_DA9062=m -CONFIG_PINCTRL_MCP23S08=m CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_SINGLE=y CONFIG_GPIO_SYSFS=y @@ -625,7 +635,7 @@ CONFIG_MFD_RK8XX_SPI=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LP873X=m CONFIG_MFD_TPS65219=y -CONFIG_MFD_TPS6594_I2C=m +CONFIG_MFD_TPS6594_I2C=y CONFIG_MFD_WM8994=m CONFIG_MFD_ROHM_BD718XX=y CONFIG_REGULATOR=y @@ -653,6 +663,7 @@ CONFIG_REGULATOR_PF8X00=y CONFIG_REGULATOR_PFUZE100=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RAA215300=y +CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_TPS65132=m CONFIG_REGULATOR_TPS65219=y @@ -672,18 +683,29 @@ CONFIG_VIDEO_IMX219=m CONFIG_VIDEO_IMX412=m CONFIG_VIDEO_OV5640=m CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_DS90UB953=m +CONFIG_VIDEO_DS90UB960=m CONFIG_AUXDISPLAY=y -CONFIG_SEG_LED_GPIO=m -CONFIG_DRM=m +CONFIG_HD44780=m +CONFIG_LCD2S=m +CONFIG_IMG_ASCII_LCD=m +CONFIG_HT16K33=m +CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_I2C_CH7006=m CONFIG_DRM_I2C_SIL164=m -CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_I2C_NXP_TDA998X=y +CONFIG_DRM_VGEM=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_ILITEK_ILI9881C=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_OSD_OSD101T2587_53TS=y +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m @@ -691,31 +713,46 @@ CONFIG_DRM_PANEL_EDP=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m -CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_DISPLAY_CONNECTOR=y CONFIG_DRM_LONTIUM_LT8912B=m CONFIG_DRM_LONTIUM_LT9611=m CONFIG_DRM_LONTIUM_LT9611UXC=m -CONFIG_DRM_ITE_IT66121=m +CONFIG_DRM_ITE_IT66121=y +CONFIG_DRM_LVDS_CODEC=y CONFIG_DRM_NWL_MIPI_DSI=m CONFIG_DRM_PARADE_PS8640=m CONFIG_DRM_SAMSUNG_DSIM=m -CONFIG_DRM_SII902X=m +CONFIG_DRM_SII902X=y CONFIG_DRM_SIMPLE_BRIDGE=m CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358762=m CONFIG_DRM_TOSHIBA_TC358767=m CONFIG_DRM_TOSHIBA_TC358768=m -CONFIG_DRM_TI_TFP410=m +CONFIG_DRM_TI_TFP410=y CONFIG_DRM_TI_SN65DSI83=m CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_TI_TPD12S015=y CONFIG_DRM_ANALOGIX_ANX7625=m -CONFIG_DRM_CDNS_MHDP8546=m +CONFIG_DRM_CDNS_DSI=y +CONFIG_DRM_CDNS_MHDP8546=y +CONFIG_DRM_SIMPLEDRM=m +CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9163=m +CONFIG_TINYDRM_ILI9225=m +CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m CONFIG_DRM_PANTHOR=m CONFIG_DRM_TIDSS=m -CONFIG_DRM_POWERVR=m CONFIG_FB=y +CONFIG_FB_SIMPLE=m CONFIG_FB_MODE_HELPERS=y -CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_BACKLIGHT_PWM=m +CONFIG_FB_TILEBLITTING=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_LP855X=m CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -725,6 +762,7 @@ CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_ALOOP=m # CONFIG_SND_SPI is not set +CONFIG_SND_USB_AUDIO=m CONFIG_SND_SOC=y CONFIG_SND_SOC_SOF_TOPLEVEL=y CONFIG_SND_SOC_SOF_OF=y @@ -802,6 +840,7 @@ CONFIG_USB_ONBOARD_DEV=m CONFIG_NOP_USB_XCEIV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=32 CONFIG_USB_SNP_UDC_PLAT=y CONFIG_USB_BDC_UDC=y CONFIG_USB_CONFIGFS=m @@ -815,9 +854,14 @@ CONFIG_USB_CONFIGFS_RNDIS=y CONFIG_USB_CONFIGFS_EEM=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_ZERO=m CONFIG_USB_ETH=m +CONFIG_USB_G_NCM=m CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_MULTI_CDC=y CONFIG_TYPEC=m CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_TCPCI=m @@ -844,7 +888,6 @@ CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_CDNS_PLATFORM=m CONFIG_SCSI_UFS_TI_J721E=m -CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_MULTICOLOR=m CONFIG_LEDS_LM3692X=m @@ -852,7 +895,6 @@ CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y -CONFIG_LEDS_PWM_MULTICOLOR=m CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_DISK=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y @@ -885,7 +927,11 @@ CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_EDMA=m CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y CONFIG_TI_K3_UDMA_GLUE_LAYER=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y CONFIG_VFIO=y CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y @@ -902,6 +948,7 @@ CONFIG_COMMON_CLK_RS9_PCIE=y CONFIG_COMMON_CLK_VC3=y CONFIG_TI_SCI_CLK=y CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_OMAP=m # CONFIG_FSL_ERRATUM_A008585 is not set # CONFIG_HISILICON_ERRATUM_161010101 is not set CONFIG_OMAP2PLUS_MBOX=m @@ -927,9 +974,8 @@ CONFIG_DEVFREQ_GOV_PASSIVE=m CONFIG_EXTCON_PTN5150=m CONFIG_EXTCON_USB_GPIO=y CONFIG_MEMORY=y +CONFIG_OMAP_GPMC=y CONFIG_IIO=y -CONFIG_MMA8452=m -CONFIG_AD7291=m CONFIG_MAX9611=m CONFIG_TI_ADS1015=m CONFIG_TI_AM335X_ADC=m @@ -940,20 +986,21 @@ CONFIG_IIO_ST_MAGN_3AXIS=m CONFIG_MPL3115=m CONFIG_PWM=y CONFIG_PWM_ADP5585=m -CONFIG_PWM_GPIO=m +CONFIG_PWM_OMAP_DMTIMER=m CONFIG_PWM_TIECAP=m CONFIG_PWM_TIEHRPWM=m CONFIG_RESET_CONTROLLER=y CONFIG_RESET_GPIO=m CONFIG_RESET_TI_SCI=y CONFIG_PHY_CAN_TRANSCEIVER=m -CONFIG_PHY_CADENCE_TORRENT=m +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_CADENCE_DPHY=m CONFIG_PHY_CADENCE_DPHY_RX=m -CONFIG_PHY_CADENCE_SIERRA=m +CONFIG_PHY_CADENCE_SIERRA=y CONFIG_PHY_CADENCE_SALVO=m CONFIG_PHY_QCOM_USB_HS=m -CONFIG_PHY_AM654_SERDES=m -CONFIG_PHY_J721E_WIZ=m +CONFIG_PHY_AM654_SERDES=y +CONFIG_PHY_J721E_WIZ=y CONFIG_OMAP_USB2=m CONFIG_ARM_CCI_PMU=m CONFIG_ARM_CCN=m @@ -974,14 +1021,15 @@ CONFIG_OF_FPGA_REGION=m CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_MUX_GPIO=m -CONFIG_MUX_MMIO=y CONFIG_INTERCONNECT=y CONFIG_COUNTER=m +CONFIG_TI_ECAP_CAPTURE=m +CONFIG_TI_EQEP=m CONFIG_HTE=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y @@ -1010,12 +1058,14 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_APPARMOR=y CONFIG_CRYPTO_USER=y CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRYPTO_GHASH_ARM64_CE=y @@ -1031,7 +1081,6 @@ CONFIG_CRYPTO_DEV_CCREE=m CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m CONFIG_CRYPTO_DEV_SA2UL=m CONFIG_INDIRECT_PIO=y -CONFIG_CRC_CCITT=m CONFIG_DMA_RESTRICTED_POOL=y CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=32 diff --git a/config/kernel/linux-k3-beagle-current-rt.config b/config/kernel/linux-k3-beagle-vendor-rt.config similarity index 87% rename from config/kernel/linux-k3-beagle-current-rt.config rename to config/kernel/linux-k3-beagle-vendor-rt.config index 877fe8821..35c102ef7 100644 --- a/config/kernel/linux-k3-beagle-current-rt.config +++ b/config/kernel/linux-k3-beagle-vendor-rt.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -116,11 +117,10 @@ CONFIG_INET_ESP=m CONFIG_IPV6=m CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_HOOK=m CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_LABELS=y CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_PPTP=m @@ -128,31 +128,111 @@ CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m CONFIG_NFT_XFRM=m CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m CONFIG_NFT_TPROXY=m CONFIG_NFT_SYNPROXY=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m CONFIG_NFT_REJECT_NETDEV=m -CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XTABLES_COMPAT=y +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_VS=m CONFIG_IP_VS_PROTO_TCP=y CONFIG_IP_VS_PROTO_UDP=y CONFIG_IP_VS_RR=m CONFIG_IP_VS_NFCT=y +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=m @@ -163,14 +243,32 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_SECURITY=y +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_IP6_NF_SECURITY=m CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m CONFIG_BRIDGE=m CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_NET_DSA=m @@ -263,6 +361,12 @@ CONFIG_MTD_HYPERBUS=m CONFIG_HBMC_AM654=m CONFIG_OF_OVERLAY=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -787,6 +891,7 @@ CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_EDMA=m CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y CONFIG_TI_K3_UDMA_GLUE_LAYER=y CONFIG_VFIO=y CONFIG_VFIO_PCI=y @@ -919,7 +1024,6 @@ CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRYPTO_GHASH_ARM64_CE=y CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y diff --git a/config/kernel/linux-k3-beagle-current.config b/config/kernel/linux-k3-beagle-vendor.config similarity index 87% rename from config/kernel/linux-k3-beagle-current.config rename to config/kernel/linux-k3-beagle-vendor.config index 725adc788..bb464f625 100644 --- a/config/kernel/linux-k3-beagle-current.config +++ b/config/kernel/linux-k3-beagle-vendor.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -117,11 +118,10 @@ CONFIG_INET_ESP=m CONFIG_IPV6=m CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_HOOK=m CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_LABELS=y CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_PPTP=m @@ -129,31 +129,111 @@ CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m CONFIG_NFT_XFRM=m CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m CONFIG_NFT_TPROXY=m CONFIG_NFT_SYNPROXY=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m CONFIG_NFT_REJECT_NETDEV=m -CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XTABLES_COMPAT=y +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_VS=m CONFIG_IP_VS_PROTO_TCP=y CONFIG_IP_VS_PROTO_UDP=y CONFIG_IP_VS_RR=m CONFIG_IP_VS_NFCT=y +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=m @@ -164,14 +244,32 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_SECURITY=y +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_IP6_NF_SECURITY=m CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m CONFIG_BRIDGE=m CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_NET_DSA=m @@ -263,6 +361,12 @@ CONFIG_MTD_HYPERBUS=m CONFIG_HBMC_AM654=m CONFIG_OF_OVERLAY=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -788,6 +892,7 @@ CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_EDMA=m CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y CONFIG_TI_K3_UDMA_GLUE_LAYER=y CONFIG_VFIO=y CONFIG_VFIO_PCI=y @@ -920,7 +1025,6 @@ CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRYPTO_GHASH_ARM64_CE=y CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y diff --git a/config/kernel/linux-k3-edge.config b/config/kernel/linux-k3-edge.config index d2410d6a4..95176fc8c 100644 --- a/config/kernel/linux-k3-edge.config +++ b/config/kernel/linux-k3-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -363,6 +364,12 @@ CONFIG_MTD_UBI=m CONFIG_MTD_HYPERBUS=m CONFIG_HBMC_AM654=m CONFIG_ZRAM=y +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -920,6 +927,7 @@ CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_EDMA=m CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y CONFIG_TI_K3_UDMA_GLUE_LAYER=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y diff --git a/config/kernel/linux-k3-vendor-edge.config b/config/kernel/linux-k3-vendor-edge.config new file mode 100644 index 000000000..95176fc8c --- /dev/null +++ b/config/kernel/linux-k3-vendor-edge.config @@ -0,0 +1,1102 @@ +# Armbian defconfig generated with 6.12 +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +# CONFIG_CRASH_DUMP is not set +CONFIG_ARCH_K3=y +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1530923 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set +# CONFIG_ARM64_ERRATUM_1508412 is not set +# CONFIG_ARM64_ERRATUM_2051678 is not set +# CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set +# CONFIG_ARM64_ERRATUM_2054223 is not set +# CONFIG_ARM64_ERRATUM_2067961 is not set +# CONFIG_ARM64_ERRATUM_2457168 is not set +# CONFIG_ARM64_ERRATUM_2645198 is not set +# CONFIG_ARM64_ERRATUM_2966298 is not set +# CONFIG_ARM64_ERRATUM_3117295 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +# CONFIG_FUJITSU_ERRATUM_010001 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_PARAVIRT=y +CONFIG_COMPAT=y +# CONFIG_ARM64_SVE is not set +CONFIG_RANDOMIZE_BASE=y +CONFIG_HIBERNATION=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_ENERGY_MODEL=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_VIRTUALIZATION=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_ZSWAP=y +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_CMA=y +CONFIG_CMA_AREAS=20 +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_INET_ESP=m +CONFIG_IPV6=m +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_HOOK=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m +CONFIG_NETFILTER_XTABLES_COMPAT=y +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_NFCT=y +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_NONE=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_OCELOT=m +CONFIG_NET_DSA_TAG_OCELOT_8021Q=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_TAPRIO=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_GATE=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CAN=m +CONFIG_BT=m +CONFIG_BT_HIDP=m +# CONFIG_BT_LE is not set +CONFIG_BT_LEDS=y +# CONFIG_BT_DEBUGFS is not set +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_NXPUART=m +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_RFKILL=m +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_PAGE_POOL_STATS=y +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PASID=y +CONFIG_HOTPLUG_PCI=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_J721E_HOST=y +CONFIG_PCIE_DW_PLAT_HOST=y +CONFIG_PCI_KEYSTONE_HOST=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=m +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_IMX_SCMI_BBM_EXT=y +CONFIG_GOOGLE_FIRMWARE=y +CONFIG_GOOGLE_CBMEM=m +CONFIG_GOOGLE_COREBOOT_TABLE=m +CONFIG_EFI_CAPSULE_LOADER=y +CONFIG_GNSS=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_SST25L=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_UBI=m +CONFIG_MTD_HYPERBUS=m +CONFIG_HBMC_AM654=m +CONFIG_ZRAM=y +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y +CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_NVME=m +CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_UACCE=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_DWC=m +CONFIG_PATA_OF_PLATFORM=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=m +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_NETKIT=y +CONFIG_MHI_NET=m +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ASIX is not set +CONFIG_ATL1C=m +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CADENCE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_DAVICOM is not set +# CONFIG_NET_VENDOR_ENGLEDER is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FUNGIBLE is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_LITEX is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MICROSEMI is not set +# CONFIG_NET_VENDOR_MICROSOFT is not set +# CONFIG_NET_VENDOR_NI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +CONFIG_R8169=m +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +CONFIG_TI_K3_AM65_CPSW_NUSS=y +CONFIG_TI_K3_AM65_CPSW_SWITCHDEV=y +CONFIG_TI_K3_AM65_CPTS=y +CONFIG_TI_AM65_CPSW_QOS=y +CONFIG_TI_ICSSG_PRUETH=m +# CONFIG_NET_VENDOR_VERTEXCOM is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WANGXUN is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_AQUANTIA_PHY=y +CONFIG_BCM7XXX_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=y +CONFIG_MARVELL_88Q2XXX_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_DP83867_PHY=y +CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_MCP251XFD=m +CONFIG_MDIO_BCM_UNIMAC=y +CONFIG_MDIO_GPIO=y +CONFIG_MDIO_THUNDER=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_WCN36XX=m +CONFIG_ATH11K=m +CONFIG_ATH11K_AHB=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m +CONFIG_BRCMFMAC=m +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MT7921E=m +CONFIG_RSI_91X=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_WWAN=m +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +CONFIG_INPUT_MATRIXKMAP=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=m +CONFIG_KEYBOARD_IMX_BBM_SCMI=y +CONFIG_KEYBOARD_MTK_PMIC=m +CONFIG_MOUSE_ELAN_I2C=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m +CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_ELAN=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_INPUT_MISC=y +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_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=12 +CONFIG_SERIAL_8250_RUNTIME_UARTS=12 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_OMAP=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_FSL_LINFLEXUART=y +CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS=m +CONFIG_TCG_TIS_SPI=m +CONFIG_TCG_TIS_SPI_CR50=y +CONFIG_TCG_TIS_I2C_CR50=m +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +CONFIG_I2C_GPIO=m +CONFIG_I2C_OMAP=y +CONFIG_I2C_SLAVE=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_OMAP24XX=m +CONFIG_SPI_SPIDEV=m +CONFIG_PINCTRL=y +CONFIG_PINCTRL_DA9062=m +CONFIG_PINCTRL_RK805=m +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DAVINCI=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_SYSCON=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_ADP5585=m +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_MAX77620=y +CONFIG_GPIO_AGGREGATOR=m +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_NVMEM_REBOOT_MODE=m +CONFIG_POWER_SEQUENCING=m +CONFIG_POWER_SEQUENCING_QCOM_WCN=m +CONFIG_BATTERY_QCOM_BATTMGR=m +CONFIG_BATTERY_SBS=m +CONFIG_BATTERY_BQ27XXX=y +CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_MT6360=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_BQ25980=m +CONFIG_CHARGER_RK817=m +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_THERMAL=y +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_K3_THERMAL=m +CONFIG_GENERIC_ADC_THERMAL=m +CONFIG_WATCHDOG=y +CONFIG_K3_RTI_WATCHDOG=m +CONFIG_ARM_SMC_WATCHDOG=y +CONFIG_MFD_ADP5585=m +CONFIG_MFD_BD9571MWV=y +CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_DA9062=m +CONFIG_MFD_HI6421_PMIC=y +CONFIG_MFD_MAX77620=y +CONFIG_MFD_MT6360=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_RK8XX_I2C=y +CONFIG_MFD_RK8XX_SPI=y +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_TI_LP873X=m +CONFIG_MFD_TPS65219=y +CONFIG_MFD_TPS6594_I2C=y +CONFIG_MFD_WM8994=m +CONFIG_MFD_ROHM_BD718XX=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ARM_SCMI=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD718XX=y +CONFIG_REGULATOR_BD9571MWV=y +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y +CONFIG_REGULATOR_LP873X=m +CONFIG_REGULATOR_MAX77620=y +CONFIG_REGULATOR_MAX8973=y +CONFIG_REGULATOR_MAX20411=m +CONFIG_REGULATOR_MP8859=y +CONFIG_REGULATOR_MT6357=y +CONFIG_REGULATOR_MT6358=y +CONFIG_REGULATOR_MT6359=y +CONFIG_REGULATOR_MT6360=y +CONFIG_REGULATOR_MT6397=y +CONFIG_REGULATOR_PCA9450=y +CONFIG_REGULATOR_PF8X00=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RAA215300=y +CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m +CONFIG_REGULATOR_RK808=y +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS65219=y +CONFIG_REGULATOR_VCTRL=m +CONFIG_MEDIA_SUPPORT=m +# CONFIG_DVB_NET is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_WAVE_VPU=m +CONFIG_VIDEO_E5010_JPEG_ENC=m +CONFIG_VIDEO_TI_J721E_CSI2RX=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_DS90UB953=m +CONFIG_VIDEO_DS90UB960=m +CONFIG_AUXDISPLAY=y +CONFIG_HD44780=m +CONFIG_LCD2S=m +CONFIG_IMG_ASCII_LCD=m +CONFIG_HT16K33=m +CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_I2C_NXP_TDA998X=y +CONFIG_DRM_VGEM=m +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_ILITEK_ILI9881C=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_OSD_OSD101T2587_53TS=y +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m +CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9611=m +CONFIG_DRM_LONTIUM_LT9611UXC=m +CONFIG_DRM_ITE_IT66121=y +CONFIG_DRM_LVDS_CODEC=y +CONFIG_DRM_NWL_MIPI_DSI=m +CONFIG_DRM_PARADE_PS8640=m +CONFIG_DRM_SAMSUNG_DSIM=m +CONFIG_DRM_SII902X=y +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358762=m +CONFIG_DRM_TOSHIBA_TC358767=m +CONFIG_DRM_TOSHIBA_TC358768=m +CONFIG_DRM_TI_TFP410=y +CONFIG_DRM_TI_SN65DSI83=m +CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_TI_TPD12S015=y +CONFIG_DRM_ANALOGIX_ANX7625=m +CONFIG_DRM_CDNS_DSI=y +CONFIG_DRM_CDNS_MHDP8546=y +CONFIG_DRM_SIMPLEDRM=m +CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9163=m +CONFIG_TINYDRM_ILI9225=m +CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m +CONFIG_DRM_PANTHOR=m +CONFIG_DRM_TIDSS=m +CONFIG_FB=y +CONFIG_FB_SIMPLE=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_LP855X=m +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ALOOP=m +# CONFIG_SND_SPI is not set +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=y +CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y +CONFIG_SND_SOC_J721E_EVM=m +CONFIG_SND_SOC_ADAU7002=m +CONFIG_SND_SOC_AK4619=m +CONFIG_SND_SOC_BT_SCO=m +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98390=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_RK817=m +CONFIG_SND_SOC_RT5640=m +CONFIG_SND_SOC_RT5659=m +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_TAS2552=m +CONFIG_SND_SOC_TLV320AIC31XX=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC3X_I2C=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_WCD938X_SDW=m +CONFIG_SND_SOC_WCD939X_SDW=m +CONFIG_SND_SOC_WM8524=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WSA883X=m +CONFIG_SND_SOC_WSA884X=m +CONFIG_SND_SOC_MT6357=m +CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_NAU8822=m +CONFIG_SND_SOC_LPASS_WSA_MACRO=m +CONFIG_SND_SOC_LPASS_VA_MACRO=m +CONFIG_SND_SOC_LPASS_RX_MACRO=m +CONFIG_SND_SOC_LPASS_TX_MACRO=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_HID_MULTITOUCH=m +CONFIG_I2C_HID_OF=m +CONFIG_I2C_HID_OF_ELAN=m +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_CONN_GPIO=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_CDNS_SUPPORT=m +CONFIG_USB_CDNS3=m +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_USB_DWC3=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_ONBOARD_DEV=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=32 +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_BDC_UDC=y +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_G_NCM=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_MULTI_CDC=y +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_UCSI_PMIC_GLINK=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_MUX_FSA4480=m +CONFIG_TYPEC_MUX_GPIO_SBU=m +CONFIG_TYPEC_MUX_NB7VPQ904M=m +CONFIG_TYPEC_MUX_WCD939X_USBSS=m +CONFIG_TYPEC_DP_ALTMODE=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SPI=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFS_BSG=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_CDNS_PLATFORM=m +CONFIG_SCSI_UFS_TI_J721E=m +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_EDAC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX77686=y +CONFIG_RTC_DRV_RK808=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_PCF85063=m +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RV3028=m +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_DA9063=m +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_IMX_BBM_SCMI=y +CONFIG_RTC_DRV_MT6397=m +CONFIG_RTC_DRV_TI_K3=m +CONFIG_DMADEVICES=y +CONFIG_BCM_SBA_RAID=m +CONFIG_DW_EDMA=m +CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y +CONFIG_TI_K3_UDMA_GLUE_LAYER=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_MAX96712=m +# CONFIG_SURFACE_PLATFORMS is not set +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_RS9_PCIE=y +CONFIG_COMMON_CLK_VC3=y +CONFIG_TI_SCI_CLK=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_OMAP=m +# CONFIG_FSL_ERRATUM_A008585 is not set +# CONFIG_HISILICON_ERRATUM_161010101 is not set +CONFIG_OMAP2PLUS_MBOX=m +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +CONFIG_IOMMU_IO_PGTABLE_DART=y +CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_V3=y +CONFIG_REMOTEPROC=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_TI_K3_DSP_REMOTEPROC=m +CONFIG_TI_K3_M4_REMOTEPROC=m +CONFIG_TI_K3_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_CTRL=m +CONFIG_RPMSG_VIRTIO=y +CONFIG_SOUNDWIRE=m +CONFIG_FSL_RCPM=y +CONFIG_QCOM_PMIC_GLINK=m +CONFIG_TI_PRUSS=m +CONFIG_TI_SCI_PM_DOMAINS=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=m +CONFIG_EXTCON_PTN5150=m +CONFIG_EXTCON_USB_GPIO=y +CONFIG_MEMORY=y +CONFIG_OMAP_GPMC=y +CONFIG_IIO=y +CONFIG_MAX9611=m +CONFIG_TI_ADS1015=m +CONFIG_TI_AM335X_ADC=m +CONFIG_IIO_ST_LSM6DSX=m +CONFIG_SENSORS_ISL29018=m +CONFIG_VCNL4000=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_MPL3115=m +CONFIG_PWM=y +CONFIG_PWM_ADP5585=m +CONFIG_PWM_OMAP_DMTIMER=m +CONFIG_PWM_TIECAP=m +CONFIG_PWM_TIEHRPWM=m +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_GPIO=m +CONFIG_RESET_TI_SCI=y +CONFIG_PHY_CAN_TRANSCEIVER=m +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_CADENCE_DPHY=m +CONFIG_PHY_CADENCE_DPHY_RX=m +CONFIG_PHY_CADENCE_SIERRA=y +CONFIG_PHY_CADENCE_SALVO=m +CONFIG_PHY_QCOM_USB_HS=m +CONFIG_PHY_AM654_SERDES=y +CONFIG_PHY_J721E_WIZ=y +CONFIG_OMAP_USB2=m +CONFIG_ARM_CCI_PMU=m +CONFIG_ARM_CCN=m +CONFIG_ARM_CMN=m +CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_DSU_PMU=m +CONFIG_ARM_SPE_PMU=m +CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_NVMEM_LAYOUT_SL28_VPD=m +CONFIG_NVMEM_RMEM=m +CONFIG_FPGA=y +CONFIG_FPGA_MGR_ALTERA_CVP=m +CONFIG_FPGA_BRIDGE=m +CONFIG_ALTERA_FREEZE_BRIDGE=m +CONFIG_FPGA_REGION=m +CONFIG_OF_FPGA_REGION=m +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_MUX_GPIO=m +CONFIG_INTERCONNECT=y +CONFIG_COUNTER=m +CONFIG_TI_ECAP_CAPTURE=m +CONFIG_TI_EQEP=m +CONFIG_HTE=y +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 +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_EFIVAR_FS=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=y +CONFIG_PSTORE=y +CONFIG_PSTORE_RAM=m +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_ENCRYPTED_KEYS=y +CONFIG_KEY_DH_OPERATIONS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CURVE25519=m +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA512_ARM64_CE=m +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +CONFIG_CRYPTO_DEV_SA2UL=m +CONFIG_INDIRECT_PIO=y +CONFIG_DMA_RESTRICTED_POOL=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=32 +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO_DWARF5=y +CONFIG_DEBUG_INFO_REDUCED=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +CONFIG_CORESIGHT=m +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m +CONFIG_CORESIGHT_CATU=m +CONFIG_CORESIGHT_SINK_TPIU=m +CONFIG_CORESIGHT_SINK_ETBV10=m +CONFIG_CORESIGHT_STM=m +CONFIG_CORESIGHT_CPU_DEBUG=m +CONFIG_CORESIGHT_CTI=m +CONFIG_MEMTEST=y diff --git a/config/kernel/linux-k3-current-rt.config b/config/kernel/linux-k3-vendor-rt.config similarity index 100% rename from config/kernel/linux-k3-current-rt.config rename to config/kernel/linux-k3-vendor-rt.config diff --git a/config/kernel/linux-k3-current.config b/config/kernel/linux-k3-vendor.config similarity index 98% rename from config/kernel/linux-k3-current.config rename to config/kernel/linux-k3-vendor.config index 75761c485..93c31c80d 100644 --- a/config/kernel/linux-k3-current.config +++ b/config/kernel/linux-k3-vendor.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -95,6 +96,7 @@ CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_THROTTLING=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_ZSWAP=y +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y # CONFIG_COMPAT_BRK is not set CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -308,7 +310,6 @@ CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -386,6 +387,12 @@ CONFIG_MTD_UBI=y CONFIG_MTD_HYPERBUS=m CONFIG_HBMC_AM654=m CONFIG_ZRAM=y +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -423,6 +430,7 @@ CONFIG_VXLAN=m CONFIG_TUN=y CONFIG_VETH=m CONFIG_VIRTIO_NET=y +CONFIG_NETKIT=y # CONFIG_NET_VENDOR_ALACRITECH is not set # CONFIG_NET_VENDOR_AMAZON is not set # CONFIG_NET_VENDOR_AMD is not set @@ -684,9 +692,9 @@ CONFIG_VIDEO_DS90UB953=m CONFIG_VIDEO_DS90UB960=m CONFIG_AUXDISPLAY=y CONFIG_HD44780=m +CONFIG_LCD2S=m CONFIG_IMG_ASCII_LCD=m CONFIG_HT16K33=m -CONFIG_LCD2S=m CONFIG_DRM=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_I2C_CH7006=m @@ -694,16 +702,16 @@ CONFIG_DRM_I2C_SIL164=m CONFIG_DRM_I2C_NXP_TDA998X=y CONFIG_DRM_VGEM=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m -CONFIG_DRM_PANEL_LVDS=m -CONFIG_DRM_PANEL_SIMPLE=m -CONFIG_DRM_PANEL_EDP=m CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=y CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m CONFIG_DRM_DISPLAY_CONNECTOR=y @@ -901,6 +909,7 @@ CONFIG_RTC_DRV_TI_K3=m CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_AM62L=y CONFIG_TI_K3_UDMA_GLUE_LAYER=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y @@ -936,8 +945,8 @@ CONFIG_RPMSG_VIRTIO=y CONFIG_SOUNDWIRE=m CONFIG_FSL_RCPM=y CONFIG_QCOM_PMIC_GLINK=m -CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_TI_PRUSS=m +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DEVFREQ_GOV_PASSIVE=m CONFIG_EXTCON_PTN5150=m diff --git a/config/kernel/linux-meson-current.config b/config/kernel/linux-meson-current.config index af5617ce8..5210ebbfa 100644 --- a/config/kernel/linux-meson-current.config +++ b/config/kernel/linux-meson-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -599,6 +600,12 @@ CONFIG_EFI_BOOTLOADER_CONTROL=m CONFIG_EFI_CAPSULE_LOADER=m CONFIG_OF_OVERLAY=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y @@ -1580,7 +1587,6 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITYFS=y -CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_TEST=m diff --git a/config/kernel/linux-meson-s4t7-legacy.config b/config/kernel/linux-meson-s4t7-legacy.config index dcb3542ce..ea177ca6b 100644 --- a/config/kernel/linux-meson-s4t7-legacy.config +++ b/config/kernel/linux-meson-s4t7-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 5.15 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-meson64-current.config b/config/kernel/linux-meson64-current.config index 6f84855c2..9fac48dd3 100644 --- a/config/kernel/linux-meson64-current.config +++ b/config/kernel/linux-meson64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -690,6 +691,12 @@ CONFIG_MTD_SPI_NAND=m CONFIG_MTD_SPI_NOR=y CONFIG_MTD_HYPERBUS=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y diff --git a/config/kernel/linux-meson64-edge.config b/config/kernel/linux-meson64-edge.config index b9b087c60..a58ca5aa5 100644 --- a/config/kernel/linux-meson64-edge.config +++ b/config/kernel/linux-meson64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -5,7 +6,9 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y +CONFIG_BPF_JIT_ALWAYS_ON=y # CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +CONFIG_BPF_LSM=y CONFIG_PREEMPT=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y @@ -19,6 +22,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_IKHEADERS=m CONFIG_NUMA_BALANCING=y +CONFIG_CGROUP_FAVOR_DYNMODS=y CONFIG_MEMCG=y CONFIG_BLK_CGROUP=y CONFIG_CFS_BANDWIDTH=y @@ -32,6 +36,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_CHECKPOINT_RESTORE=y @@ -48,8 +53,6 @@ CONFIG_ARM64_ERRATUM_1542419=y # CONFIG_ARM64_ERRATUM_2077057 is not set CONFIG_ARM64_ERRATUM_2441009=y CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_CLUSTER=y CONFIG_NR_CPUS=256 CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 @@ -90,6 +93,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y +CONFIG_BLK_CGROUP_IOCOST=y # CONFIG_BLK_DEBUG_FS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m @@ -415,7 +419,7 @@ CONFIG_NET_DSA=m CONFIG_NET_DSA_TAG_RTL4_A=m CONFIG_NET_DSA_TAG_RTL8_4=m CONFIG_NET_DSA_TAG_RZN1_A5PSW=m -CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m @@ -505,18 +509,17 @@ CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m CONFIG_VIRTIO_VSOCKETS=m -CONFIG_HYPERV_VSOCKETS=m CONFIG_NETLINK_DIAG=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_HSR=m CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y CONFIG_NET_PKTGEN=m CONFIG_HAMRADIO=y CONFIG_AX25=m @@ -615,7 +618,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PCI_HOST_THUNDER_PEM=y CONFIG_PCI_HOST_THUNDER_ECAM=y CONFIG_PCI_HOST_GENERIC=y -CONFIG_PCI_HYPERV_INTERFACE=m CONFIG_PCI_XGENE=y CONFIG_PCI_MESON=y CONFIG_PCI_HISI=y @@ -670,6 +672,12 @@ CONFIG_MTD_SPI_NAND=m CONFIG_MTD_SPI_NOR=y CONFIG_MTD_HYPERBUS=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -1033,6 +1041,7 @@ CONFIG_ATH10K_SDIO=m CONFIG_ATH10K_USB=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43LEGACY=m @@ -1136,7 +1145,6 @@ CONFIG_XEN_NETDEV_BACKEND=m CONFIG_VMXNET3=m CONFIG_FUJITSU_ES=m CONFIG_USB4_NET=m -CONFIG_HYPERV_NET=m CONFIG_NETDEVSIM=m CONFIG_INPUT_FF_MEMLESS=y CONFIG_INPUT_MOUSEDEV=y @@ -2277,7 +2285,6 @@ CONFIG_RADIO_SHARK2=m CONFIG_RADIO_SI4713=m CONFIG_RADIO_TEA5764=m CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -2346,7 +2353,6 @@ CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7740=m @@ -2493,11 +2499,9 @@ CONFIG_DRM_GUD=m CONFIG_DRM_SSD130X=m CONFIG_DRM_SSD130X_I2C=m CONFIG_DRM_SSD130X_SPI=m -CONFIG_DRM_HYPERV=m CONFIG_FB=y CONFIG_FB_UVESA=m CONFIG_FB_SM501=m -CONFIG_FB_HYPERV=m CONFIG_LCD_CLASS_DEVICE=m CONFIG_LCD_OTM3225A=m CONFIG_BACKLIGHT_CLASS_DEVICE=y @@ -2861,7 +2865,6 @@ CONFIG_HID_SUNPLUS=m CONFIG_HID_RMI=m CONFIG_HID_GREENASIA=m CONFIG_GREENASIA_FF=y -CONFIG_HID_HYPERV_MOUSE=m CONFIG_HID_SMARTJOYPLUS=m CONFIG_SMARTJOYPLUS_FF=y CONFIG_HID_TIVO=m @@ -3258,8 +3261,8 @@ CONFIG_RTC_DRV_PCAP=m CONFIG_RTC_DRV_MC13XXX=m CONFIG_RTC_DRV_MT6397=m CONFIG_RTC_DRV_CPCAP=m -CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_AXI_DMAC=m @@ -3273,7 +3276,6 @@ CONFIG_QCOM_HIDMA=y CONFIG_DW_EDMA=m CONFIG_DW_EDMA_PCIE=m CONFIG_SF_PDMA=m -CONFIG_UIO_HV_GENERIC=m CONFIG_VFIO=y CONFIG_VFIO_PCI=y CONFIG_VIRT_DRIVERS=y @@ -3294,9 +3296,6 @@ CONFIG_VP_VDPA=m CONFIG_VHOST_NET=m CONFIG_VHOST_SCSI=m CONFIG_VHOST_VDPA=m -CONFIG_HYPERV=m -CONFIG_HYPERV_UTILS=m -CONFIG_HYPERV_BALLOON=m CONFIG_XEN_DEV_EVTCHN=m CONFIG_XENFS=m CONFIG_XEN_SCSI_BACKEND=m @@ -3733,9 +3732,9 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y @@ -3765,7 +3764,7 @@ CONFIG_AUTOFS_FS=m CONFIG_FUSE_FS=y CONFIG_CUSE=m CONFIG_VIRTIO_FS=m -CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS_XINO_AUTO=y CONFIG_FSCACHE_STATS=y CONFIG_CACHEFILES=m @@ -3961,8 +3960,6 @@ CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_AEGIS128=m CONFIG_CRYPTO_CHACHA20POLY1305=y CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_RMD160=y @@ -4034,7 +4031,9 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_TEST_LOCKUP=m CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_FTRACE is not set +CONFIG_FUNCTION_TRACER=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_KUNIT=m # CONFIG_KUNIT_DEBUGFS is not set CONFIG_KUNIT_ALL_TESTS=m diff --git a/config/kernel/linux-mt7623-current.config b/config/kernel/linux-mt7623-current.config index 9b0be0ba1..fbcf85fc5 100644 --- a/config/kernel/linux-mt7623-current.config +++ b/config/kernel/linux-mt7623-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-mvebu-current.config b/config/kernel/linux-mvebu-current.config index ee93e69b1..211495b31 100644 --- a/config/kernel/linux-mvebu-current.config +++ b/config/kernel/linux-mvebu-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-mvebu-edge.config b/config/kernel/linux-mvebu-edge.config index 4fca83ece..216e792b7 100644 --- a/config/kernel/linux-mvebu-edge.config +++ b/config/kernel/linux-mvebu-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.15 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -655,6 +656,12 @@ CONFIG_OF_OVERLAY=y CONFIG_PARPORT=m CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -944,6 +951,7 @@ CONFIG_ATH10K_PCI=m CONFIG_ATH10K_USB=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set CONFIG_B43=m CONFIG_B43_SDIO=y diff --git a/config/kernel/linux-mvebu64-current.config b/config/kernel/linux-mvebu64-current.config index 196bf7be1..3d457be03 100644 --- a/config/kernel/linux-mvebu64-current.config +++ b/config/kernel/linux-mvebu64-current.config @@ -1,13 +1,14 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_BUILD_SALT="y" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_USELIB=y -CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set CONFIG_PREEMPT=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y @@ -36,22 +37,19 @@ CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_CHECKPOINT_RESTORE=y CONFIG_SCHED_AUTOGROUP=y -CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y CONFIG_SGETMASK_SYSCALL=y CONFIG_KALLSYMS_ALL=y -CONFIG_USERFAULTFD=y -CONFIG_EMBEDDED=y -# CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y +CONFIG_KEXEC=y CONFIG_ARCH_MVEBU=y CONFIG_ARM64_VA_BITS_48=y CONFIG_SCHED_MC=y +CONFIG_SCHED_CLUSTER=y CONFIG_NR_CPUS=64 CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 -CONFIG_KEXEC=y -CONFIG_CRASH_DUMP=y CONFIG_XEN=y CONFIG_COMPAT=y CONFIG_ARMV8_DEPRECATED=y @@ -62,7 +60,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_CMDLINE="console=ttyAMA0" CONFIG_HIBERNATION=y CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y @@ -71,41 +68,32 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y -CONFIG_ACPI_CPPC_CPUFREQ=y CONFIG_ARM_ARMADA_37XX_CPUFREQ=y +CONFIG_ARM_ARMADA_8K_CPUFREQ=y +CONFIG_ACPI_CPPC_CPUFREQ=y CONFIG_ACPI=y CONFIG_ACPI_AC=m CONFIG_VIRTUALIZATION=y CONFIG_KVM=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SM4_ARM64_CE=m -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_BLK_DEV_THROTTLING=y -CONFIG_IOSCHED_BFQ=y -CONFIG_BFQ_GROUP_IOSCHED=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m +CONFIG_ZSWAP=y +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y +# CONFIG_COMPAT_BRK is not set CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CMA=y CONFIG_CMA_AREAS=7 -CONFIG_ZPOOL=y -CONFIG_ZBUD=m -CONFIG_ZSMALLOC=m +CONFIG_USERFAULTFD=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m -CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_XFRM_USER=m CONFIG_XFRM_INTERFACE=m @@ -115,7 +103,6 @@ CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m -CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y @@ -203,7 +190,6 @@ CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m CONFIG_NFT_CT=m CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_COUNTER=m CONFIG_NFT_CONNLIMIT=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m @@ -211,7 +197,6 @@ CONFIG_NFT_MASQ=m CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m @@ -229,6 +214,7 @@ CONFIG_NFT_FIB_NETDEV=m CONFIG_NFT_REJECT_NETDEV=m CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XTABLES_COMPAT=y CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -335,7 +321,6 @@ CONFIG_IP_VS_PE_SIP=m CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y -CONFIG_NF_FLOW_TABLE_IPV4=m CONFIG_NF_LOG_ARP=m CONFIG_NF_LOG_IPV4=m CONFIG_IP_NF_IPTABLES=m @@ -351,17 +336,14 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_SECURITY=m -CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m -CONFIG_NF_FLOW_TABLE_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -426,7 +408,7 @@ CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m -CONFIG_BRIDGE=m +CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y CONFIG_NET_DSA=m @@ -435,8 +417,10 @@ CONFIG_NET_DSA_TAG_BRCM=m CONFIG_NET_DSA_TAG_BRCM_LEGACY=m CONFIG_NET_DSA_TAG_BRCM_PREPEND=m CONFIG_NET_DSA_TAG_GSWIP=m -CONFIG_NET_DSA_TAG_KSZ=m CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_RTL4_A=m +CONFIG_NET_DSA_TAG_RTL8_4=m +CONFIG_NET_DSA_TAG_RZN1_A5PSW=m CONFIG_NET_DSA_TAG_SJA1105=m CONFIG_NET_DSA_TAG_TRAILER=m CONFIG_VLAN_8021Q=m @@ -444,9 +428,6 @@ CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_PHONET=m @@ -509,7 +490,6 @@ CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -522,13 +502,13 @@ CONFIG_NET_ACT_CONNMARK=m CONFIG_NET_ACT_CTINFO=m CONFIG_NET_ACT_CT=m CONFIG_NET_ACT_GATE=m -CONFIG_DCB=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m # CONFIG_BATMAN_ADV_BATMAN_V is not set CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m +CONFIG_VMWARE_VMCI_VSOCKETS=m CONFIG_NETLINK_DIAG=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m @@ -539,40 +519,6 @@ CONFIG_CGROUP_NET_PRIO=y CONFIG_NET_PKTGEN=m CONFIG_CAN=m CONFIG_CAN_ISOTP=m -CONFIG_CAN_VCAN=m -CONFIG_CAN_VXCAN=m -CONFIG_CAN_SLCAN=m -CONFIG_CAN_GRCAN=m -CONFIG_CAN_XILINXCAN=m -CONFIG_CAN_C_CAN=m -CONFIG_CAN_C_CAN_PLATFORM=m -CONFIG_CAN_C_CAN_PCI=m -CONFIG_CAN_CC770=m -CONFIG_CAN_CC770_ISA=m -CONFIG_CAN_CC770_PLATFORM=m -CONFIG_CAN_M_CAN=m -CONFIG_CAN_M_CAN_PCI=m -CONFIG_CAN_PEAK_PCIEFD=m -CONFIG_CAN_SJA1000=m -CONFIG_CAN_EMS_PCI=m -CONFIG_CAN_KVASER_PCI=m -CONFIG_CAN_PEAK_PCI=m -CONFIG_CAN_PLX_PCI=m -CONFIG_CAN_SJA1000_ISA=m -CONFIG_CAN_SJA1000_PLATFORM=m -CONFIG_CAN_SOFTING=m -CONFIG_CAN_HI311X=m -CONFIG_CAN_MCP251X=m -CONFIG_CAN_MCP251XFD=m -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB2=m -CONFIG_CAN_ETAS_ES58X=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -CONFIG_CAN_MCBA_USB=m -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m CONFIG_BT=m CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y @@ -580,7 +526,6 @@ CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m -CONFIG_BT_HS=y CONFIG_BT_6LOWPAN=m # CONFIG_BT_DEBUGFS is not set CONFIG_BT_HCIBTUSB=m @@ -639,19 +584,21 @@ CONFIG_NFC_NXP_NCI=m CONFIG_NFC_NXP_NCI_I2C=m CONFIG_NFC_S3FWRN5_I2C=m CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y +CONFIG_PCI_PF_STUB=m +# CONFIG_HOTPLUG_PCI is not set CONFIG_PCI_AARDVARK=y CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCIE_ARMADA_8K=y CONFIG_CXL_BUS=m CONFIG_UEVENT_HELPER=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_VEXPRESS_CONFIG=y CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_MHI_BUS_EP=m CONFIG_ARM_SCPI_PROTOCOL=m CONFIG_ARM_FFA_TRANSPORT=m -CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y CONFIG_EFI_BOOTLOADER_CONTROL=m CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y @@ -667,9 +614,15 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_UBI=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y @@ -680,14 +633,17 @@ CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_UBLK=m CONFIG_BLK_DEV_NVME=y CONFIG_NVME_TCP=m CONFIG_DW_XDATA_PCIE=m CONFIG_PCI_ENDPOINT_TEST=m CONFIG_XILINX_SDFEC=m CONFIG_HISI_HIKEY_USB=m +CONFIG_OPEN_DICE=m CONFIG_EEPROM_AT24=y CONFIG_EEPROM_EE1004=m +CONFIG_VMWARE_VMCI=m CONFIG_BCM_VK=m CONFIG_MISC_RTSX_PCI=m CONFIG_UACCE=m @@ -702,6 +658,7 @@ CONFIG_SCSI_MVSAS=m CONFIG_SCSI_MVSAS_TASKLET=y CONFIG_SCSI_MVUMI=m CONFIG_SCSI_MPI3MR=m +CONFIG_SCSI_BUSLOGIC=m CONFIG_SCSI_MYRB=m CONFIG_SCSI_MYRS=m CONFIG_XEN_SCSI_FRONTEND=m @@ -713,13 +670,9 @@ CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_CEVA=y CONFIG_AHCI_MVEBU=y -CONFIG_AHCI_XGENE=y -CONFIG_PATA_PLATFORM=y CONFIG_PATA_OF_PLATFORM=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m CONFIG_MD_CLUSTER=m CONFIG_BLK_DEV_DM=m CONFIG_DM_UNSTRIPED=m @@ -765,34 +718,45 @@ CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m CONFIG_BAREUDP=m +CONFIG_AMT=m CONFIG_TUN=y CONFIG_VETH=y CONFIG_VIRTIO_NET=y +CONFIG_NETKIT=y CONFIG_NET_VRF=m CONFIG_MHI_NET=m CONFIG_NET_DSA_LOOP=m CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m +CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MSCC_SEVILLE=m CONFIG_NET_DSA_XRS700X_I2C=m CONFIG_NET_DSA_XRS700X_MDIO=m -CONFIG_NET_DSA_REALTEK_SMI=m CONFIG_NET_DSA_SMSC_LAN9303_I2C=m CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m +CONFIG_SPI_AX88796C=m CONFIG_CAVIUM_PTP=m +CONFIG_DM9051=m +# CONFIG_NET_VENDOR_ENGLEDER is not set +CONFIG_FUN_ETH=m CONFIG_HINIC=m CONFIG_E1000E=y CONFIG_IGB=y CONFIG_IGBVF=y -CONFIG_IXGB=y CONFIG_IXGBE=y CONFIG_IXGBEVF=y CONFIG_ICE=m CONFIG_MVNETA=y +CONFIG_MVPP2=m +CONFIG_MVPP2_PTP=y CONFIG_SKY2=y CONFIG_OCTEONTX2_PF=m CONFIG_OCTEONTX2_VF=m +CONFIG_OCTEON_EP=m CONFIG_PRESTERA=m CONFIG_MLXBF_GIGE=m CONFIG_LAN743X=m @@ -801,15 +765,17 @@ CONFIG_IONIC=m CONFIG_8139CP=y CONFIG_8139TOO=y CONFIG_R8169=y +CONFIG_SFC_SIENA=m CONFIG_SMC91X=y CONFIG_SMSC911X=y +# CONFIG_NET_VENDOR_VERTEXCOM is not set CONFIG_XILINX_EMACLITE=m CONFIG_XILINX_LL_TEMAC=m CONFIG_ADIN_PHY=m +CONFIG_ADIN1100_PHY=m CONFIG_BCM54140_PHY=m CONFIG_BCM7XXX_PHY=m CONFIG_MARVELL_PHY=y -CONFIG_MARVELL_10G_PHY=m CONFIG_MARVELL_88X2222_PHY=m CONFIG_MAXLINEAR_GPHY=m CONFIG_MICROCHIP_T1_PHY=m @@ -818,9 +784,47 @@ CONFIG_NXP_C45_TJA11XX_PHY=m CONFIG_NXP_TJA11XX_PHY=m CONFIG_DP83TC811_PHY=m CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=m CONFIG_VITESSE_PHY=m CONFIG_MICREL_KS8995MA=m -CONFIG_MDIO_BITBANG=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_CAN327=m +CONFIG_CAN_GRCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_XILINXCAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +CONFIG_CAN_CTUCANFD_PCI=m +CONFIG_CAN_CTUCANFD_PLATFORM=m +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PCI=m +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PLX_PCI=m +CONFIG_CAN_SJA1000_ISA=m +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_SOFTING=m +CONFIG_CAN_HI311X=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_MCP251XFD=m +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +CONFIG_MCTP_TRANSPORT_I2C=m CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_GPIO=m CONFIG_MDIO_MVUSB=m @@ -829,7 +833,6 @@ CONFIG_MDIO_IPQ4019=m CONFIG_MDIO_IPQ8064=m CONFIG_MDIO_BUS_MUX_GPIO=m CONFIG_MDIO_BUS_MUX_MMIOREG=m -CONFIG_PCS_XPCS=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -853,32 +856,8 @@ CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_QMI_WWAN=m CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -CONFIG_USB_NET_CH9200=m -CONFIG_USB_NET_AQC111=m CONFIG_ADM8211=m CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y CONFIG_ATH5K=m @@ -905,8 +884,7 @@ CONFIG_ATH10K_DFS_CERTIFIED=y CONFIG_WCN36XX=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m -CONFIG_ATMEL=m -CONFIG_PCI_ATMEL=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43_SDIO=y @@ -926,7 +904,6 @@ CONFIG_IWL3945=m CONFIG_IWLWIFI=m CONFIG_IWLDVM=m CONFIG_IWLMVM=m -CONFIG_IWLWIFI_BCAST_FILTERING=y CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m CONFIG_LIBERTAS_SDIO=m @@ -950,6 +927,9 @@ CONFIG_MT7663U=m CONFIG_MT7663S=m CONFIG_MT7915E=m CONFIG_MT7921E=m +CONFIG_MT7921S=m +CONFIG_MT7921U=m +CONFIG_PLFXLC=m CONFIG_RT2X00=m CONFIG_RT2400PCI=m CONFIG_RT2500PCI=m @@ -976,8 +956,6 @@ CONFIG_RTL8192CU=m # CONFIG_RTLWIFI_DEBUG is not set CONFIG_RTL8XXXU=m CONFIG_RTW88=m -CONFIG_RTW88_8822BE=m -CONFIG_RTW88_8822CE=m CONFIG_RTW88_8723DE=m CONFIG_RTW88_8821CE=m CONFIG_RSI_91X=m @@ -992,23 +970,21 @@ CONFIG_WL12XX=m CONFIG_WL18XX=m CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m -CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m -CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m CONFIG_MAC80211_HWSIM=m -CONFIG_USB_NET_RNDIS_WLAN=m # CONFIG_IEEE802154_DRIVERS is not set CONFIG_WWAN=m CONFIG_WWAN_HWSIM=m CONFIG_MHI_WWAN_CTRL=m CONFIG_MHI_WWAN_MBIM=m CONFIG_RPMSG_WWAN_CTRL=m +CONFIG_MTK_T7XX=m CONFIG_XEN_NETDEV_FRONTEND=m CONFIG_XEN_NETDEV_BACKEND=m CONFIG_FUJITSU_ES=m @@ -1023,6 +999,7 @@ CONFIG_KEYBOARD_QT1050=m CONFIG_KEYBOARD_DLINK_DIR685=m CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_IQS62X=m +CONFIG_KEYBOARD_CYPRESS_SF=m CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_ADC=m CONFIG_JOYSTICK_IFORCE=m @@ -1031,22 +1008,24 @@ CONFIG_JOYSTICK_XPAD=m CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_JOYSTICK_QWIIC=m +CONFIG_JOYSTICK_SENSEHAT=m CONFIG_SERIO_SERPORT=m CONFIG_SERIO_AMBAKMI=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_PERICOM is not set CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_SIFIVE=m -CONFIG_SERIAL_BCM63XX=m CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_FSL_LINFLEXUART=m CONFIG_SERIAL_SPRD=m CONFIG_SERIAL_MVEBU_UART=y +CONFIG_RPMSG_TTY=m CONFIG_TTY_PRINTK=m CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=y @@ -1055,8 +1034,6 @@ CONFIG_HW_RANDOM_CCTRNG=m CONFIG_HW_RANDOM_XIPHERA=m CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m CONFIG_XILLYUSB=m -# CONFIG_RANDOM_TRUST_CPU is not set -# CONFIG_RANDOM_TRUST_BOOTLOADER is not set CONFIG_I2C_CHARDEV=y CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_GPIO=m @@ -1086,8 +1063,6 @@ CONFIG_I2C_VIAPRO=m CONFIG_I2C_SCMI=m CONFIG_I2C_CADENCE=m CONFIG_I2C_CBUS_GPIO=m -CONFIG_I2C_DESIGNWARE_PLATFORM=m -CONFIG_I2C_DESIGNWARE_PCI=m CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m CONFIG_I2C_HISI=m @@ -1109,7 +1084,9 @@ CONFIG_I2C_SLAVE_TESTUNIT=m CONFIG_SPI=y CONFIG_SPI_ARMADA_3700=y CONFIG_SPI_CADENCE_QUADSPI=m +CONFIG_SPI_CADENCE_XSPI=m CONFIG_SPI_HISI_KUNPENG=m +CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_ORION=y CONFIG_SPI_PL022=y CONFIG_SPI_MUX=m @@ -1139,6 +1116,7 @@ CONFIG_POWER_RESET_VEXPRESS=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y CONFIG_GENERIC_ADC_BATTERY=m +CONFIG_IP5XXX_POWER=m CONFIG_CHARGER_ADP5061=m CONFIG_BATTERY_CW2015=m CONFIG_MANAGER_SBS=m @@ -1151,10 +1129,10 @@ CONFIG_CHARGER_BQ256XX=m CONFIG_BATTERY_GOLDFISH=m CONFIG_BATTERY_RT5033=m CONFIG_CHARGER_BD99954=m +CONFIG_BATTERY_UG3105=m CONFIG_SENSORS_AD7314=m CONFIG_SENSORS_AD7414=m CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADM1021=m CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m @@ -1171,7 +1149,6 @@ CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m CONFIG_SENSORS_ASC7621=m CONFIG_SENSORS_AXI_FAN_CONTROL=m CONFIG_SENSORS_ARM_SCPI=m -CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_CORSAIR_CPRO=m CONFIG_SENSORS_CORSAIR_PSU=m @@ -1210,8 +1187,8 @@ CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m +CONFIG_SENSORS_MAX6620=m CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m @@ -1241,11 +1218,14 @@ CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_NCT6683=m CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6775_I2C=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m CONFIG_SENSORS_NZXT_KRAKEN2=m CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_PECI_CPUTEMP=m +CONFIG_SENSORS_PECI_DIMMTEMP=m CONFIG_PMBUS=m CONFIG_SENSORS_ADM1266=m CONFIG_SENSORS_ADM1275=m @@ -1255,6 +1235,7 @@ CONFIG_SENSORS_DPS920AB=m CONFIG_SENSORS_IR35221=m CONFIG_SENSORS_IR36021=m CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LT7182S=m CONFIG_SENSORS_LTC2978=m CONFIG_SENSORS_LTC3815=m CONFIG_SENSORS_MAX15301=m @@ -1266,12 +1247,14 @@ CONFIG_SENSORS_MAX8688=m CONFIG_SENSORS_MP2888=m CONFIG_SENSORS_MP2975=m CONFIG_SENSORS_PIM4328=m +CONFIG_SENSORS_PLI1209BC=m CONFIG_SENSORS_PM6764TR=m CONFIG_SENSORS_Q54SJ108A2=m CONFIG_SENSORS_STPDDC60=m CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE152=m CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SBTSI=m @@ -1292,7 +1275,6 @@ CONFIG_SENSORS_SMSC47B397=m CONFIG_SENSORS_SCH5627=m CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_ADC128D818=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m @@ -1307,6 +1289,7 @@ CONFIG_SENSORS_TMP103=m CONFIG_SENSORS_TMP108=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP464=m CONFIG_SENSORS_VEXPRESS=m CONFIG_SENSORS_VIA686A=m CONFIG_SENSORS_VT1211=m @@ -1328,12 +1311,13 @@ CONFIG_WATCHDOG=y CONFIG_SOFT_WATCHDOG=m CONFIG_BD957XMUF_WATCHDOG=m CONFIG_ARMADA_37XX_WATCHDOG=m +CONFIG_MAX77620_WATCHDOG=m CONFIG_MFD_MADERA=m CONFIG_MFD_MADERA_I2C=m CONFIG_MFD_GATEWORKS_GSC=m CONFIG_MFD_MP2629=m -CONFIG_MFD_INTEL_PMT=m CONFIG_MFD_IQS62X=m +CONFIG_MFD_MAX77714=m CONFIG_MFD_MT6360=m CONFIG_MFD_NTXEC=m CONFIG_MFD_RT4831=m @@ -1342,7 +1326,6 @@ CONFIG_MFD_ROHM_BD718XX=m CONFIG_MFD_ROHM_BD957XMUF=m CONFIG_MFD_ATC260X_I2C=m CONFIG_MFD_QCOM_PM8008=m -CONFIG_MFD_INTEL_M10_BMC=m CONFIG_MFD_RSMU_I2C=m CONFIG_MFD_RSMU_SPI=m CONFIG_REGULATOR=y @@ -1361,69 +1344,46 @@ CONFIG_REGULATOR_MT6360=m CONFIG_REGULATOR_PCA9450=m CONFIG_REGULATOR_PF8X00=m CONFIG_REGULATOR_PWM=m -CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m CONFIG_REGULATOR_RT4801=m CONFIG_REGULATOR_RT4831=m +CONFIG_REGULATOR_RT5190A=m +CONFIG_REGULATOR_RT5759=m CONFIG_REGULATOR_RT6160=m CONFIG_REGULATOR_RT6245=m CONFIG_REGULATOR_RTQ2134=m CONFIG_REGULATOR_RTMV20=m CONFIG_REGULATOR_RTQ6752=m CONFIG_REGULATOR_SY8827N=m +CONFIG_REGULATOR_TPS6286X=m CONFIG_RC_CORE=y CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_MCE_KBD_DECODER=y CONFIG_IR_NEC_DECODER=y CONFIG_IR_RC5_DECODER=y CONFIG_IR_RC6_DECODER=y -CONFIG_IR_JVC_DECODER=y -CONFIG_IR_SONY_DECODER=y CONFIG_IR_SANYO_DECODER=y CONFIG_IR_SHARP_DECODER=y -CONFIG_IR_MCE_KBD_DECODER=y +CONFIG_IR_SONY_DECODER=y CONFIG_IR_XMP_DECODER=y -CONFIG_IR_IMON_DECODER=m # CONFIG_MEDIA_CEC_SUPPORT is not set CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_MEDIA_USB_SUPPORT=y -CONFIG_USB_VIDEO_CLASS=m CONFIG_VIDEO_USBTV=m -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_USB_VIDEO_CLASS=m CONFIG_VIDEO_GO7007=m CONFIG_VIDEO_GO7007_USB=m CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_STK1160=m CONFIG_VIDEO_AU0828=m CONFIG_VIDEO_CX231XX=m CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_TM6000=m -CONFIG_VIDEO_TM6000_ALSA=m -CONFIG_VIDEO_TM6000_DVB=m -CONFIG_DVB_USB=m -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_AS102=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m CONFIG_DVB_USB_V2=m CONFIG_DVB_USB_AF9015=m CONFIG_DVB_USB_AF9035=m @@ -1431,26 +1391,50 @@ CONFIG_DVB_USB_ANYSEE=m CONFIG_DVB_USB_AU6610=m CONFIG_DVB_USB_AZ6007=m CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_DVBSKY=m CONFIG_DVB_USB_EC168=m CONFIG_DVB_USB_GL861=m CONFIG_DVB_USB_LME2510=m CONFIG_DVB_USB_MXL111SF=m CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_DVBSKY=m CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_SMS_USB_DRV=m CONFIG_DVB_TTUSB_BUDGET=m CONFIG_DVB_TTUSB_DEC=m -CONFIG_SMS_USB_DRV=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -CONFIG_DVB_AS102=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m # CONFIG_RADIO_ADAPTERS is not set CONFIG_SDR_PLATFORM_DRIVERS=y -CONFIG_VIDEO_ADV7604=m -CONFIG_VIDEO_MAX9286=m -CONFIG_VIDEO_ST_MIPID02=m +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_CADENCE_CSI2TX=m +CONFIG_VIDEO_AR0521=m CONFIG_VIDEO_HI556=m +CONFIG_VIDEO_HI846=m +CONFIG_VIDEO_HI847=m CONFIG_VIDEO_IMX208=m CONFIG_VIDEO_IMX214=m CONFIG_VIDEO_IMX219=m @@ -1462,7 +1446,10 @@ CONFIG_VIDEO_IMX334=m CONFIG_VIDEO_IMX335=m CONFIG_VIDEO_IMX355=m CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_OG01A1B=m CONFIG_VIDEO_OV02A10=m +CONFIG_VIDEO_OV08D10=m +CONFIG_VIDEO_OV13B10=m CONFIG_VIDEO_OV2680=m CONFIG_VIDEO_OV5648=m CONFIG_VIDEO_OV8865=m @@ -1472,36 +1459,34 @@ CONFIG_VIDEO_RDACM20=m CONFIG_VIDEO_RDACM21=m CONFIG_VIDEO_CCS=m CONFIG_VIDEO_DW9768=m +CONFIG_VIDEO_ADV7604=m +CONFIG_VIDEO_ISL7998X=m +CONFIG_VIDEO_MAX9286=m +CONFIG_VIDEO_ST_MIPID02=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_CX24110=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24117=m CONFIG_DVB_MB86A16=m CONFIG_DVB_TDA10071=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10036=m CONFIG_DVB_TDA10021=m -CONFIG_DVB_OR51211=m CONFIG_DVB_MXL692=m +CONFIG_DVB_OR51211=m CONFIG_DVB_S921=m CONFIG_DVB_MN88443X=m -CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_LNBH29=m -CONFIG_DVB_ISL6405=m CONFIG_DVB_A8293=m +CONFIG_DVB_ISL6405=m CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LNBH29=m CONFIG_DVB_TDA665x=m +CONFIG_DVB_DRX39XYJ=m CONFIG_FB=y -CONFIG_FB_ARMCLCD=y CONFIG_XEN_FBDEV_FRONTEND=m CONFIG_LCD_CLASS_DEVICE=m -CONFIG_BACKLIGHT_KTD253=m -CONFIG_BACKLIGHT_PWM=m -CONFIG_BACKLIGHT_RT4831=m -CONFIG_BACKLIGHT_LM3630A=m -CONFIG_BACKLIGHT_LP855X=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -1524,18 +1509,25 @@ CONFIG_HID_ELAN=m CONFIG_HID_EZKEY=y CONFIG_HID_GLORIOUS=m CONFIG_HID_VIVALDI=m +CONFIG_HID_XIAOMI=m CONFIG_HID_ITE=m CONFIG_HID_KENSINGTON=y CONFIG_HID_LOGITECH=y +CONFIG_HID_MEGAWORLD_FF=m CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y +CONFIG_HID_NINTENDO=m CONFIG_HID_PLAYSTATION=m +CONFIG_HID_RAZER=m CONFIG_HID_RETRODE=m CONFIG_HID_SEMITEK=m +CONFIG_HID_SIGMAMICRO=m +CONFIG_HID_TOPRE=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_MCP2221=m CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF_ELAN=m CONFIG_I2C_HID_OF_GOODIX=m CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y @@ -1581,9 +1573,11 @@ CONFIG_TYPEC_TCPCI=m CONFIG_TYPEC_MT6360=m CONFIG_TYPEC_TCPCI_MAXIM=m CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_ANX7411=m +CONFIG_TYPEC_RT1719=m CONFIG_TYPEC_STUSB160X=m -CONFIG_TYPEC_DP_ALTMODE=m -CONFIG_TYPEC_NVIDIA_ALTMODE=m +CONFIG_TYPEC_WUSB3801=m +CONFIG_TYPEC_MUX_FSA4480=m CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y @@ -1591,6 +1585,7 @@ CONFIG_MMC_SDHCI_ACPI=m CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_HSQ=m CONFIG_MMC_SDHCI_XENON=y +CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_MULTICOLOR=m CONFIG_LEDS_AW2013=m @@ -1601,15 +1596,19 @@ CONFIG_LEDS_LP55XX_COMMON=m CONFIG_LEDS_PWM=m CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXREG=m +CONFIG_LEDS_PWM_MULTICOLOR=m CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_LEDS_TRIGGER_ACTIVITY=m CONFIG_LEDS_TRIGGER_TTY=m CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MAX77686=m +CONFIG_RTC_DRV_NCT3018Y=m CONFIG_RTC_DRV_ISL12026=m CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_RV3032=m CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_OPTEE=m CONFIG_RTC_DRV_NTXEC=m CONFIG_RTC_DRV_ARMADA38X=y CONFIG_RTC_DRV_HID_SENSOR_TIME=m @@ -1626,6 +1625,8 @@ CONFIG_VFIO=y CONFIG_VFIO_PCI=y CONFIG_VFIO_PLATFORM=y CONFIG_VIRT_DRIVERS=y +CONFIG_VMGENID=m +CONFIG_NITRO_ENCLAVES=m CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y @@ -1637,47 +1638,46 @@ CONFIG_XENFS=m CONFIG_XEN_SCSI_BACKEND=m CONFIG_STAGING=y CONFIG_RTL8723BS=m -CONFIG_R8188EU=m -CONFIG_88EU_AP_MODE=y CONFIG_VT6655=m CONFIG_VT6656=m CONFIG_ADIS16203=m CONFIG_ADIS16240=m CONFIG_AD7816=m -CONFIG_AD7280=m CONFIG_ADT7316=m CONFIG_ADT7316_I2C=m -CONFIG_AD7746=m CONFIG_AD9832=m CONFIG_AD9834=m CONFIG_AD5933=m -CONFIG_ADE7854=m -CONFIG_AD2S1210=m -CONFIG_COMMON_CLK_XLNX_CLKWZRD=m -CONFIG_SURFACE_3_BUTTON=m CONFIG_SURFACE_3_POWER_OPREGION=m CONFIG_SURFACE_GPE=m CONFIG_SURFACE_HOTPLUG=m CONFIG_SURFACE_PRO3_BUTTON=m -CONFIG_ICST=y CONFIG_LMK04832=m CONFIG_COMMON_CLK_SI544=m CONFIG_COMMON_CLK_AXI_CLKGEN=m CONFIG_COMMON_CLK_XGENE=y CONFIG_COMMON_CLK_PWM=m +CONFIG_COMMON_CLK_RS9_PCIE=m +CONFIG_COMMON_CLK_XLNX_CLKWZRD=m CONFIG_ARM_MHU=m CONFIG_ARM_MHU_V2=m CONFIG_ARM_SMMU=y +CONFIG_RPMSG_CTRL=m CONFIG_RPMSG_NS=m CONFIG_RPMSG_QCOM_GLINK_RPM=m CONFIG_EXTCON_ADC_JACK=m CONFIG_EXTCON_USBC_TUSB320=m -CONFIG_IIO=m CONFIG_IIO_SW_TRIGGER=m CONFIG_ADIS16201=m CONFIG_ADIS16209=m +CONFIG_ADXL313_I2C=m +CONFIG_ADXL313_SPI=m CONFIG_ADXL345_I2C=m CONFIG_ADXL345_SPI=m +CONFIG_ADXL355_I2C=m +CONFIG_ADXL355_SPI=m +CONFIG_ADXL367_SPI=m +CONFIG_ADXL367_I2C=m CONFIG_BMA180=m CONFIG_BMA220=m CONFIG_BMC150_ACCEL=m @@ -1707,6 +1707,7 @@ CONFIG_STK8312=m CONFIG_STK8BA50=m CONFIG_AD7192=m CONFIG_AD7266=m +CONFIG_AD7280=m CONFIG_AD7291=m CONFIG_AD7298=m CONFIG_AD7606_IFACE_PARALLEL=m @@ -1719,7 +1720,6 @@ CONFIG_AD7887=m CONFIG_AD7923=m CONFIG_AD799X=m CONFIG_AD9467=m -CONFIG_ADI_AXI_ADC=m CONFIG_CC10001_ADC=m CONFIG_ENVELOPE_DETECTOR=m CONFIG_HI8435=m @@ -1753,8 +1753,10 @@ CONFIG_TI_TSC2046=m CONFIG_VF610_ADC=m CONFIG_IIO_RESCALE=m CONFIG_AD8366=m +CONFIG_ADA4250=m CONFIG_HMC425=m CONFIG_AD7150=m +CONFIG_AD7746=m CONFIG_ATLAS_PH_SENSOR=m CONFIG_ATLAS_EZO_SENSOR=m CONFIG_BME680=m @@ -1762,8 +1764,10 @@ CONFIG_CCS811=m CONFIG_IAQCORE=m CONFIG_SCD30_CORE=m CONFIG_SCD30_I2C=m +CONFIG_SCD4X=m CONFIG_SENSIRION_SGP40=m CONFIG_SPS30_I2C=m +CONFIG_SENSEAIR_SUNRISE_CO2=m CONFIG_VZ89X=m CONFIG_IIO_SSP_SENSORS_COMMONS=m CONFIG_IIO_SSP_SENSORHUB=m @@ -1777,6 +1781,7 @@ CONFIG_AD5592R=m CONFIG_AD5593R=m CONFIG_AD5504=m CONFIG_AD5624R_SPI=m +CONFIG_LTC2688=m CONFIG_AD5686_SPI=m CONFIG_AD5696_I2C=m CONFIG_AD5755=m @@ -1801,6 +1806,9 @@ CONFIG_TI_DAC5571=m CONFIG_VF610_DAC=m CONFIG_AD9523=m CONFIG_ADF4350=m +CONFIG_ADMV1014=m +CONFIG_ADMV4420=m +CONFIG_ADRF6780=m CONFIG_ADIS16080=m CONFIG_ADIS16130=m CONFIG_ADIS16136=m @@ -1930,11 +1938,14 @@ CONFIG_LIDAR_LITE_V2=m CONFIG_RFD77402=m CONFIG_SRF04=m CONFIG_SX9310=m +CONFIG_SX9324=m +CONFIG_SX9360=m CONFIG_SX9500=m CONFIG_SRF08=m CONFIG_VCNL3020=m CONFIG_AD2S90=m CONFIG_AD2S1200=m +CONFIG_AD2S1210=m CONFIG_IQS620AT_TEMP=m CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m @@ -1945,17 +1956,21 @@ CONFIG_TMP007=m CONFIG_TMP117=m CONFIG_TSYS01=m CONFIG_TSYS02D=m +CONFIG_MAX31865=m CONFIG_PWM=y CONFIG_PWM_ATMEL_TCB=m +CONFIG_PWM_CLK=m CONFIG_PWM_DWC=m CONFIG_PWM_FSL_FTM=m CONFIG_PWM_IQS620A=m CONFIG_PWM_NTXEC=m CONFIG_PWM_PCA9685=m +CONFIG_PWM_XILINX=m CONFIG_RESET_CONTROLLER=y -CONFIG_PHY_XGENE=y +CONFIG_RESET_TI_TPS380X=m CONFIG_PHY_CAN_TRANSCEIVER=m CONFIG_PHY_CADENCE_TORRENT=m +CONFIG_PHY_CADENCE_DPHY_RX=m CONFIG_PHY_CADENCE_SALVO=m CONFIG_PHY_MVEBU_A3700_COMPHY=m CONFIG_PHY_MVEBU_CP110_UTMI=m @@ -1967,6 +1982,7 @@ CONFIG_ARM_CCI_PMU=m CONFIG_ARM_CMN=m CONFIG_ARM_SMMU_V3_PMU=m CONFIG_ARM_DMC620_PMU=m +CONFIG_HNS3_PMU=m CONFIG_USB4=m CONFIG_USB4_DMA_TEST=m CONFIG_DAX=y @@ -1977,6 +1993,7 @@ CONFIG_MUX_ADG792A=m CONFIG_MUX_ADGS1408=m CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=m +CONFIG_PECI=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y @@ -1995,7 +2012,7 @@ CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m -CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=y CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_OVERLAY_FS=m @@ -2017,6 +2034,7 @@ CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_NFS_V4_1_MIGRATION=y +# CONFIG_NFS_V4_2_READ_PLUS is not set CONFIG_NFSD=m CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y @@ -2088,27 +2106,20 @@ CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_UNICODE=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_TRUSTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=y +CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=y CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_DH=m -CONFIG_CRYPTO_SM2=m -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_CFB=m -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_KEYWRAP=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_VMAC=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_RMD160=y -CONFIG_CRYPTO_WP512=y CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m @@ -2120,6 +2131,18 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_HCTR2=m +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=y CONFIG_CRYPTO_LZ4HC=m @@ -2128,8 +2151,26 @@ CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_SM4_ARM64_CE=m +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m +CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m CONFIG_CRYPTO_DEV_MARVELL_CESA=m +CONFIG_CRYPTO_DEV_QAT_DH895xCC=m +CONFIG_CRYPTO_DEV_QAT_C3XXX=m +CONFIG_CRYPTO_DEV_QAT_C62X=m +CONFIG_CRYPTO_DEV_QAT_4XXX=m +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m +CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m +CONFIG_CRYPTO_DEV_QAT_C62XVF=m CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m @@ -2137,10 +2178,8 @@ CONFIG_CRYPTO_DEV_CCREE=m CONFIG_CRYPTO_DEV_HISI_TRNG=m CONFIG_PRIME_NUMBERS=m CONFIG_CRC_CCITT=y -CONFIG_CRC64=m CONFIG_DMA_CMA=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_DWARF5=y CONFIG_DEBUG_INFO_BTF=y CONFIG_MAGIC_SYSRQ=y @@ -2161,6 +2200,7 @@ CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y CONFIG_CORESIGHT_SOURCE_ETM4X=y CONFIG_CORESIGHT_CPU_DEBUG=m CONFIG_CORESIGHT_TRBE=m +CONFIG_FUNCTION_ERROR_INJECTION=y CONFIG_TEST_DIV64=m CONFIG_TEST_SCANF=m CONFIG_TEST_BITOPS=m diff --git a/config/kernel/linux-mvebu64-edge.config b/config/kernel/linux-mvebu64-edge.config index 72a81db9f..88e2d1061 100644 --- a/config/kernel/linux-mvebu64-edge.config +++ b/config/kernel/linux-mvebu64-edge.config @@ -1,9 +1,8 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_BUILD_SALT="y" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_USELIB=y -CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y @@ -43,11 +42,8 @@ CONFIG_SGETMASK_SYSCALL=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y CONFIG_KEXEC=y -CONFIG_CRASH_DUMP=y CONFIG_ARCH_MVEBU=y CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_CLUSTER=y CONFIG_NR_CPUS=64 CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 @@ -69,22 +65,21 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y -CONFIG_ACPI_CPPC_CPUFREQ=y CONFIG_ARM_ARMADA_37XX_CPUFREQ=y CONFIG_ARM_ARMADA_8K_CPUFREQ=y +CONFIG_ACPI_CPPC_CPUFREQ=y CONFIG_ACPI=y CONFIG_ACPI_AC=m -CONFIG_ACPI_VIDEO=m CONFIG_VIRTUALIZATION=y CONFIG_KVM=y CONFIG_KPROBES=y -CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_BLK_DEV_THROTTLING=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m +CONFIG_ZSWAP=y # CONFIG_COMPAT_BRK is not set CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y @@ -221,18 +216,22 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_HMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m @@ -247,6 +246,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m @@ -270,6 +270,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_SOCKET=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m @@ -328,20 +329,9 @@ CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -356,24 +346,14 @@ CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m @@ -391,9 +371,6 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_IP_DCCP=m -CONFIG_SCTP_DBG_OBJCNT=y -CONFIG_SCTP_COOKIE_HMAC_SHA1=y CONFIG_RDS=m CONFIG_RDS_TCP=m CONFIG_TIPC=m @@ -409,7 +386,7 @@ CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m -CONFIG_BRIDGE=m +CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y CONFIG_NET_DSA=m @@ -429,9 +406,6 @@ CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_PHONET=m @@ -494,7 +468,6 @@ CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -507,11 +480,9 @@ CONFIG_NET_ACT_CONNMARK=m CONFIG_NET_ACT_CTINFO=m CONFIG_NET_ACT_CT=m CONFIG_NET_ACT_GATE=m -CONFIG_DCB=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m # CONFIG_BATMAN_ADV_BATMAN_V is not set -CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m @@ -555,6 +526,7 @@ CONFIG_CFG80211_CERTIFICATION_ONUS=y CONFIG_CFG80211_REG_CELLULAR_HINTS=y CONFIG_CFG80211_REG_RELAX_NO_IR=y # CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_MAC80211_MESH=y CONFIG_RFKILL=m @@ -620,7 +592,14 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_UBI=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m @@ -672,8 +651,6 @@ CONFIG_AHCI_MVEBU=y CONFIG_PATA_OF_PLATFORM=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m CONFIG_MD_CLUSTER=m CONFIG_BLK_DEV_DM=m CONFIG_DM_UNSTRIPED=m @@ -723,6 +700,7 @@ CONFIG_AMT=m CONFIG_TUN=y CONFIG_VETH=y CONFIG_VIRTIO_NET=y +CONFIG_NETKIT=y CONFIG_NET_VRF=m CONFIG_MHI_NET=m CONFIG_NET_DSA_LOOP=m @@ -769,7 +747,6 @@ CONFIG_SFC_SIENA=m CONFIG_SMC91X=y CONFIG_SMSC911X=y # CONFIG_NET_VENDOR_VERTEXCOM is not set -CONFIG_TXGBE=m CONFIG_XILINX_EMACLITE=m CONFIG_XILINX_LL_TEMAC=m CONFIG_ADIN_PHY=m @@ -787,7 +764,6 @@ CONFIG_DP83TC811_PHY=m CONFIG_DP83869_PHY=m CONFIG_DP83TD510_PHY=m CONFIG_VITESSE_PHY=m -CONFIG_MICREL_KS8995MA=m CONFIG_CAN_VCAN=m CONFIG_CAN_VXCAN=m CONFIG_CAN_CAN327=m @@ -857,32 +833,8 @@ CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_QMI_WWAN=m CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -CONFIG_USB_NET_CH9200=m -CONFIG_USB_NET_AQC111=m CONFIG_ADM8211=m CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y CONFIG_ATH5K=m @@ -909,8 +861,7 @@ CONFIG_ATH10K_DFS_CERTIFIED=y CONFIG_WCN36XX=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m -CONFIG_ATMEL=m -CONFIG_PCI_ATMEL=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43_SDIO=y @@ -996,15 +947,10 @@ CONFIG_WL12XX=m CONFIG_WL18XX=m CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m -CONFIG_RTL8822BU=m -CONFIG_RTL8821CU=m -CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m -CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m -CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_MAC80211_HWSIM=m # CONFIG_IEEE802154_DRIVERS is not set CONFIG_WWAN=m @@ -1091,7 +1037,6 @@ CONFIG_I2C_VIAPRO=m CONFIG_I2C_SCMI=m CONFIG_I2C_CADENCE=m CONFIG_I2C_CBUS_GPIO=m -CONFIG_I2C_DESIGNWARE_PCI=m CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m CONFIG_I2C_HISI=m @@ -1287,7 +1232,6 @@ CONFIG_SENSORS_XDPE152=m CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SBTSI=m -CONFIG_SENSORS_SBRMI=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m CONFIG_SENSORS_SHT3x=m @@ -1373,7 +1317,6 @@ CONFIG_REGULATOR_MT6360=m CONFIG_REGULATOR_PCA9450=m CONFIG_REGULATOR_PF8X00=m CONFIG_REGULATOR_PWM=m -CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m CONFIG_REGULATOR_RT4801=m CONFIG_REGULATOR_RT4831=m CONFIG_REGULATOR_RT5190A=m @@ -1515,14 +1458,8 @@ CONFIG_DVB_LNBH29=m CONFIG_DVB_TDA665x=m CONFIG_DVB_DRX39XYJ=m CONFIG_FB=y -CONFIG_FB_ARMCLCD=y CONFIG_XEN_FBDEV_FRONTEND=m CONFIG_LCD_CLASS_DEVICE=m -CONFIG_BACKLIGHT_KTD253=m -CONFIG_BACKLIGHT_PWM=m -CONFIG_BACKLIGHT_RT4831=m -CONFIG_BACKLIGHT_LM3630A=m -CONFIG_BACKLIGHT_LP855X=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -1548,7 +1485,7 @@ CONFIG_HID_VIVALDI=m CONFIG_HID_XIAOMI=m CONFIG_HID_ITE=m CONFIG_HID_KENSINGTON=y -CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH=m CONFIG_HID_MEGAWORLD_FF=m CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y @@ -1593,11 +1530,9 @@ CONFIG_USB_SERIAL_CP210X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_XR=m CONFIG_APPLE_MFI_FASTCHARGE=m -CONFIG_USB_ONBOARD_HUB=m CONFIG_NOP_USB_XCEIV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y -CONFIG_USB_MV_UDC=y CONFIG_USB_SNP_UDC_PLAT=m CONFIG_USB_MAX3420_UDC=m CONFIG_USB_MASS_STORAGE=m @@ -1648,8 +1583,8 @@ CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_OPTEE=m CONFIG_RTC_DRV_NTXEC=m CONFIG_RTC_DRV_ARMADA38X=y -CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_DW_AXI_DMAC=m @@ -1675,17 +1610,13 @@ CONFIG_XENFS=m CONFIG_XEN_SCSI_BACKEND=m CONFIG_STAGING=y CONFIG_RTL8723BS=m -CONFIG_VT6655=m -CONFIG_VT6656=m CONFIG_ADIS16203=m -CONFIG_ADIS16240=m CONFIG_AD7816=m CONFIG_ADT7316=m CONFIG_ADT7316_I2C=m CONFIG_AD9832=m CONFIG_AD9834=m CONFIG_AD5933=m -CONFIG_AD2S1210=m CONFIG_SURFACE_3_POWER_OPREGION=m CONFIG_SURFACE_GPE=m CONFIG_SURFACE_HOTPLUG=m @@ -1758,7 +1689,6 @@ CONFIG_AD7887=m CONFIG_AD7923=m CONFIG_AD799X=m CONFIG_AD9467=m -CONFIG_ADI_AXI_ADC=m CONFIG_CC10001_ADC=m CONFIG_ENVELOPE_DETECTOR=m CONFIG_HI8435=m @@ -1780,13 +1710,13 @@ CONFIG_SD_ADC_MODULATOR=m CONFIG_TI_ADC081C=m CONFIG_TI_ADC0832=m CONFIG_TI_ADC084S021=m -CONFIG_TI_ADC12138=m CONFIG_TI_ADC108S102=m +CONFIG_TI_ADC12138=m CONFIG_TI_ADC161S626=m CONFIG_TI_ADS1015=m +CONFIG_TI_ADS131E08=m CONFIG_TI_ADS7950=m CONFIG_TI_ADS8688=m -CONFIG_TI_ADS131E08=m CONFIG_TI_TLC4541=m CONFIG_TI_TSC2046=m CONFIG_VF610_ADC=m @@ -1984,6 +1914,7 @@ CONFIG_SRF08=m CONFIG_VCNL3020=m CONFIG_AD2S90=m CONFIG_AD2S1200=m +CONFIG_AD2S1210=m CONFIG_IQS620AT_TEMP=m CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m @@ -2034,9 +1965,9 @@ CONFIG_MUX_MMIO=m CONFIG_PECI=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_XFS_FS=y CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y @@ -2089,7 +2020,6 @@ CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG is not set CONFIG_SMB_SERVER=m -CONFIG_SMB_SERVER_KERBEROS5=y CONFIG_9P_FS=m CONFIG_9P_FS_POSIX_ACL=y CONFIG_9P_FS_SECURITY=y @@ -2144,14 +2074,16 @@ CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_UNICODE=y +CONFIG_PERSISTENT_KEYRINGS=y CONFIG_TRUSTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=y +CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_SM2=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m @@ -2167,16 +2099,13 @@ CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_CFB=m CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_HCTR2=m -CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_RMD160=y -CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_WP512=y CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_842=m @@ -2189,11 +2118,8 @@ CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_POLYVAL_ARM64_CE=m CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_SM4_ARM64_CE=m CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m @@ -2208,13 +2134,11 @@ CONFIG_CRYPTO_DEV_QAT_4XXX=m CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m CONFIG_CRYPTO_DEV_QAT_C62XVF=m -CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m CONFIG_CRYPTO_DEV_HISI_TRNG=m CONFIG_PRIME_NUMBERS=m -CONFIG_CRC_CCITT=y CONFIG_DMA_CMA=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO_DWARF5=y @@ -2224,7 +2148,6 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DETECT_HUNG_TASK=y CONFIG_TEST_LOCKUP=m -# CONFIG_SCHED_DEBUG is not set CONFIG_SCF_TORTURE_TEST=m CONFIG_RCU_SCALE_TEST=m CONFIG_RCU_REF_SCALE_TEST=m @@ -2239,7 +2162,6 @@ CONFIG_CORESIGHT_CPU_DEBUG=m CONFIG_CORESIGHT_TRBE=m CONFIG_FUNCTION_ERROR_INJECTION=y CONFIG_TEST_DIV64=m -CONFIG_TEST_SCANF=m CONFIG_TEST_BITOPS=m CONFIG_TEST_FREE_PAGES=m CONFIG_MEMTEST=y diff --git a/config/kernel/linux-mvebu64-legacy.config b/config/kernel/linux-mvebu64-legacy.config new file mode 100644 index 000000000..4b063bfbe --- /dev/null +++ b/config/kernel/linux-mvebu64-legacy.config @@ -0,0 +1,2251 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="y" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_USELIB=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +CONFIG_PREEMPT=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_SGETMASK_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +CONFIG_ARCH_MVEBU=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_CLUSTER=y +CONFIG_NR_CPUS=64 +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=2 +CONFIG_XEN=y +CONFIG_COMPAT=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_CMDLINE="console=ttyAMA0" +CONFIG_HIBERNATION=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPUFREQ_DT=y +CONFIG_ACPI_CPPC_CPUFREQ=y +CONFIG_ARM_ARMADA_37XX_CPUFREQ=y +CONFIG_ARM_ARMADA_8K_CPUFREQ=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_VIDEO=m +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m +CONFIG_ZSWAP=y +# CONFIG_COMPAT_BRK is not set +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_CMA=y +CONFIG_CMA_AREAS=7 +CONFIG_USERFAULTFD=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_USER=m +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_ILA=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_HOOK=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XTABLES_COMPAT=y +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_MH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_TWOS=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_IP_DCCP=m +CONFIG_SCTP_DBG_OBJCNT=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_TIPC=m +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +CONFIG_ATM_CLIP_NO_ICMP=y +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_BRIDGE_MRP=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_AR9331=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_RTL4_A=m +CONFIG_NET_DSA_TAG_RTL8_4=m +CONFIG_NET_DSA_TAG_RZN1_A5PSW=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC2=m +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_PHONET=m +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_TAPRIO=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_FQ_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_SCH_ETS=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_CANID=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_EMATCH_IPT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m +CONFIG_NET_ACT_CT=m +CONFIG_NET_ACT_GATE=m +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_BATMAN_V is not set +CONFIG_BATMAN_ADV_NC=y +CONFIG_OPENVSWITCH=m +CONFIG_VSOCKETS=m +CONFIG_VMWARE_VMCI_VSOCKETS=m +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_HSR=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_CGROUP_NET_PRIO=y +CONFIG_NET_PKTGEN=m +CONFIG_CAN=m +CONFIG_CAN_ISOTP=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_6LOWPAN=m +# CONFIG_BT_DEBUGFS is not set +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_VIRTIO=m +CONFIG_AF_RXRPC=m +CONFIG_MCTP=y +CONFIG_CFG80211=m +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_REG_CELLULAR_HINTS=y +CONFIG_CFG80211_REG_RELAX_NO_IR=y +# CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_XEN=m +CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_NCI_UART=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PORT100=m +CONFIG_NFC_VIRTUAL_NCI=m +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_MICROREAD_I2C=m +CONFIG_NFC_MRVL_USB=m +CONFIG_NFC_MRVL_UART=m +CONFIG_NFC_MRVL_I2C=m +CONFIG_NFC_MRVL_SPI=m +CONFIG_NFC_ST21NFCA_I2C=m +CONFIG_NFC_ST_NCI_I2C=m +CONFIG_NFC_ST_NCI_SPI=m +CONFIG_NFC_NXP_NCI=m +CONFIG_NFC_NXP_NCI_I2C=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCI_PF_STUB=m +# CONFIG_HOTPLUG_PCI is not set +CONFIG_PCI_AARDVARK=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCIE_ARMADA_8K=y +CONFIG_CXL_BUS=m +CONFIG_UEVENT_HELPER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_VEXPRESS_CONFIG=y +CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_MHI_BUS_EP=m +CONFIG_ARM_SCPI_PROTOCOL=m +CONFIG_ARM_FFA_TRANSPORT=m +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MCHP48L640=m +CONFIG_MTD_RAW_NAND=m +CONFIG_MTD_NAND_MARVELL=m +CONFIG_MTD_NAND_MXIC=m +CONFIG_MTD_NAND_CADENCE=m +CONFIG_MTD_NAND_ARASAN=m +CONFIG_MTD_NAND_INTEL_LGM=m +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_NULL_BLK=m +CONFIG_ZRAM=m +CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=48000 +CONFIG_ATA_OVER_ETH=m +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_UBLK=m +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_TCP=m +CONFIG_DW_XDATA_PCIE=m +CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_XILINX_SDFEC=m +CONFIG_HISI_HIKEY_USB=m +CONFIG_OPEN_DICE=m +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_EE1004=m +CONFIG_VMWARE_VMCI=m +CONFIG_BCM_VK=m +CONFIG_MISC_RTSX_PCI=m +CONFIG_UACCE=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MVSAS_TASKLET=y +CONFIG_SCSI_MVUMI=m +CONFIG_SCSI_MPI3MR=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_MYRB=m +CONFIG_SCSI_MYRS=m +CONFIG_XEN_SCSI_FRONTEND=m +CONFIG_SCSI_FDOMAIN_PCI=m +CONFIG_SCSI_VIRTIO=m +CONFIG_ATA=y +# CONFIG_ATA_VERBOSE_ERROR is not set +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_CEVA=y +CONFIG_AHCI_MVEBU=y +CONFIG_PATA_OF_PLATFORM=y +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_MD_CLUSTER=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_UNSTRIPED=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_WRITECACHE=m +CONFIG_DM_EBS=m +CONFIG_DM_CLONE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_MULTIPATH_HST=m +CONFIG_DM_MULTIPATH_IOA=m +CONFIG_DM_DELAY=m +CONFIG_DM_DUST=m +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y +CONFIG_DM_VERITY_FEC=y +CONFIG_DM_SWITCH=m +CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +CONFIG_LOOPBACK_TARGET=m +CONFIG_ISCSI_TARGET=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +CONFIG_IFB=m +CONFIG_MACVLAN=y +CONFIG_MACVTAP=y +CONFIG_IPVLAN=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_AMT=m +CONFIG_TUN=y +CONFIG_VETH=y +CONFIG_VIRTIO_NET=y +CONFIG_NET_VRF=m +CONFIG_MHI_NET=m +CONFIG_NET_DSA_LOOP=m +CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m +CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m +CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MSCC_SEVILLE=m +CONFIG_NET_DSA_XRS700X_I2C=m +CONFIG_NET_DSA_XRS700X_MDIO=m +CONFIG_NET_DSA_SMSC_LAN9303_I2C=m +CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m +CONFIG_SPI_AX88796C=m +CONFIG_CAVIUM_PTP=m +CONFIG_DM9051=m +# CONFIG_NET_VENDOR_ENGLEDER is not set +CONFIG_FUN_ETH=m +CONFIG_HINIC=m +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y +CONFIG_IXGBE=y +CONFIG_IXGBEVF=y +CONFIG_ICE=m +CONFIG_MVNETA=y +CONFIG_MVPP2=m +CONFIG_MVPP2_PTP=y +CONFIG_SKY2=y +CONFIG_OCTEONTX2_PF=m +CONFIG_OCTEONTX2_VF=m +CONFIG_OCTEON_EP=m +CONFIG_PRESTERA=m +CONFIG_MLXBF_GIGE=m +CONFIG_LAN743X=m +CONFIG_NI_XGE_MANAGEMENT_ENET=m +CONFIG_IONIC=m +CONFIG_8139CP=y +CONFIG_8139TOO=y +CONFIG_R8169=y +CONFIG_SFC_SIENA=m +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +# CONFIG_NET_VENDOR_VERTEXCOM is not set +CONFIG_TXGBE=m +CONFIG_XILINX_EMACLITE=m +CONFIG_XILINX_LL_TEMAC=m +CONFIG_ADIN_PHY=m +CONFIG_ADIN1100_PHY=m +CONFIG_BCM54140_PHY=m +CONFIG_BCM7XXX_PHY=m +CONFIG_MARVELL_PHY=y +CONFIG_MARVELL_88X2222_PHY=m +CONFIG_MAXLINEAR_GPHY=m +CONFIG_MICROCHIP_T1_PHY=m +CONFIG_MOTORCOMM_PHY=m +CONFIG_NXP_C45_TJA11XX_PHY=m +CONFIG_NXP_TJA11XX_PHY=m +CONFIG_DP83TC811_PHY=m +CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_MICREL_KS8995MA=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_CAN327=m +CONFIG_CAN_GRCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_XILINXCAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +CONFIG_CAN_CTUCANFD_PCI=m +CONFIG_CAN_CTUCANFD_PLATFORM=m +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PCI=m +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PLX_PCI=m +CONFIG_CAN_SJA1000_ISA=m +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_SOFTING=m +CONFIG_CAN_HI311X=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_MCP251XFD=m +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +CONFIG_MCTP_TRANSPORT_I2C=m +CONFIG_MDIO_BCM_UNIMAC=m +CONFIG_MDIO_GPIO=m +CONFIG_MDIO_MVUSB=m +CONFIG_MDIO_OCTEON=m +CONFIG_MDIO_IPQ4019=m +CONFIG_MDIO_IPQ8064=m +CONFIG_MDIO_BUS_MUX_GPIO=m +CONFIG_MDIO_BUS_MUX_MMIOREG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m +CONFIG_ADM8211=m +CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y +CONFIG_ATH5K=m +CONFIG_ATH9K=m +CONFIG_ATH9K_AHB=y +CONFIG_ATH9K_DFS_CERTIFIED=y +CONFIG_ATH9K_DYNACK=y +CONFIG_ATH9K_WOW=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCI_NO_EEPROM=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +CONFIG_ATH6KL_REGDOMAIN=y +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_DFS_CERTIFIED=y +CONFIG_WCN36XX=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_AT76C50X_USB=m +CONFIG_B43=m +CONFIG_B43_SDIO=y +CONFIG_B43LEGACY=m +# CONFIG_B43LEGACY_DEBUG is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IWL4965=m +CONFIG_IWL3945=m +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +CONFIG_LIBERTAS_MESH=y +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_MWL8K=m +CONFIG_MT7601U=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615E=m +CONFIG_MT7663U=m +CONFIG_MT7663S=m +CONFIG_MT7915E=m +CONFIG_MT7921E=m +CONFIG_MT7921S=m +CONFIG_MT7921U=m +CONFIG_PLFXLC=m +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8XXXU=m +CONFIG_RTW88=m +CONFIG_RTW88_8723DE=m +CONFIG_RTW88_8821CE=m +CONFIG_RSI_91X=m +# CONFIG_RSI_DEBUGFS is not set +CONFIG_CW1200=m +CONFIG_CW1200_WLAN_SDIO=m +CONFIG_CW1200_WLAN_SPI=m +CONFIG_WL1251=m +CONFIG_WL1251_SPI=m +CONFIG_WL1251_SDIO=m +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_RTL8822BU=m +CONFIG_RTL8821CU=m +CONFIG_88XXAU=m +CONFIG_RTL8192EU=m +CONFIG_RTL8189FS=m +CONFIG_RTL8189ES=m +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_MAC80211_HWSIM=m +# CONFIG_IEEE802154_DRIVERS is not set +CONFIG_WWAN=m +CONFIG_WWAN_HWSIM=m +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +CONFIG_RPMSG_WWAN_CTRL=m +CONFIG_MTK_T7XX=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_FUJITSU_ES=m +CONFIG_USB4_NET=m +CONFIG_NETDEVSIM=m +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_QT1050=m +CONFIG_KEYBOARD_DLINK_DIR685=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_IQS62X=m +CONFIG_KEYBOARD_CYPRESS_SF=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ADC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_QWIIC=m +CONFIG_JOYSTICK_SENSEHAT=m +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_AMBAKMI=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_PERICOM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SIFIVE=m +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_FSL_LINFLEXUART=m +CONFIG_SERIAL_SPRD=m +CONFIG_SERIAL_MVEBU_UART=y +CONFIG_RPMSG_TTY=m +CONFIG_TTY_PRINTK=m +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BA431=m +CONFIG_HW_RANDOM_CCTRNG=m +CONFIG_HW_RANDOM_XIPHERA=m +CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m +CONFIG_XILLYUSB=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=m +CONFIG_I2C_MUX_GPIO=m +CONFIG_I2C_MUX_GPMUX=m +CONFIG_I2C_MUX_LTC4306=m +CONFIG_I2C_MUX_PCA9541=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_PINCTRL=m +CONFIG_I2C_MUX_REG=m +CONFIG_I2C_DEMUX_PINCTRL=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_AMD_MP2=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NVIDIA_GPU=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_SCMI=m +CONFIG_I2C_CADENCE=m +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_PCI=m +CONFIG_I2C_EMEV2=m +CONFIG_I2C_GPIO=m +CONFIG_I2C_HISI=m +CONFIG_I2C_MV64XXX=y +CONFIG_I2C_NOMADIK=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_RK3X=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_XILINX=m +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_CP2615=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIRTIO=m +CONFIG_I2C_SLAVE_EEPROM=m +CONFIG_I2C_SLAVE_TESTUNIT=m +CONFIG_SPI=y +CONFIG_SPI_ARMADA_3700=y +CONFIG_SPI_CADENCE_QUADSPI=m +CONFIG_SPI_CADENCE_XSPI=m +CONFIG_SPI_HISI_KUNPENG=m +CONFIG_SPI_MICROCHIP_CORE=m +CONFIG_SPI_ORION=y +CONFIG_SPI_PL022=y +CONFIG_SPI_MUX=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m +CONFIG_DP83640_PHY=m +CONFIG_PTP_1588_CLOCK_KVM=m +CONFIG_PTP_1588_CLOCK_IDT82P33=m +CONFIG_PTP_1588_CLOCK_OCP=m +CONFIG_PINCTRL_MCP23S08=m +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_AMDPT=m +CONFIG_GPIO_HISI=m +CONFIG_GPIO_HLWD=m +CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_PL061=y +CONFIG_GPIO_SYSCON=m +CONFIG_GPIO_XGENE=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA9570=m +CONFIG_GPIO_XRA1403=m +CONFIG_GPIO_AGGREGATOR=m +CONFIG_GPIO_VIRTIO=m +CONFIG_POWER_RESET_ATC260X=m +CONFIG_POWER_RESET_LINKSTATION=m +CONFIG_POWER_RESET_VEXPRESS=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_GENERIC_ADC_BATTERY=m +CONFIG_IP5XXX_POWER=m +CONFIG_CHARGER_ADP5061=m +CONFIG_BATTERY_CW2015=m +CONFIG_MANAGER_SBS=m +CONFIG_CHARGER_LTC4162L=m +CONFIG_CHARGER_MP2629=m +CONFIG_CHARGER_MT6360=m +CONFIG_CHARGER_BQ2515X=m +CONFIG_CHARGER_BQ25980=m +CONFIG_CHARGER_BQ256XX=m +CONFIG_BATTERY_GOLDFISH=m +CONFIG_BATTERY_RT5033=m +CONFIG_CHARGER_BD99954=m +CONFIG_BATTERY_UG3105=m +CONFIG_SENSORS_AD7314=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7310=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_AHT10=m +CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_AXI_FAN_CONTROL=m +CONFIG_SENSORS_ARM_SCPI=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORSAIR_CPRO=m +CONFIG_SENSORS_CORSAIR_PSU=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_GSC=m +CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_HIH6130=m +CONFIG_SENSORS_IIO_HWMON=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC2990=m +CONFIG_SENSORS_LTC2992=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX127=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX31722=m +CONFIG_SENSORS_MAX6620=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_MAX31790=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_TC654=m +CONFIG_SENSORS_TPS23861=m +CONFIG_SENSORS_MR75203=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6775_I2C=m +CONFIG_SENSORS_NCT7802=m +CONFIG_SENSORS_NCT7904=m +CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_NZXT_KRAKEN2=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_PECI_CPUTEMP=m +CONFIG_SENSORS_PECI_DIMMTEMP=m +CONFIG_PMBUS=m +CONFIG_SENSORS_ADM1266=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_BPA_RS600=m +CONFIG_SENSORS_FSP_3Y=m +CONFIG_SENSORS_DPS920AB=m +CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR36021=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LT7182S=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC3815=m +CONFIG_SENSORS_MAX15301=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX16601=m +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_MP2888=m +CONFIG_SENSORS_MP2975=m +CONFIG_SENSORS_PIM4328=m +CONFIG_SENSORS_PLI1209BC=m +CONFIG_SENSORS_PM6764TR=m +CONFIG_SENSORS_Q54SJ108A2=m +CONFIG_SENSORS_STPDDC60=m +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE152=m +CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_SBTSI=m +CONFIG_SENSORS_SBRMI=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +CONFIG_SENSORS_SHT4x=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADS7871=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_TC74=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP108=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP464=m +CONFIG_SENSORS_VEXPRESS=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_XGENE=m +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_ARMADA_THERMAL=y +CONFIG_GENERIC_ADC_THERMAL=m +CONFIG_WATCHDOG=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_BD957XMUF_WATCHDOG=m +CONFIG_ARMADA_37XX_WATCHDOG=m +CONFIG_MAX77620_WATCHDOG=m +CONFIG_MFD_MADERA=m +CONFIG_MFD_MADERA_I2C=m +CONFIG_MFD_GATEWORKS_GSC=m +CONFIG_MFD_MP2629=m +CONFIG_MFD_IQS62X=m +CONFIG_MFD_MAX77714=m +CONFIG_MFD_MT6360=m +CONFIG_MFD_NTXEC=m +CONFIG_MFD_RT4831=m +CONFIG_MFD_TI_LP87565=m +CONFIG_MFD_ROHM_BD718XX=m +CONFIG_MFD_ROHM_BD957XMUF=m +CONFIG_MFD_ATC260X_I2C=m +CONFIG_MFD_QCOM_PM8008=m +CONFIG_MFD_RSMU_I2C=m +CONFIG_MFD_RSMU_SPI=m +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_88PG86X=m +CONFIG_REGULATOR_ATC260X=m +CONFIG_REGULATOR_BD957XMUF=m +CONFIG_REGULATOR_DA9121=m +CONFIG_REGULATOR_FAN53880=m +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MAX8893=m +CONFIG_REGULATOR_MAX77826=m +CONFIG_REGULATOR_MP5416=m +CONFIG_REGULATOR_MP886X=m +CONFIG_REGULATOR_MT6360=m +CONFIG_REGULATOR_PCA9450=m +CONFIG_REGULATOR_PF8X00=m +CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m +CONFIG_REGULATOR_RT4801=m +CONFIG_REGULATOR_RT4831=m +CONFIG_REGULATOR_RT5190A=m +CONFIG_REGULATOR_RT5759=m +CONFIG_REGULATOR_RT6160=m +CONFIG_REGULATOR_RT6245=m +CONFIG_REGULATOR_RTQ2134=m +CONFIG_REGULATOR_RTMV20=m +CONFIG_REGULATOR_RTQ6752=m +CONFIG_REGULATOR_SY8827N=m +CONFIG_REGULATOR_TPS6286X=m +CONFIG_RC_CORE=y +CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_MCE_KBD_DECODER=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_SANYO_DECODER=y +CONFIG_IR_SHARP_DECODER=y +CONFIG_IR_SONY_DECODER=y +CONFIG_IR_XMP_DECODER=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_VIDEO_USBTV=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_STK1160=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_DVB_AS102=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_USB_AIRSPY=m +CONFIG_USB_HACKRF=m +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_CADENCE_CSI2TX=m +CONFIG_VIDEO_AR0521=m +CONFIG_VIDEO_HI556=m +CONFIG_VIDEO_HI846=m +CONFIG_VIDEO_HI847=m +CONFIG_VIDEO_IMX208=m +CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX258=m +CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_IMX290=m +CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX334=m +CONFIG_VIDEO_IMX335=m +CONFIG_VIDEO_IMX355=m +CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_OG01A1B=m +CONFIG_VIDEO_OV02A10=m +CONFIG_VIDEO_OV08D10=m +CONFIG_VIDEO_OV13B10=m +CONFIG_VIDEO_OV2680=m +CONFIG_VIDEO_OV5648=m +CONFIG_VIDEO_OV8865=m +CONFIG_VIDEO_OV9282=m +CONFIG_VIDEO_OV9734=m +CONFIG_VIDEO_RDACM20=m +CONFIG_VIDEO_RDACM21=m +CONFIG_VIDEO_CCS=m +CONFIG_VIDEO_DW9768=m +CONFIG_VIDEO_ADV7604=m +CONFIG_VIDEO_ISL7998X=m +CONFIG_VIDEO_MAX9286=m +CONFIG_VIDEO_ST_MIPID02=m +CONFIG_DVB_STV0910=m +CONFIG_DVB_STV6111=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_TDA10071=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_MXL692=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_S921=m +CONFIG_DVB_MN88443X=m +CONFIG_DVB_A8293=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LNBH29=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_DRX39XYJ=m +CONFIG_FB=y +CONFIG_FB_ARMCLCD=y +CONFIG_XEN_FBDEV_FRONTEND=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_BACKLIGHT_KTD253=m +CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_RT4831=m +CONFIG_BACKLIGHT_LM3630A=m +CONFIG_BACKLIGHT_LP855X=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_DUMMY=m +# CONFIG_SND_PCI is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_VIRTIO=m +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CYPRESS=y +CONFIG_HID_ELAN=m +CONFIG_HID_EZKEY=y +CONFIG_HID_GLORIOUS=m +CONFIG_HID_VIVALDI=m +CONFIG_HID_XIAOMI=m +CONFIG_HID_ITE=m +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MEGAWORLD_FF=m +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NINTENDO=m +CONFIG_HID_PLAYSTATION=m +CONFIG_HID_RAZER=m +CONFIG_HID_RETRODE=m +CONFIG_HID_SEMITEK=m +CONFIG_HID_SIGMAMICRO=m +CONFIG_HID_TOPRE=m +CONFIG_HID_SENSOR_HUB=m +CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +CONFIG_HID_MCP2221=m +CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF_ELAN=m +CONFIG_I2C_HID_OF_GOODIX=m +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_XHCI_MVEBU=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_HCD_BCMA=m +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_HOST=m +CONFIG_USBIP_VUDC=m +CONFIG_USB_CDNS_SUPPORT=m +CONFIG_USB_CDNSP_PCI=m +CONFIG_USB_ISP1760=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_XR=m +CONFIG_APPLE_MFI_FASTCHARGE=m +CONFIG_USB_ONBOARD_HUB=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_MV_UDC=y +CONFIG_USB_SNP_UDC_PLAT=m +CONFIG_USB_MAX3420_UDC=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_GADGET_TARGET=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_RAW_GADGET=m +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_MT6360=m +CONFIG_TYPEC_TCPCI_MAXIM=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_ANX7411=m +CONFIG_TYPEC_RT1719=m +CONFIG_TYPEC_STUSB160X=m +CONFIG_TYPEC_WUSB3801=m +CONFIG_TYPEC_MUX_FSA4480=m +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_HSQ=m +CONFIG_MMC_SDHCI_XENON=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_AW2013=m +CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_LP50XX=m +CONFIG_LEDS_LP55XX_COMMON=m +CONFIG_LEDS_PWM=m +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_MLXREG=m +CONFIG_LEDS_PWM_MULTICOLOR=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m +CONFIG_LEDS_TRIGGER_TTY=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MAX77686=m +CONFIG_RTC_DRV_NCT3018Y=m +CONFIG_RTC_DRV_ISL12026=m +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_RV3032=m +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_OPTEE=m +CONFIG_RTC_DRV_NTXEC=m +CONFIG_RTC_DRV_ARMADA38X=y +CONFIG_RTC_DRV_HID_SENSOR_TIME=m +CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_DMADEVICES=y +CONFIG_BCM_SBA_RAID=m +CONFIG_DW_AXI_DMAC=m +CONFIG_MV_XOR=y +CONFIG_MV_XOR_V2=y +CONFIG_XILINX_ZYNQMP_DPDMA=m +CONFIG_ASYNC_TX_DMA=y +CONFIG_DMATEST=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VFIO_PLATFORM=y +CONFIG_VIRT_DRIVERS=y +CONFIG_VMGENID=m +CONFIG_NITRO_ENCLAVES=m +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_VHOST_NET=y +CONFIG_VHOST_SCSI=m +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XENFS=m +CONFIG_XEN_SCSI_BACKEND=m +CONFIG_STAGING=y +CONFIG_RTL8723BS=m +CONFIG_VT6655=m +CONFIG_VT6656=m +CONFIG_ADIS16203=m +CONFIG_ADIS16240=m +CONFIG_AD7816=m +CONFIG_ADT7316=m +CONFIG_ADT7316_I2C=m +CONFIG_AD9832=m +CONFIG_AD9834=m +CONFIG_AD5933=m +CONFIG_AD2S1210=m +CONFIG_SURFACE_3_POWER_OPREGION=m +CONFIG_SURFACE_GPE=m +CONFIG_SURFACE_HOTPLUG=m +CONFIG_SURFACE_PRO3_BUTTON=m +CONFIG_LMK04832=m +CONFIG_COMMON_CLK_SI544=m +CONFIG_COMMON_CLK_AXI_CLKGEN=m +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMMON_CLK_PWM=m +CONFIG_COMMON_CLK_RS9_PCIE=m +CONFIG_COMMON_CLK_XLNX_CLKWZRD=m +CONFIG_ARM_MHU=m +CONFIG_ARM_MHU_V2=m +CONFIG_ARM_SMMU=y +CONFIG_RPMSG_CTRL=m +CONFIG_RPMSG_NS=m +CONFIG_RPMSG_QCOM_GLINK_RPM=m +CONFIG_EXTCON_ADC_JACK=m +CONFIG_EXTCON_USBC_TUSB320=m +CONFIG_IIO_SW_TRIGGER=m +CONFIG_ADIS16201=m +CONFIG_ADIS16209=m +CONFIG_ADXL313_I2C=m +CONFIG_ADXL313_SPI=m +CONFIG_ADXL345_I2C=m +CONFIG_ADXL345_SPI=m +CONFIG_ADXL355_I2C=m +CONFIG_ADXL355_SPI=m +CONFIG_ADXL367_SPI=m +CONFIG_ADXL367_I2C=m +CONFIG_BMA180=m +CONFIG_BMA220=m +CONFIG_BMC150_ACCEL=m +CONFIG_BMI088_ACCEL=m +CONFIG_DA280=m +CONFIG_DA311=m +CONFIG_DMARD06=m +CONFIG_DMARD09=m +CONFIG_DMARD10=m +CONFIG_FXLS8962AF_I2C=m +CONFIG_FXLS8962AF_SPI=m +CONFIG_HID_SENSOR_ACCEL_3D=m +CONFIG_KXSD9=m +CONFIG_KXCJK1013=m +CONFIG_MC3230=m +CONFIG_MMA7455_I2C=m +CONFIG_MMA7455_SPI=m +CONFIG_MMA7660=m +CONFIG_MMA8452=m +CONFIG_MMA9551=m +CONFIG_MMA9553=m +CONFIG_MXC4005=m +CONFIG_MXC6255=m +CONFIG_SCA3000=m +CONFIG_SCA3300=m +CONFIG_STK8312=m +CONFIG_STK8BA50=m +CONFIG_AD7192=m +CONFIG_AD7266=m +CONFIG_AD7280=m +CONFIG_AD7291=m +CONFIG_AD7298=m +CONFIG_AD7606_IFACE_PARALLEL=m +CONFIG_AD7606_IFACE_SPI=m +CONFIG_AD7766=m +CONFIG_AD7780=m +CONFIG_AD7791=m +CONFIG_AD7793=m +CONFIG_AD7887=m +CONFIG_AD7923=m +CONFIG_AD799X=m +CONFIG_AD9467=m +CONFIG_ADI_AXI_ADC=m +CONFIG_CC10001_ADC=m +CONFIG_ENVELOPE_DETECTOR=m +CONFIG_HI8435=m +CONFIG_HX711=m +CONFIG_INA2XX_ADC=m +CONFIG_LTC2485=m +CONFIG_LTC2497=m +CONFIG_MAX1027=m +CONFIG_MAX11100=m +CONFIG_MAX1118=m +CONFIG_MAX1241=m +CONFIG_MAX1363=m +CONFIG_MAX9611=m +CONFIG_MCP320X=m +CONFIG_MCP3422=m +CONFIG_MEDIATEK_MT6360_ADC=m +CONFIG_MP2629_ADC=m +CONFIG_SD_ADC_MODULATOR=m +CONFIG_TI_ADC081C=m +CONFIG_TI_ADC0832=m +CONFIG_TI_ADC084S021=m +CONFIG_TI_ADC12138=m +CONFIG_TI_ADC108S102=m +CONFIG_TI_ADC161S626=m +CONFIG_TI_ADS1015=m +CONFIG_TI_ADS7950=m +CONFIG_TI_ADS8688=m +CONFIG_TI_ADS131E08=m +CONFIG_TI_TLC4541=m +CONFIG_TI_TSC2046=m +CONFIG_VF610_ADC=m +CONFIG_IIO_RESCALE=m +CONFIG_AD8366=m +CONFIG_ADA4250=m +CONFIG_HMC425=m +CONFIG_AD7150=m +CONFIG_AD7746=m +CONFIG_ATLAS_PH_SENSOR=m +CONFIG_ATLAS_EZO_SENSOR=m +CONFIG_BME680=m +CONFIG_CCS811=m +CONFIG_IAQCORE=m +CONFIG_SCD30_CORE=m +CONFIG_SCD30_I2C=m +CONFIG_SCD4X=m +CONFIG_SENSIRION_SGP40=m +CONFIG_SPS30_I2C=m +CONFIG_SENSEAIR_SUNRISE_CO2=m +CONFIG_VZ89X=m +CONFIG_IIO_SSP_SENSORS_COMMONS=m +CONFIG_IIO_SSP_SENSORHUB=m +CONFIG_AD5064=m +CONFIG_AD5360=m +CONFIG_AD5380=m +CONFIG_AD5421=m +CONFIG_AD5446=m +CONFIG_AD5449=m +CONFIG_AD5592R=m +CONFIG_AD5593R=m +CONFIG_AD5504=m +CONFIG_AD5624R_SPI=m +CONFIG_LTC2688=m +CONFIG_AD5686_SPI=m +CONFIG_AD5696_I2C=m +CONFIG_AD5755=m +CONFIG_AD5758=m +CONFIG_AD5761=m +CONFIG_AD5764=m +CONFIG_AD5766=m +CONFIG_AD5770R=m +CONFIG_AD5791=m +CONFIG_AD7303=m +CONFIG_AD8801=m +CONFIG_DPOT_DAC=m +CONFIG_DS4424=m +CONFIG_LTC2632=m +CONFIG_M62332=m +CONFIG_MAX517=m +CONFIG_MAX5821=m +CONFIG_MCP4725=m +CONFIG_MCP4922=m +CONFIG_TI_DAC082S085=m +CONFIG_TI_DAC5571=m +CONFIG_VF610_DAC=m +CONFIG_AD9523=m +CONFIG_ADF4350=m +CONFIG_ADMV1014=m +CONFIG_ADMV4420=m +CONFIG_ADRF6780=m +CONFIG_ADIS16080=m +CONFIG_ADIS16130=m +CONFIG_ADIS16136=m +CONFIG_ADIS16260=m +CONFIG_ADXRS290=m +CONFIG_ADXRS450=m +CONFIG_BMG160=m +CONFIG_HID_SENSOR_GYRO_3D=m +CONFIG_MPU3050_I2C=m +CONFIG_IIO_ST_GYRO_3AXIS=m +CONFIG_ITG3200=m +CONFIG_AFE4403=m +CONFIG_AFE4404=m +CONFIG_MAX30100=m +CONFIG_MAX30102=m +CONFIG_AM2315=m +CONFIG_DHT11=m +CONFIG_HDC100X=m +CONFIG_HDC2010=m +CONFIG_HID_SENSOR_HUMIDITY=m +CONFIG_HTS221=m +CONFIG_HTU21=m +CONFIG_SI7005=m +CONFIG_SI7020=m +CONFIG_ADIS16400=m +CONFIG_ADIS16475=m +CONFIG_BMI160_I2C=m +CONFIG_BMI160_SPI=m +CONFIG_KMX61=m +CONFIG_INV_ICM42600_I2C=m +CONFIG_INV_ICM42600_SPI=m +CONFIG_INV_MPU6050_I2C=m +CONFIG_INV_MPU6050_SPI=m +CONFIG_IIO_ST_LSM6DSX=m +CONFIG_IIO_ST_LSM9DS0=m +CONFIG_ACPI_ALS=m +CONFIG_ADJD_S311=m +CONFIG_AL3010=m +CONFIG_AL3320A=m +CONFIG_APDS9300=m +CONFIG_APDS9960=m +CONFIG_AS73211=m +CONFIG_BH1750=m +CONFIG_BH1780=m +CONFIG_CM32181=m +CONFIG_CM3232=m +CONFIG_CM3323=m +CONFIG_CM3605=m +CONFIG_CM36651=m +CONFIG_GP2AP002=m +CONFIG_GP2AP020A00F=m +CONFIG_IQS621_ALS=m +CONFIG_SENSORS_ISL29018=m +CONFIG_SENSORS_ISL29028=m +CONFIG_ISL29125=m +CONFIG_HID_SENSOR_ALS=m +CONFIG_HID_SENSOR_PROX=m +CONFIG_RPR0521=m +CONFIG_LTR501=m +CONFIG_LV0104CS=m +CONFIG_MAX44000=m +CONFIG_OPT3001=m +CONFIG_PA12203001=m +CONFIG_SI1133=m +CONFIG_SI1145=m +CONFIG_STK3310=m +CONFIG_ST_UVIS25=m +CONFIG_TCS3414=m +CONFIG_TCS3472=m +CONFIG_SENSORS_TSL2563=m +CONFIG_TSL2583=m +CONFIG_TSL2591=m +CONFIG_TSL2772=m +CONFIG_TSL4531=m +CONFIG_US5182D=m +CONFIG_VCNL4000=m +CONFIG_VEML6070=m +CONFIG_VL6180=m +CONFIG_ZOPT2201=m +CONFIG_AK8974=m +CONFIG_AK09911=m +CONFIG_BMC150_MAGN_I2C=m +CONFIG_BMC150_MAGN_SPI=m +CONFIG_MAG3110=m +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m +CONFIG_MMC35240=m +CONFIG_SENSORS_HMC5843_I2C=m +CONFIG_SENSORS_HMC5843_SPI=m +CONFIG_YAMAHA_YAS530=m +CONFIG_IIO_MUX=m +CONFIG_HID_SENSOR_INCLINOMETER_3D=m +CONFIG_HID_SENSOR_DEVICE_ROTATION=m +CONFIG_IIO_HRTIMER_TRIGGER=m +CONFIG_IIO_TIGHTLOOP_TRIGGER=m +CONFIG_IIO_SYSFS_TRIGGER=m +CONFIG_IQS624_POS=m +CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m +CONFIG_AD5110=m +CONFIG_AD5272=m +CONFIG_DS1803=m +CONFIG_MAX5481=m +CONFIG_MAX5487=m +CONFIG_MCP4018=m +CONFIG_MCP4131=m +CONFIG_MCP4531=m +CONFIG_TPL0102=m +CONFIG_LMP91000=m +CONFIG_ABP060MG=m +CONFIG_BMP280=m +CONFIG_HID_SENSOR_PRESS=m +CONFIG_HP03=m +CONFIG_ICP10100=m +CONFIG_MPL115_I2C=m +CONFIG_MPL115_SPI=m +CONFIG_MPL3115=m +CONFIG_MS5611=m +CONFIG_MS5611_I2C=m +CONFIG_MS5611_SPI=m +CONFIG_MS5637=m +CONFIG_IIO_ST_PRESS=m +CONFIG_T5403=m +CONFIG_HP206C=m +CONFIG_ZPA2326=m +CONFIG_AS3935=m +CONFIG_ISL29501=m +CONFIG_LIDAR_LITE_V2=m +CONFIG_RFD77402=m +CONFIG_SRF04=m +CONFIG_SX9310=m +CONFIG_SX9324=m +CONFIG_SX9360=m +CONFIG_SX9500=m +CONFIG_SRF08=m +CONFIG_VCNL3020=m +CONFIG_AD2S90=m +CONFIG_AD2S1200=m +CONFIG_IQS620AT_TEMP=m +CONFIG_MAXIM_THERMOCOUPLE=m +CONFIG_HID_SENSOR_TEMP=m +CONFIG_MLX90614=m +CONFIG_MLX90632=m +CONFIG_TMP006=m +CONFIG_TMP007=m +CONFIG_TMP117=m +CONFIG_TSYS01=m +CONFIG_TSYS02D=m +CONFIG_MAX31865=m +CONFIG_PWM=y +CONFIG_PWM_ATMEL_TCB=m +CONFIG_PWM_CLK=m +CONFIG_PWM_DWC=m +CONFIG_PWM_FSL_FTM=m +CONFIG_PWM_IQS620A=m +CONFIG_PWM_NTXEC=m +CONFIG_PWM_PCA9685=m +CONFIG_PWM_XILINX=m +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_TI_TPS380X=m +CONFIG_PHY_CAN_TRANSCEIVER=m +CONFIG_PHY_CADENCE_TORRENT=m +CONFIG_PHY_CADENCE_DPHY_RX=m +CONFIG_PHY_CADENCE_SALVO=m +CONFIG_PHY_MVEBU_A3700_COMPHY=m +CONFIG_PHY_MVEBU_CP110_UTMI=m +CONFIG_PHY_CPCAP_USB=m +CONFIG_PHY_MAPPHONE_MDM6600=m +CONFIG_ARM_CCI_PMU=m +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI5xx_PMU is not set +CONFIG_ARM_CMN=m +CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_DMC620_PMU=m +CONFIG_HNS3_PMU=m +CONFIG_USB4=m +CONFIG_USB4_DMA_TEST=m +CONFIG_DAX=y +CONFIG_NVMEM_RMEM=m +CONFIG_TEE=m +CONFIG_OPTEE=m +CONFIG_MUX_ADG792A=m +CONFIG_MUX_ADGS1408=m +CONFIG_MUX_GPIO=m +CONFIG_MUX_MMIO=m +CONFIG_PECI=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_XFS_FS=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_VFAT_FS=y +CONFIG_EXFAT_FS=m +CONFIG_NTFS3_FS=m +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_NTFS3_FS_POSIX_ACL=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_EFIVAR_FS=y +CONFIG_JFFS2_FS=y +CONFIG_UBIFS_FS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_NFS_V4_1_MIGRATION=y +# CONFIG_NFS_V4_2_READ_PLUS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_NFSD_SCSILAYOUT=y +CONFIG_NFSD_FLEXFILELAYOUT=y +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_CEPH_FS=m +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CIFS=m +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_SMB_SERVER=m +CONFIG_SMB_SERVER_KERBEROS5=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_9P_FS_SECURITY=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_DLM=m +CONFIG_UNICODE=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_TRUSTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=y +CONFIG_KEY_DH_OPERATIONS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_SM2=m +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_HCTR2=m +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=y +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_SM4_ARM64_CE=m +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m +CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m +CONFIG_CRYPTO_DEV_MARVELL_CESA=m +CONFIG_CRYPTO_DEV_QAT_DH895xCC=m +CONFIG_CRYPTO_DEV_QAT_C3XXX=m +CONFIG_CRYPTO_DEV_QAT_C62X=m +CONFIG_CRYPTO_DEV_QAT_4XXX=m +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m +CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m +CONFIG_CRYPTO_DEV_QAT_C62XVF=m +CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_HISI_TRNG=m +CONFIG_PRIME_NUMBERS=m +CONFIG_CRC_CCITT=y +CONFIG_DMA_CMA=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO_DWARF5=y +CONFIG_DEBUG_INFO_BTF=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_TEST_LOCKUP=m +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCF_TORTURE_TEST=m +CONFIG_RCU_SCALE_TEST=m +CONFIG_RCU_REF_SCALE_TEST=m +# CONFIG_RCU_TRACE is not set +# CONFIG_FTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_ARM64_RELOC_TEST=m +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_CPU_DEBUG=m +CONFIG_CORESIGHT_TRBE=m +CONFIG_FUNCTION_ERROR_INJECTION=y +CONFIG_TEST_DIV64=m +CONFIG_TEST_SCANF=m +CONFIG_TEST_BITOPS=m +CONFIG_TEST_FREE_PAGES=m +CONFIG_MEMTEST=y diff --git a/config/kernel/linux-odroidxu4-current.config b/config/kernel/linux-odroidxu4-current.config index 251a30dd0..a54a2193d 100644 --- a/config/kernel/linux-odroidxu4-current.config +++ b/config/kernel/linux-odroidxu4-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -490,6 +491,17 @@ CONFIG_NETLINK_DIAG=m CONFIG_CGROUP_NET_PRIO=y CONFIG_NET_DROP_MONITOR=m CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m CONFIG_CAN=m CONFIG_CAN_J1939=m CONFIG_BT=m diff --git a/config/kernel/linux-odroidxu4-edge.config b/config/kernel/linux-odroidxu4-edge.config index 51b6ec4e3..65f0e7fc0 100644 --- a/config/kernel/linux-odroidxu4-edge.config +++ b/config/kernel/linux-odroidxu4-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.15 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -493,6 +494,17 @@ CONFIG_QRTR_MHI=m CONFIG_CGROUP_NET_PRIO=y CONFIG_NET_DROP_MONITOR=m CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m CONFIG_CAN=m CONFIG_CAN_J1939=m CONFIG_CAN_ISOTP=m @@ -541,6 +553,12 @@ CONFIG_FW_CFG_SYSFS=m CONFIG_PARPORT=m CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m diff --git a/config/kernel/linux-phytium-embedded-current.config b/config/kernel/linux-phytium-embedded-current.config index 6d829ba8f..bca74e1fc 100644 --- a/config/kernel/linux-phytium-embedded-current.config +++ b/config/kernel/linux-phytium-embedded-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-phytium-embedded-legacy.config b/config/kernel/linux-phytium-embedded-legacy.config index 882952167..01995d252 100644 --- a/config/kernel/linux-phytium-embedded-legacy.config +++ b/config/kernel/linux-phytium-embedded-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 5.10 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-qcs6490-edge.config b/config/kernel/linux-qcs6490-edge.config index 63f81f9a9..57f0c1f02 100644 --- a/config/kernel/linux-qcs6490-edge.config +++ b/config/kernel/linux-qcs6490-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="radxa-qcom" CONFIG_SYSVIPC=y @@ -58,9 +59,6 @@ CONFIG_KEXEC_FILE=y CONFIG_ARCH_QCOM=y CONFIG_ARM64_ERRATUM_2441007=y CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_CLUSTER=y -CONFIG_SCHED_SMT=y CONFIG_NUMA=y CONFIG_HZ_1000=y CONFIG_PARAVIRT_TIME_ACCOUNTING=y @@ -103,7 +101,6 @@ CONFIG_ACPI_VIDEO=m CONFIG_ACPI_TAD=m CONFIG_ACPI_DOCK=y CONFIG_ACPI_IPMI=m -CONFIG_ACPI_DEBUG=y CONFIG_ACPI_PCI_SLOT=y CONFIG_ACPI_HOTPLUG_MEMORY=y CONFIG_ACPI_BGRT=y @@ -186,9 +183,6 @@ CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_XFRM_IPTFS=m -CONFIG_SMC=m -CONFIG_SMC_DIAG=m -CONFIG_SMC_LO=y CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_IP_MULTICAST=y @@ -316,18 +310,22 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_HMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m @@ -425,19 +423,9 @@ CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=y -CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -452,24 +440,14 @@ CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m @@ -623,7 +601,6 @@ CONFIG_NET_TC_SKB_EXT=y CONFIG_DCB=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VIRTIO_VSOCKETS=m @@ -1831,7 +1808,6 @@ CONFIG_RTC_DRV_HYM8563=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_ISL1208=m -CONFIG_RTC_DRV_PCF85063=m CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_PCF8563=m CONFIG_RTC_DRV_M41T80=m @@ -1841,6 +1817,7 @@ CONFIG_RTC_DRV_RV3028=m CONFIG_RTC_DRV_RV8803=m CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_PCF85063=m CONFIG_RTC_DRV_DA9063=m CONFIG_RTC_DRV_EFI=m CONFIG_RTC_DRV_PL031=y @@ -2047,7 +2024,6 @@ CONFIG_OPTEE=m CONFIG_ARM_TSTEE=m CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=y -CONFIG_SLIM_QCOM_CTRL=m CONFIG_SLIM_QCOM_NGD_CTRL=m CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_OSM_L3=y @@ -2067,10 +2043,6 @@ CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_CHECK_FS=y CONFIG_F2FS_FS_COMPRESSION=y CONFIG_F2FS_UNFAIR_RWSEM=y -CONFIG_BCACHEFS_FS=m -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_POSIX_ACL=y -CONFIG_BCACHEFS_LOCK_TIME_STATS=y CONFIG_ZONEFS_FS=m CONFIG_FS_DAX=y CONFIG_FS_ENCRYPTION=y @@ -2261,7 +2233,6 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_ECDSA=y CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m @@ -2297,8 +2268,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m # CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set CONFIG_CRYPTO_NHPOLY1305_NEON=y CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA512_ARM64_CE=m CONFIG_CRYPTO_SHA3_ARM64=m CONFIG_CRYPTO_SM3_NEON=y CONFIG_CRYPTO_SM3_ARM64_CE=m diff --git a/config/kernel/linux-rk322x-edge.config b/config/kernel/linux-rk322x-edge.config index 399b4c16d..b9977d706 100644 --- a/config/kernel/linux-rk322x-edge.config +++ b/config/kernel/linux-rk322x-edge.config @@ -2435,7 +2435,9 @@ CONFIG_ATH10K_USB=m # CONFIG_ATH10K_TRACING is not set CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set -# CONFIG_ATH11K is not set +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_WLAN_VENDOR_ATMEL=y CONFIG_AT76C50X_USB=m CONFIG_WLAN_VENDOR_BROADCOM=y diff --git a/config/kernel/linux-rk35xx-vendor.config b/config/kernel/linux-rk35xx-vendor.config index d7560f96b..5fa5e7f1a 100644 --- a/config/kernel/linux-rk35xx-vendor.config +++ b/config/kernel/linux-rk35xx-vendor.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.1 CONFIG_WERROR=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y @@ -424,6 +425,7 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y +CONFIG_NET_DSA=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y @@ -501,7 +503,6 @@ CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VIRTIO_VSOCKETS=m CONFIG_HSR=m -CONFIG_NET_SWITCHDEV=y CONFIG_QRTR_TUN=m CONFIG_NET_NCSI=y CONFIG_NCSI_OEM_CMD_GET_MAC=y @@ -641,7 +642,7 @@ CONFIG_TARGET_CORE=m CONFIG_ISCSI_TARGET=m CONFIG_NETDEVICES=y CONFIG_BONDING=m -CONFIG_DUMMY=m +CONFIG_DUMMY=y CONFIG_WIREGUARD=m CONFIG_EQUALIZER=m CONFIG_IFB=m @@ -660,6 +661,9 @@ CONFIG_NET_VRF=m CONFIG_ARCNET=m CONFIG_CAIF_DRIVERS=y CONFIG_CAIF_VIRTIO=m +CONFIG_NET_DSA_REALTEK=m +CONFIG_NET_DSA_REALTEK_RTL8365MB=m +CONFIG_NET_DSA_REALTEK_RTL8366RB=m # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set # CONFIG_NET_VENDOR_AGERE is not set @@ -2597,7 +2601,7 @@ CONFIG_PHY_ROCKCHIP_USBDP=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDERFS=y CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" -CONFIG_NVMEM_ROCKCHIP_OTP=m +CONFIG_NVMEM_ROCKCHIP_OTP=y CONFIG_NVMEM_U_BOOT_ENV=y CONFIG_TEE=y CONFIG_OPTEE=y diff --git a/config/kernel/linux-rockchip-current.config b/config/kernel/linux-rockchip-current.config index f0a350427..f6d4612df 100644 --- a/config/kernel/linux-rockchip-current.config +++ b/config/kernel/linux-rockchip-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="localhost" CONFIG_SYSVIPC=y @@ -535,6 +536,12 @@ CONFIG_GNSS=m CONFIG_GNSS_SIRF_SERIAL=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y diff --git a/config/kernel/linux-rockchip-edge.config b/config/kernel/linux-rockchip-edge.config index ef4392595..0c9ca19df 100644 --- a/config/kernel/linux-rockchip-edge.config +++ b/config/kernel/linux-rockchip-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.17 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="localhost" CONFIG_SYSVIPC=y @@ -519,8 +520,11 @@ CONFIG_GNSS=m CONFIG_GNSS_SIRF_SERIAL=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_DEF_COMP_ZSTD=y CONFIG_ZRAM_WRITEBACK=y diff --git a/config/kernel/linux-rockchip-rk3588-edge.config b/config/kernel/linux-rockchip-rk3588-edge.config index c9b5b23d5..6ed30fb8b 100644 --- a/config/kernel/linux-rockchip-rk3588-edge.config +++ b/config/kernel/linux-rockchip-rk3588-edge.config @@ -3720,7 +3720,7 @@ CONFIG_ATH11K_AHB=m # CONFIG_ATH11K_PCI is not set # CONFIG_ATH11K_DEBUG is not set # CONFIG_ATH11K_TRACING is not set -# CONFIG_ATH12K is not set +CONFIG_ATH12K=m CONFIG_WLAN_VENDOR_ATMEL=y CONFIG_AT76C50X_USB=m CONFIG_WLAN_VENDOR_BROADCOM=y diff --git a/config/kernel/linux-rockchip-rv1106-vendor.config b/config/kernel/linux-rockchip-rv1106-vendor.config new file mode 100644 index 000000000..370370fe9 --- /dev/null +++ b/config/kernel/linux-rockchip-rv1106-vendor.config @@ -0,0 +1,489 @@ +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_KERNEL_XZ is not set +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_RD_GZIP=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_BUG is not set +# CONFIG_BASE_FULL is not set +# CONFIG_IO_URING is not set +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_VDSO is not set +CONFIG_VMSPLIT_3G_OPT=y +CONFIG_THUMB2_KERNEL=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set +CONFIG_FORCE_MAX_ZONEORDER=9 +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_CMDLINE="user_debug=31" +CONFIG_CMDLINE_EXTEND=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_SUSPEND is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STACKPROTECTOR_STRONG is not set +# CONFIG_STRICT_KERNEL_RWX is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_EFI_PARTITION=y +CONFIG_CMDLINE_PARTITION=y +# CONFIG_MQ_IOSCHED_KYBER is not set +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CMA is not set +# CONFIG_CMA_INACTIVE is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_INET_TABLE_PERTURB_ORDER=8 +# CONFIG_INET_DIAG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_SIT is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_OF_PARTS is not set +CONFIG_MTD_BLOCK=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_SPI_NOR_MISC=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BLOCK=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_DTBO=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_UFSHCD=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_6LOWPAN=m +CONFIG_BT_LEDS=y +CONFIG_BT_MSFTEXT=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_RTL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_ATH3K=m +CONFIG_BT_HCIBTUSB_RTLBTUSB=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_RK=y +CONFIG_NETDEVICES=y +# CONFIG_NET_CORE is not set +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_AURORA is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CADENCE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MICROSEMI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NI is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +CONFIG_STMMAC_ETH=y +# CONFIG_DWMAC_GENERIC is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_RK630_PHY=y +CONFIG_USB_NET_DRIVERS=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_WLAN_VENDOR_INTERSIL is not set +# CONFIG_WLAN_VENDOR_MICROCHIP is not set +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +CONFIG_WL_ROCKCHIP=m +CONFIG_WIFI_BUILD_MODULE=y +# CONFIG_ATH5K is not set +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m +# CONFIG_WIL6210 is not set +CONFIG_ATH10K=m +# CONFIG_ATH10K_PCI is not set +# CONFIG_ATH10K_AHB is not set +# CONFIG_ATH10K_SDIO is not set +CONFIG_ATH10K_USB=m +# CONFIG_WCN36XX is not set +# CONFIG_ATH11K is not set +# CONFIG_ATH11K_PCI is not set +CONFIG_AT76C50X_USB=m +CONFIG_MWIFIEX=m +# CONFIG_MWIFIEX_SDIO is not set +CONFIG_MWIFIEX_USB=m +CONFIG_MT7601U=m +CONFIG_MT76x0U=m +# CONFIG_MT76x0E is not set +# CONFIG_MT76x2E is not set +CONFIG_MT76x2U=m +# CONFIG_MT7603E is not set +# CONFIG_MT7615E is not set +CONFIG_MT7663U=m +# CONFIG_MT7663S is not set +# CONFIG_MT7915E is not set +# CONFIG_MT7921E is not set +# CONFIG_MT7921S is not set +CONFIG_MT7921U=m +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_RT2X00=m +# CONFIG_RT2800PCI is not set +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +# CONFIG_RTL8180 is not set +CONFIG_RTL8187=m +CONFIG_RTL_CARDS=m +# CONFIG_RTL8723BE is not set +# CONFIG_RTL8192EE is not set +CONFIG_RTL8192CU=m +CONFIG_RTL8XXXU=m +CONFIG_RTW88=m +# CONFIG_RTW88_8822BE is not set +# CONFIG_RTW88_8822BS is not set +CONFIG_RTW88_8822BU=m +# CONFIG_RTW88_8822CE is not set +# CONFIG_RTW88_8822CS is not set +CONFIG_RTW88_8822CU=m +# CONFIG_RTW88_8723DE is not set +# CONFIG_RTW88_8723DS is not set +CONFIG_RTW88_8723DU=m +# CONFIG_RTW88_8821CE is not set +# CONFIG_RTW88_8821CS is not set +CONFIG_RTW88_8821CU=m +# CONFIG_RTW89 is not set +# CONFIG_RTW89_8852AE is not set +# CONFIG_RTW89_8852BE is not set +# CONFIG_RTW89_8852CE is not set +# CONFIG_RTL8852BS is not set +# CONFIG_RTL8723DS is not set +CONFIG_RTL8822BU=m +CONFIG_RTL8821CU=m +CONFIG_88XXAU=m +CONFIG_RTL8192EU=m +# CONFIG_RTL8189ES is not set +CONFIG_AIC_WLAN_SUPPORT=y +# CONFIG_BCMDHD is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_NR_UARTS=6 +CONFIG_SERIAL_8250_RUNTIME_UARTS=6 +CONFIG_SERIAL_8250_DW=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_ROCKCHIP=y +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_RK3X=y +CONFIG_SPI=y +CONFIG_SPI_ROCKCHIP=y +CONFIG_SPI_ROCKCHIP_SFC=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SLAVE=y +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_RESTART=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_ROCKCHIP_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_PWM=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_MEDIA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_TEST_SUPPORT is not set +# CONFIG_MEDIA_USB_SUPPORT is not set +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_VIDEOBUF2_CMA_SG is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +# CONFIG_VIDEO_ROCKCHIP_CIF is not set +# CONFIG_VIDEO_ROCKCHIP_ISP is not set +# CONFIG_VIDEO_RK_IRCUT is not set +# CONFIG_VIDEO_MIS5001 is not set +# CONFIG_VIDEO_SC3336 is not set +# CONFIG_DRM is not set +# CONFIG_DRM_EDID is not set +# CONFIG_DRM_ROCKCHIP is not set +# CONFIG_ROCKCHIP_VOP is not set +# CONFIG_ROCKCHIP_RGB is not set +# CONFIG_DRM_PANEL_SIMPLE is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_BACKLIGHT_PWM is not set +# CONFIG_ROCKCHIP_MULTI_RGA is not set +# CONFIG_ROCKCHIP_RGA_PROC_FS is not set +# CONFIG_ROCKCHIP_RGA_DEBUG_FS is not set +# CONFIG_ROCKCHIP_RVE is not set +# CONFIG_ROCKCHIP_RVE_PROC_FS is not set +# CONFIG_ROCKCHIP_DVBM is not set +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_PCM_TIMER is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y +CONFIG_SND_SOC_RV1106=y +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_HID is not set +# CONFIG_USB_HID is not set +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CH343=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_HID=y +# CONFIG_USB_CONFIGFS_F_UVC is not set +CONFIG_USB_GADGETFS=y +CONFIG_USB_MASS_STORAGE=y +CONFIG_USB_HUB=y +CONFIG_MMC=y +# CONFIG_PWRSEQ_EMMC is not set +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_QUEUE_DEPTH=1 +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_ACTIVITY=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ROCKCHIP=y +CONFIG_DMADEVICES=y +CONFIG_PL330_DMA=y +# CONFIG_DMABUF_HEAPS_ROCKCHIP is not set +# CONFIG_DMABUF_HEAPS_ROCKCHIP_CMA_HEAP is not set +# CONFIG_DMABUF_HEAPS_ROCKCHIP_CMA_ALIGNMENT is not set +# CONFIG_DMABUF_RK_HEAPS_DEBUG is not set +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VHOST_MENU is not set +CONFIG_STAGING=y +CONFIG_RTL8723BS=m +# CONFIG_FB_TFT is not set +# CONFIG_FB_TFT_ST7735R is not set +# CONFIG_FB_TFT_ST7789V is not set +CONFIG_COMMON_CLK_PROCFS=y +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_CPU_RV1106=y +CONFIG_ROCKCHIP_AMP=y +CONFIG_ROCKCHIP_CPUINFO=y +CONFIG_ROCKCHIP_IOMUX=y +CONFIG_ROCKCHIP_OPP=y +CONFIG_ROCKCHIP_PVTM=y +CONFIG_ROCKCHIP_SYSTEM_MONITOR=y +CONFIG_ROCKCHIP_VENDOR_STORAGE=y +CONFIG_FIQ_DEBUGGER=y +CONFIG_FIQ_DEBUGGER_NO_SLEEP=y +CONFIG_FIQ_DEBUGGER_CONSOLE=y +CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y +CONFIG_RK_CONSOLE_THREAD=y +CONFIG_ROCKCHIP_NPOR_POWERGOOD=y +# CONFIG_RK_CMA_PROCFS is not set +# CONFIG_RK_DMABUF_PROCFS is not set +CONFIG_RK_MEMBLOCK_PROCFS=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_EXTCON=y +CONFIG_IIO=y +CONFIG_ROCKCHIP_SARADC=y +CONFIG_PWM=y +CONFIG_PWM_ROCKCHIP=y +# CONFIG_PHY_ROCKCHIP_CSI2_DPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_MIPI_RX is not set +# CONFIG_ANDROID is not set +CONFIG_ROCKCHIP_OTP=y +CONFIG_ROCKCHIP_RKNPU=m +# CONFIG_ROCKCHIP_RKNPU_DEBUG_FS is not set +CONFIG_ROCKCHIP_RKNPU_PROC_FS=y +CONFIG_ROCKCHIP_RKNPU_DMA_HEAP=y +CONFIG_EXT4_FS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +# CONFIG_DNOTIFY is not set +CONFIG_VFAT_FS=y +CONFIG_EXFAT_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +# CONFIG_JFFS2_RTIME is not set +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_UBIFS_FS_ZSTD is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_ZSTD=y +# CONFIG_CRYPTO_HW is not set +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_DMA_CMA is not set +# CONFIG_CMA_SIZE_MBYTES is not set +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_MISC is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_BLK_CGROUP=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_ROCKCHIP=y +CONFIG_STMMAC_ETHTOOL=y +CONFIG_PHYLIB=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_BUS=y +CONFIG_ROCKCHIP_PHY=y +CONFIG_FIXED_PHY=y +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_ROCKCHIP_OTP=y +CONFIG_NVMEM_ROCKCHIP_EFUSE=y +# CONFIG_NVMEM_ROCKCHIP_SEC_OTP is not set +# CONFIG_ROCKCHIP_SECURE_OTP is not set +CONFIG_SWAP=y +CONFIG_ZSWAP=y +CONFIG_ZSWAP_DEFAULT_ON=y +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd" diff --git a/config/kernel/linux-rockchip-vendor.config b/config/kernel/linux-rockchip-vendor.config index 5d07b6b67..088163ecf 100644 --- a/config/kernel/linux-rockchip-vendor.config +++ b/config/kernel/linux-rockchip-vendor.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.1 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_LZ4=y CONFIG_DEFAULT_HOSTNAME="localhost" diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index 740c74510..e786c9a64 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -668,6 +669,12 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_HYPERBUS=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y @@ -1030,6 +1037,7 @@ CONFIG_ATH10K_SDIO=m CONFIG_ATH10K_USB=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43LEGACY=m @@ -3141,7 +3149,7 @@ CONFIG_DAX=y CONFIG_DEV_DAX=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m -CONFIG_NVMEM_ROCKCHIP_OTP=m +CONFIG_NVMEM_ROCKCHIP_OTP=y CONFIG_NVMEM_SPMI_SDAM=m CONFIG_NVMEM_U_BOOT_ENV=m CONFIG_MUX_ADG792A=m diff --git a/config/kernel/linux-rockchip64-edge.config b/config/kernel/linux-rockchip64-edge.config index 3e0dc3864..420329037 100644 --- a/config/kernel/linux-rockchip64-edge.config +++ b/config/kernel/linux-rockchip64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -6,6 +7,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y +CONFIG_BPF_JIT_ALWAYS_ON=y # CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set CONFIG_BPF_LSM=y CONFIG_PREEMPT=y @@ -24,6 +26,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=18 CONFIG_NUMA_BALANCING=y +CONFIG_CGROUP_FAVOR_DYNMODS=y CONFIG_MEMCG=y CONFIG_BLK_CGROUP=y CONFIG_CFS_BANDWIDTH=y @@ -55,9 +58,6 @@ CONFIG_ARM64_ERRATUM_1542419=y CONFIG_ARM64_ERRATUM_2441009=y # CONFIG_ARM64_ERRATUM_2645198 is not set CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_CLUSTER=y -CONFIG_SCHED_SMT=y CONFIG_NR_CPUS=256 CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 @@ -92,6 +92,7 @@ CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y +CONFIG_BLK_CGROUP_IOCOST=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y @@ -415,7 +416,7 @@ CONFIG_NET_DSA_TAG_OCELOT=m CONFIG_NET_DSA_TAG_OCELOT_8021Q=m CONFIG_NET_DSA_TAG_RTL4_A=m CONFIG_NET_DSA_TAG_RTL8_4=m -CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m @@ -504,7 +505,6 @@ CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m @@ -514,8 +514,10 @@ CONFIG_NETLINK_DIAG=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_HSR=m +CONFIG_QRTR_MHI=m CONFIG_QRTR_TUN=m CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y CONFIG_NET_PKTGEN=m CONFIG_NET_DROP_MONITOR=m CONFIG_HAMRADIO=y @@ -648,6 +650,12 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_HYPERBUS=m CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_ZRAM_MULTI_COMP=y @@ -1009,6 +1017,7 @@ CONFIG_ATH10K_SDIO=m CONFIG_ATH10K_USB=m CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43LEGACY=m @@ -1891,7 +1900,6 @@ CONFIG_RADIO_SHARK2=m CONFIG_RADIO_SI4713=m CONFIG_RADIO_TEA5764=m CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -1945,7 +1953,6 @@ CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV7670=m CONFIG_VIDEO_OV772X=m @@ -2108,6 +2115,8 @@ CONFIG_BACKLIGHT_RAVE_SP=m CONFIG_BACKLIGHT_LED=m CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y +CONFIG_DRM_ACCEL=y +CONFIG_DRM_ACCEL_ROCKET=m CONFIG_SOUND=y CONFIG_SND=y # CONFIG_SND_SUPPORT_OLD_API is not set @@ -2189,6 +2198,7 @@ CONFIG_SND_SOC_DA7213=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8323=y CONFIG_SND_SOC_ES8326=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_MAX9867=m @@ -2400,6 +2410,7 @@ CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_ALPS=m CONFIG_HID_MCP2221=m +CONFIG_HID_BPF=y CONFIG_I2C_HID_OF=m CONFIG_I2C_HID_OF_GOODIX=m CONFIG_HID_PID=y @@ -2710,8 +2721,8 @@ CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_NTXEC=m CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_CADENCE=m -CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y CONFIG_ALTERA_MSGDMA=m CONFIG_BCM_SBA_RAID=m @@ -2823,7 +2834,6 @@ CONFIG_ROCKCHIP_IOMMU=y CONFIG_VIRTIO_IOMMU=m CONFIG_LITEX_SOC_CONTROLLER=m CONFIG_ROCKCHIP_IODOMAIN=y -CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_DEVFREQ_GOV_PERFORMANCE=m CONFIG_DEVFREQ_GOV_POWERSAVE=m CONFIG_DEVFREQ_GOV_USERSPACE=m @@ -3100,7 +3110,7 @@ CONFIG_DAX=y CONFIG_DEV_DAX=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m -CONFIG_NVMEM_ROCKCHIP_OTP=m +CONFIG_NVMEM_ROCKCHIP_OTP=y CONFIG_NVMEM_SPMI_SDAM=m CONFIG_NVMEM_U_BOOT_ENV=m CONFIG_MUX_ADG792A=m @@ -3116,16 +3126,15 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_KUNIT_TESTS=m CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y CONFIG_JFS_STATISTICS=y CONFIG_XFS_FS=m -# CONFIG_XFS_SUPPORT_ASCII_CI is not set CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_GFS2_FS=m @@ -3138,10 +3147,6 @@ CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_CHECK_FS=y CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_BCACHEFS_FS=m -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_ERASURE_CODING=y -CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_ZONEFS_FS=m CONFIG_FS_ENCRYPTION=y CONFIG_FS_VERITY=y @@ -3155,7 +3160,7 @@ CONFIG_AUTOFS_FS=m CONFIG_FUSE_FS=y CONFIG_CUSE=m CONFIG_VIRTIO_FS=m -CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS=m CONFIG_OVERLAY_FS_XINO_AUTO=y CONFIG_FSCACHE_STATS=y CONFIG_ISO9660_FS=m @@ -3335,7 +3340,6 @@ CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m @@ -3355,8 +3359,6 @@ CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_AEGIS128=m CONFIG_CRYPTO_CHACHA20POLY1305=y CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_MD4=m @@ -3425,7 +3427,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_TEST_LOCKUP=m CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED is not set +CONFIG_FUNCTION_TRACER=y CONFIG_FTRACE_SYSCALLS=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_KUNIT=m diff --git a/config/kernel/linux-sm8250-current.config b/config/kernel/linux-sm8250-current.config index 4c3598373..a7be0730c 100644 --- a/config/kernel/linux-sm8250-current.config +++ b/config/kernel/linux-sm8250-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -276,6 +277,7 @@ CONFIG_NET_ACT_GATE=m CONFIG_QRTR_SMD=m CONFIG_QRTR_TUN=m CONFIG_CGROUP_NET_PRIO=y +CONFIG_CAN=m CONFIG_BT=m CONFIG_BT_HIDP=m # CONFIG_BT_DEBUGFS is not set @@ -333,6 +335,12 @@ CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_QCOM=y CONFIG_MTD_SPI_NOR=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -468,22 +476,55 @@ CONFIG_R8169=m CONFIG_QCOM_IPA=m CONFIG_PHYLIB=y CONFIG_AQUANTIA_PHY=y -CONFIG_MICROCHIP_PHY=m CONFIG_AT803X_PHY=y CONFIG_VITESSE_PHY=y +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_F81604=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_THUNDER=y CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m CONFIG_USB_NET_SR9800=m CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m # CONFIG_WLAN_VENDOR_ADMTEK is not set CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m @@ -712,7 +753,6 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_ACM=m CONFIG_USB_STORAGE=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_DWC3=y diff --git a/config/kernel/linux-sm8250-edge.config b/config/kernel/linux-sm8250-edge.config index 990c61acf..0e31102c3 100644 --- a/config/kernel/linux-sm8250-edge.config +++ b/config/kernel/linux-sm8250-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.14 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -337,6 +338,12 @@ CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_QCOM=y CONFIG_MTD_SPI_NOR=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -497,6 +504,7 @@ CONFIG_USB_NET_CH9200=m # CONFIG_WLAN_VENDOR_ADMTEK is not set CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set # CONFIG_WLAN_VENDOR_BROADCOM is not set # CONFIG_WLAN_VENDOR_INTEL is not set diff --git a/config/kernel/linux-sm8550-current.config b/config/kernel/linux-sm8550-current.config index c86b70132..9d27d85d3 100644 --- a/config/kernel/linux-sm8550-current.config +++ b/config/kernel/linux-sm8550-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="@DEVICENAME@" CONFIG_SYSVIPC=y @@ -350,6 +351,8 @@ CONFIG_ZRAM=m CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y diff --git a/config/kernel/linux-sm8550-edge.config b/config/kernel/linux-sm8550-edge.config index f9f3a924b..b87e1b494 100644 --- a/config/kernel/linux-sm8550-edge.config +++ b/config/kernel/linux-sm8550-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="@DEVICENAME@" CONFIG_SYSVIPC=y @@ -351,6 +352,8 @@ CONFIG_ZRAM=m CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y diff --git a/config/kernel/linux-spacemit-current.config b/config/kernel/linux-spacemit-current.config index 4def99df8..e258becc3 100644 --- a/config/kernel/linux-spacemit-current.config +++ b/config/kernel/linux-spacemit-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="" CONFIG_SYSVIPC=y diff --git a/config/kernel/linux-spacemit-edge.config b/config/kernel/linux-spacemit-edge.config index 97f118c6d..30b5d7540 100644 --- a/config/kernel/linux-spacemit-edge.config +++ b/config/kernel/linux-spacemit-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.17 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="" CONFIG_SYSVIPC=y @@ -169,18 +170,22 @@ CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_HMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -275,19 +280,9 @@ CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m -CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -302,24 +297,14 @@ CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m @@ -501,7 +486,6 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_EXTRA_FIRMWARE="esos.elf" CONFIG_EXTRA_FIRMWARE_DIR="firmware" CONFIG_MOXTET=m -CONFIG_MHI_BUS=m CONFIG_MHI_BUS_PCI_GENERIC=m CONFIG_MHI_BUS_EP=m CONFIG_CONNECTOR=y @@ -521,6 +505,7 @@ CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y @@ -699,7 +684,14 @@ CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_USB_RTL8152=m # CONFIG_WLAN_VENDOR_ADMTEK is not set -# CONFIG_WLAN_VENDOR_ATH is not set +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_AHB=y +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set # CONFIG_WLAN_VENDOR_BROADCOM is not set # CONFIG_WLAN_VENDOR_INTEL is not set @@ -1010,7 +1002,6 @@ CONFIG_SPACEMIT_HDMI=y # CONFIG_DRM_LT9711 is not set CONFIG_FB=y CONFIG_FB_SIMPLE=m -CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_GPIO=y diff --git a/config/kernel/linux-starfive-edge.config b/config/kernel/linux-starfive-edge.config index cd8f4ce6d..29c753896 100644 --- a/config/kernel/linux-starfive-edge.config +++ b/config/kernel/linux-starfive-edge.config @@ -1219,6 +1219,7 @@ CONFIG_ATH11K=m CONFIG_ATH11K_AHB=m CONFIG_ATH11K_PCI=m CONFIG_ATH11K_DEBUGFS=y +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set CONFIG_B43=m CONFIG_B43_SDIO=y diff --git a/config/kernel/linux-starfive2-vendor.config b/config/kernel/linux-starfive2-vendor.config index d7d1588fc..ce62d2dcb 100644 --- a/config/kernel/linux-starfive2-vendor.config +++ b/config/kernel/linux-starfive2-vendor.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 CONFIG_COMPILE_TEST=y # CONFIG_WERROR is not set CONFIG_DEFAULT_HOSTNAME="StarFive" diff --git a/config/kernel/linux-sun55iw3-syterkit-legacy.config b/config/kernel/linux-sun55iw3-syterkit-legacy.config index d1c0bf06e..7eed306f0 100644 --- a/config/kernel/linux-sun55iw3-syterkit-legacy.config +++ b/config/kernel/linux-sun55iw3-syterkit-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 5.15 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-sunxi-current.config b/config/kernel/linux-sunxi-current.config index 7b128a99b..752f2a1c5 100644 --- a/config/kernel/linux-sunxi-current.config +++ b/config/kernel/linux-sunxi-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -582,6 +583,12 @@ CONFIG_OF_OVERLAY=y CONFIG_OF_CONFIGFS=y CONFIG_PARPORT=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -2269,7 +2276,6 @@ CONFIG_TYPEC_MUX_PI3USB30532=m CONFIG_TYPEC_DP_ALTMODE=m CONFIG_TYPEC_NVIDIA_ALTMODE=m CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SD8787=m CONFIG_PWRSEQ_SIMPLE=m CONFIG_SDIO_UART=m diff --git a/config/kernel/linux-sunxi-edge.config b/config/kernel/linux-sunxi-edge.config index c2ecfd4af..a21b066c2 100644 --- a/config/kernel/linux-sunxi-edge.config +++ b/config/kernel/linux-sunxi-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.16 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -580,6 +581,12 @@ CONFIG_OF_OVERLAY=y CONFIG_OF_CONFIGFS=y CONFIG_PARPORT=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -2258,7 +2265,6 @@ CONFIG_TYPEC_MUX_PI3USB30532=m CONFIG_TYPEC_DP_ALTMODE=m CONFIG_TYPEC_NVIDIA_ALTMODE=m CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SD8787=m CONFIG_PWRSEQ_SIMPLE=m CONFIG_SDIO_UART=m diff --git a/config/kernel/linux-sunxi-legacy.config b/config/kernel/linux-sunxi-legacy.config index e2d513182..d9131811d 100644 --- a/config/kernel/linux-sunxi-legacy.config +++ b/config/kernel/linux-sunxi-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -2281,7 +2282,6 @@ CONFIG_TYPEC_MUX_PI3USB30532=m CONFIG_TYPEC_DP_ALTMODE=m CONFIG_TYPEC_NVIDIA_ALTMODE=m CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SD8787=m CONFIG_PWRSEQ_SIMPLE=m CONFIG_SDIO_UART=m diff --git a/config/kernel/linux-sunxi64-current.config b/config/kernel/linux-sunxi64-current.config index be8f50ce5..8cf6a35d8 100644 --- a/config/kernel/linux-sunxi64-current.config +++ b/config/kernel/linux-sunxi64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -629,6 +630,12 @@ CONFIG_MTD_SPI_NOR=y CONFIG_OF_OVERLAY=y CONFIG_OF_CONFIGFS=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y diff --git a/config/kernel/linux-sunxi64-edge.config b/config/kernel/linux-sunxi64-edge.config index 583a7b642..eaf9a6de2 100644 --- a/config/kernel/linux-sunxi64-edge.config +++ b/config/kernel/linux-sunxi64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.16 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -596,7 +597,6 @@ CONFIG_UEVENT_HELPER=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MHI_BUS=m CONFIG_MHI_BUS_EP=m CONFIG_CONNECTOR=y CONFIG_ARM_SCMI_PROTOCOL=m @@ -625,6 +625,7 @@ CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y @@ -837,6 +838,7 @@ CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m CONFIG_ATH9K=m CONFIG_ATH9K_HTC=m CONFIG_ATH9K_HWRNG=y @@ -845,6 +847,9 @@ CONFIG_CARL9170_HWRNG=y CONFIG_AR5523=m CONFIG_ATH10K=m CONFIG_ATH10K_USB=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set CONFIG_B43=m CONFIG_B43_SDIO=y @@ -856,10 +861,20 @@ CONFIG_BRCMFMAC=m # CONFIG_WLAN_VENDOR_MARVELL is not set CONFIG_MT7601U=m CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2E=m CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615E=m CONFIG_MT7663U=m +CONFIG_MT7663S=m +CONFIG_MT7915E=m +CONFIG_MT7921E=m CONFIG_MT7921S=m CONFIG_MT7921U=m +CONFIG_MT7996E=m +CONFIG_MT7925E=m +CONFIG_MT7925U=m CONFIG_PLFXLC=m CONFIG_RT2X00=m CONFIG_RT2500USB=m @@ -869,30 +884,67 @@ CONFIG_RT2800USB_RT3573=y CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_RT55XX=y CONFIG_RTL8187=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m CONFIG_RTL8192CU=m +CONFIG_RTL8192DU=m # CONFIG_RTLWIFI_DEBUG is not set CONFIG_RTL8XXXU=m +CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTW88=m CONFIG_RTW88_8822BS=m CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CE=m CONFIG_RTW88_8822CS=m CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DE=m CONFIG_RTW88_8723DS=m CONFIG_RTW88_8723CS=m CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CE=m CONFIG_RTW88_8821CS=m CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m +CONFIG_RTW88_8814AE=m +CONFIG_RTW88_8814AU=m CONFIG_RTW88_DEBUGFS=y +CONFIG_RTW89=m +CONFIG_RTW89_8851BE=m +CONFIG_RTW89_8852AE=m +CONFIG_RTW89_8852BE=m +CONFIG_RTW89_8852BTE=m +CONFIG_RTW89_8852CE=m +CONFIG_RTW89_8922AE=m # CONFIG_WLAN_VENDOR_RSI is not set CONFIG_WFX=m # CONFIG_WLAN_VENDOR_ST is not set # CONFIG_WLAN_VENDOR_TI is not set +CONFIG_RTL8723DS=m +CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m +CONFIG_XRADIO=m CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m # CONFIG_WLAN_VENDOR_ZYDAS is not set +CONFIG_SPARD_WLAN_SUPPORT=y +CONFIG_SC23XX=y +CONFIG_UMW2653=m +CONFIG_SC2342_INTEG=m +CONFIG_SC2355=m +CONFIG_SC2366=m +CONFIG_WCN_BSP_DRIVER_BUILDIN=y +CONFIG_WLAN_UWE5621=m +CONFIG_WLAN_UWE5622=m +CONFIG_UNISOC_WIFI_PS=y CONFIG_VIRT_WIFI=m CONFIG_WWAN=m CONFIG_WWAN_HWSIM=m diff --git a/config/kernel/linux-sunxi64-legacy.config b/config/kernel/linux-sunxi64-legacy.config index 8842217f3..53427f775 100644 --- a/config/kernel/linux-sunxi64-legacy.config +++ b/config/kernel/linux-sunxi64-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-thead-edge.config b/config/kernel/linux-thead-edge.config index 72a5c0b6c..912e259d6 100644 --- a/config/kernel/linux-thead-edge.config +++ b/config/kernel/linux-thead-edge.config @@ -2604,6 +2604,7 @@ CONFIG_ATH10K_USB=m CONFIG_ATH10K_DEBUGFS=y # CONFIG_ATH10K_SPECTRAL is not set # CONFIG_ATH10K_TRACING is not set +CONFIG_ATH12K=m CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set # CONFIG_WLAN_VENDOR_ATMEL is not set diff --git a/config/kernel/linux-tqma-current.config b/config/kernel/linux-tqma-current.config index d365f3f18..8fed2ef25 100644 --- a/config/kernel/linux-tqma-current.config +++ b/config/kernel/linux-tqma-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -361,6 +362,12 @@ CONFIG_MTD_NAND_BRCMNAND=m CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_SPI_NOR=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y diff --git a/config/kernel/linux-uefi-arm64-cloud.config b/config/kernel/linux-uefi-arm64-cloud.config index b43b0c363..0da92a55a 100644 --- a/config/kernel/linux-uefi-arm64-cloud.config +++ b/config/kernel/linux-uefi-arm64-cloud.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -245,6 +246,12 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_VIRTIO_BLK=y @@ -264,7 +271,7 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_MIRROR=y CONFIG_DM_ZERO=y CONFIG_NETDEVICES=y -CONFIG_DUMMY=m +CONFIG_DUMMY=y CONFIG_WIREGUARD=m CONFIG_MACVLAN=m CONFIG_IPVLAN=m diff --git a/config/kernel/linux-uefi-arm64-current.config b/config/kernel/linux-uefi-arm64-current.config index e1ef93da3..788b3f179 100644 --- a/config/kernel/linux-uefi-arm64-current.config +++ b/config/kernel/linux-uefi-arm64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -922,6 +923,12 @@ CONFIG_PARPORT_1284=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y diff --git a/config/kernel/linux-uefi-arm64-edge.config b/config/kernel/linux-uefi-arm64-edge.config index afb96a79a..4f3fbecb5 100644 --- a/config/kernel/linux-uefi-arm64-edge.config +++ b/config/kernel/linux-uefi-arm64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -52,13 +53,13 @@ CONFIG_ARCH_SUNXI=y CONFIG_ARCH_APPLE=y CONFIG_ARCH_BERLIN=y CONFIG_ARCH_BITMAIN=y -CONFIG_ARCH_SPARX5=y CONFIG_ARCH_K3=y CONFIG_ARCH_LG1K=y CONFIG_ARCH_HISI=y CONFIG_ARCH_KEEMBAY=y CONFIG_ARCH_MEDIATEK=y CONFIG_ARCH_MESON=y +CONFIG_ARCH_SPARX5=y CONFIG_ARCH_MVEBU=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_REALTEK=y @@ -81,8 +82,6 @@ CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1542419=y CONFIG_ARM64_ERRATUM_2441009=y CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y CONFIG_NR_CPUS=256 CONFIG_NUMA=y CONFIG_NODES_SHIFT=6 @@ -199,8 +198,6 @@ CONFIG_XFRM_USER=m CONFIG_XFRM_INTERFACE=m CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=m -CONFIG_SMC=m -CONFIG_SMC_DIAG=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_IP_MULTICAST=y @@ -584,7 +581,6 @@ CONFIG_NET_TC_SKB_EXT=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m # CONFIG_BATMAN_ADV_BATMAN_V is not set -CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m @@ -898,6 +894,12 @@ CONFIG_PARPORT_1284=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -920,7 +922,6 @@ CONFIG_NVME_FC=m CONFIG_NVME_TCP=m CONFIG_NVME_TCP_TLS=y CONFIG_NVME_HOST_AUTH=y -CONFIG_NVME_APPLE=m CONFIG_NVME_TARGET=m CONFIG_NVME_TARGET_PASSTHRU=y CONFIG_NVME_TARGET_LOOP=m @@ -1512,7 +1513,6 @@ CONFIG_DP83867_PHY=m CONFIG_DP83869_PHY=m CONFIG_DP83TD510_PHY=m CONFIG_XILINX_GMII2RGMII=m -CONFIG_MICREL_KS8995MA=m CONFIG_CAN_VCAN=m CONFIG_CAN_VXCAN=m CONFIG_CAN_CAN327=m @@ -1658,6 +1658,7 @@ CONFIG_ATH11K_PCI=m CONFIG_ATH11K_DEBUGFS=y CONFIG_ATH11K_TRACING=y CONFIG_ATH11K_SPECTRAL=y +CONFIG_ATH12K=m CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43LEGACY=m @@ -1838,7 +1839,6 @@ CONFIG_KEYBOARD_DLINK_DIR685=m CONFIG_KEYBOARD_LKKBD=m CONFIG_KEYBOARD_GPIO=m CONFIG_KEYBOARD_GPIO_POLLED=m -CONFIG_KEYBOARD_TCA6416=m CONFIG_KEYBOARD_TCA8418=m CONFIG_KEYBOARD_MATRIX=m CONFIG_KEYBOARD_LM8323=m @@ -3406,7 +3406,6 @@ CONFIG_RADIO_SI4713=m CONFIG_RADIO_SI476X=m CONFIG_RADIO_TEA5764=m CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -3499,7 +3498,6 @@ CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7740=m @@ -4893,8 +4891,8 @@ CONFIG_RTC_DRV_XGENE=y CONFIG_RTC_DRV_R7301=m CONFIG_RTC_DRV_CPCAP=m CONFIG_RTC_DRV_TI_K3=m -CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y CONFIG_ALTERA_MSGDMA=m CONFIG_AMBA_PL08X=y @@ -4979,7 +4977,7 @@ CONFIG_VHOST_NET=m CONFIG_VHOST_SCSI=m CONFIG_VHOST_VSOCK=m CONFIG_VHOST_VDPA=m -CONFIG_HYPERV=m +CONFIG_HYPERV=y CONFIG_HYPERV_UTILS=m CONFIG_HYPERV_BALLOON=m CONFIG_XEN_DEV_EVTCHN=m @@ -5357,7 +5355,6 @@ CONFIG_RPMSG_VIRTIO=m CONFIG_SOUNDWIRE=m CONFIG_SOUNDWIRE_INTEL=m CONFIG_SOUNDWIRE_QCOM=m -CONFIG_APPLE_RTKIT=m CONFIG_APPLE_SART=m CONFIG_QUICC_ENGINE=y CONFIG_FSL_RCPM=y @@ -5396,7 +5393,6 @@ CONFIG_ARM_SCMI_POWER_DOMAIN=m CONFIG_QCOM_CPR=m CONFIG_QCOM_RPMHPD=y CONFIG_QCOM_RPMPD=m -CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_TI_SCI_PM_DOMAINS=m CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y @@ -6012,7 +6008,6 @@ CONFIG_MUX_ADGS1408=m CONFIG_MUX_GPIO=m CONFIG_SIOX=m CONFIG_SIOX_BUS_GPIO=m -CONFIG_SLIM_QCOM_CTRL=m CONFIG_SLIM_QCOM_NGD_CTRL=m CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_MSM8916=m @@ -6060,10 +6055,6 @@ CONFIG_NILFS2_FS=m CONFIG_F2FS_FS=m CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_BCACHEFS_FS=m -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_ERASURE_CODING=y -CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_ZONEFS_FS=m CONFIG_FS_DAX=y CONFIG_FS_ENCRYPTION=y diff --git a/config/kernel/linux-uefi-arm64-legacy.config b/config/kernel/linux-uefi-arm64-legacy.config index 205791de0..b579c475a 100644 --- a/config/kernel/linux-uefi-arm64-legacy.config +++ b/config/kernel/linux-uefi-arm64-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-uefi-loong64-current.config b/config/kernel/linux-uefi-loong64-current.config index d82fcce21..a2145ba40 100644 --- a/config/kernel/linux-uefi-loong64-current.config +++ b/config/kernel/linux-uefi-loong64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_ZSTD=y CONFIG_SYSVIPC=y @@ -662,6 +663,8 @@ CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m diff --git a/config/kernel/linux-uefi-loong64-edge.config b/config/kernel/linux-uefi-loong64-edge.config index 62a1d58a5..3d9e9de35 100644 --- a/config/kernel/linux-uefi-loong64-edge.config +++ b/config/kernel/linux-uefi-loong64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_ZSTD=y CONFIG_SYSVIPC=y @@ -106,8 +107,6 @@ CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y -CONFIG_SMC=m -CONFIG_SMC_DIAG=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_IP_MULTICAST=y @@ -496,7 +495,6 @@ CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m CONFIG_DCB=y CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VIRTIO_VSOCKETS=m @@ -643,6 +641,8 @@ CONFIG_ZRAM_BACKEND_LZ4=y CONFIG_ZRAM_BACKEND_LZ4HC=y CONFIG_ZRAM_BACKEND_ZSTD=y CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m @@ -2009,7 +2009,6 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_CXGB4=m -CONFIG_INFINIBAND_IRDMA=m CONFIG_MLX4_INFINIBAND=m CONFIG_MLX5_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m @@ -2299,9 +2298,6 @@ CONFIG_NILFS2_FS=m CONFIG_F2FS_FS=m CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_BCACHEFS_FS=m -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_ZONEFS_FS=m CONFIG_FS_DAX=y CONFIG_FS_ENCRYPTION=y @@ -2487,7 +2483,6 @@ CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_ECDSA=y CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST5=m diff --git a/config/kernel/linux-uefi-riscv64-current.config b/config/kernel/linux-uefi-riscv64-current.config index 716bded15..f9b038247 100644 --- a/config/kernel/linux-uefi-riscv64-current.config +++ b/config/kernel/linux-uefi-riscv64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -643,6 +644,12 @@ CONFIG_MTD_UBI=m CONFIG_OF_OVERLAY=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m diff --git a/config/kernel/linux-uefi-riscv64-edge.config b/config/kernel/linux-uefi-riscv64-edge.config index 73f4a6152..a99ac9758 100644 --- a/config/kernel/linux-uefi-riscv64-edge.config +++ b/config/kernel/linux-uefi-riscv64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -90,8 +91,6 @@ CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y -CONFIG_SMC=m -CONFIG_SMC_DIAG=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_IP_MULTICAST=y @@ -475,7 +474,6 @@ CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m CONFIG_NET_TC_SKB_EXT=y CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_TRACING=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m @@ -625,6 +623,12 @@ CONFIG_MTD_UBI=m CONFIG_OF_OVERLAY=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=m @@ -1175,6 +1179,7 @@ CONFIG_ATH11K=m CONFIG_ATH11K_AHB=m CONFIG_ATH11K_PCI=m CONFIG_ATH11K_DEBUGFS=y +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set CONFIG_B43=m CONFIG_B43_SDIO=y @@ -1836,7 +1841,6 @@ CONFIG_RADIO_SHARK=m CONFIG_RADIO_SHARK2=m CONFIG_RADIO_SI4713=m CONFIG_RADIO_TEA5764=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -1871,7 +1875,6 @@ CONFIG_VIDEO_OV5647=m CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV7670=m CONFIG_VIDEO_OV772X=m @@ -2867,7 +2870,6 @@ CONFIG_JFS_SECURITY=y CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_ONLINE_SCRUB=y CONFIG_XFS_DEBUG=y CONFIG_GFS2_FS=m CONFIG_GFS2_FS_LOCKING_DLM=y @@ -3057,7 +3059,6 @@ CONFIG_BUG_ON_DATA_CORRUPTION=y CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m diff --git a/config/kernel/linux-uefi-riscv64-legacy.config b/config/kernel/linux-uefi-riscv64-legacy.config index 623b70cda..0df08c97c 100644 --- a/config/kernel/linux-uefi-riscv64-legacy.config +++ b/config/kernel/linux-uefi-riscv64-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-uefi-x86-cloud.config b/config/kernel/linux-uefi-x86-cloud.config index d0d98e83f..e0a110802 100644 --- a/config/kernel/linux-uefi-x86-cloud.config +++ b/config/kernel/linux-uefi-x86-cloud.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -256,6 +257,12 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_VIRTIO_BLK=y @@ -275,7 +282,7 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_MIRROR=y CONFIG_DM_ZERO=y CONFIG_NETDEVICES=y -CONFIG_DUMMY=m +CONFIG_DUMMY=y CONFIG_WIREGUARD=y CONFIG_MACVLAN=m CONFIG_IPVLAN=m diff --git a/config/kernel/linux-uefi-x86-current.config b/config/kernel/linux-uefi-x86-current.config index 062065ed5..80669387e 100644 --- a/config/kernel/linux-uefi-x86-current.config +++ b/config/kernel/linux-uefi-x86-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.12 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_ZSTD=y CONFIG_SYSVIPC=y @@ -907,6 +908,12 @@ CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_FD=m CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -2194,7 +2201,6 @@ CONFIG_APPLICOM=m CONFIG_MWAVE=m CONFIG_HPET=y CONFIG_HANGCHECK_TIMER=m -# CONFIG_TCG_TPM2_HMAC is not set CONFIG_TCG_TIS_SPI=m CONFIG_TCG_TIS_SPI_CR50=y CONFIG_TCG_TIS_I2C=m diff --git a/config/kernel/linux-uefi-x86-edge.config b/config/kernel/linux-uefi-x86-edge.config index 68d6913ea..ab06d3ad8 100644 --- a/config/kernel/linux-uefi-x86-edge.config +++ b/config/kernel/linux-uefi-x86-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_ZSTD=y CONFIG_SYSVIPC=y @@ -55,7 +56,6 @@ CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_KEXEC_JUMP=y CONFIG_SMP=y CONFIG_X86_CPU_RESCTRL=y -CONFIG_X86_FRED=y CONFIG_X86_NUMACHIP=y CONFIG_X86_UV=y CONFIG_X86_INTEL_LPSS=y @@ -156,7 +156,6 @@ CONFIG_KVM_INTEL_PROVE_VE=y CONFIG_X86_SGX_KVM=y CONFIG_KVM_AMD=m CONFIG_KVM_XEN=y -CONFIG_JUMP_LABEL=y CONFIG_ARCH_MMAP_RND_COMPAT_BITS=14 CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_MODULES=y @@ -223,8 +222,6 @@ CONFIG_XFRM_USER_COMPAT=m CONFIG_XFRM_INTERFACE=m CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=m -CONFIG_SMC=m -CONFIG_SMC_DIAG=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=m CONFIG_IP_MULTICAST=y @@ -610,7 +607,6 @@ CONFIG_NET_TC_SKB_EXT=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m # CONFIG_BATMAN_ADV_BATMAN_V is not set -CONFIG_BATMAN_ADV_NC=y CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m @@ -884,6 +880,12 @@ CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_FD=m CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y CONFIG_BLK_DEV_LOOP=y @@ -1521,7 +1523,6 @@ CONFIG_DP83869_PHY=m CONFIG_DP83TD510_PHY=m CONFIG_DP83TG720_PHY=m CONFIG_XILINX_GMII2RGMII=m -CONFIG_MICREL_KS8995MA=m CONFIG_PSE_CONTROLLER=y CONFIG_PSE_REGULATOR=m CONFIG_PSE_PD692X0=m @@ -1661,8 +1662,6 @@ CONFIG_ATH11K_DEBUGFS=y CONFIG_ATH11K_TRACING=y CONFIG_ATH11K_SPECTRAL=y CONFIG_ATH12K=m -CONFIG_ATH12K_DEBUGFS=y -CONFIG_ATH12K_TRACING=y CONFIG_AT76C50X_USB=m CONFIG_B43=m CONFIG_B43LEGACY=m @@ -1855,7 +1854,6 @@ CONFIG_KEYBOARD_QT2160=m CONFIG_KEYBOARD_DLINK_DIR685=m CONFIG_KEYBOARD_LKKBD=m CONFIG_KEYBOARD_GPIO=m -CONFIG_KEYBOARD_TCA6416=m CONFIG_KEYBOARD_TCA8418=m CONFIG_KEYBOARD_MATRIX=m CONFIG_KEYBOARD_LM8323=m @@ -2166,7 +2164,6 @@ CONFIG_APPLICOM=m CONFIG_MWAVE=m CONFIG_HPET=y CONFIG_HANGCHECK_TIMER=m -# CONFIG_TCG_TPM2_HMAC is not set CONFIG_TCG_TIS_SPI=m CONFIG_TCG_TIS_SPI_CR50=y CONFIG_TCG_TIS_I2C=m @@ -3295,7 +3292,6 @@ CONFIG_RADIO_SI4713=m CONFIG_RADIO_SI476X=m CONFIG_RADIO_TEA5764=m CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_USB_DSBR=m CONFIG_USB_KEENE=m CONFIG_USB_MA901=m @@ -3349,7 +3345,6 @@ CONFIG_VIDEO_MT9M111=m CONFIG_VIDEO_MT9M114=m CONFIG_VIDEO_MT9P031=m CONFIG_VIDEO_MT9T112=m -CONFIG_VIDEO_MT9V032=m CONFIG_VIDEO_MT9V111=m CONFIG_VIDEO_OG01A1B=m CONFIG_VIDEO_OV01A10=m @@ -3370,7 +3365,6 @@ CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m CONFIG_VIDEO_OV64A40=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7740=m @@ -4690,8 +4684,8 @@ CONFIG_RTC_DRV_FTRTC010=m CONFIG_RTC_DRV_PCAP=m CONFIG_RTC_DRV_MC13XXX=m CONFIG_RTC_DRV_MT6397=m -CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_RTC_DRV_GOLDFISH=m +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y CONFIG_ALTERA_MSGDMA=m CONFIG_INTEL_IDMA64=m @@ -4765,7 +4759,7 @@ CONFIG_VHOST_NET=m CONFIG_VHOST_SCSI=m CONFIG_VHOST_VSOCK=m CONFIG_VHOST_VDPA=m -CONFIG_HYPERV=m +CONFIG_HYPERV=y CONFIG_HYPERV_UTILS=m CONFIG_HYPERV_BALLOON=m CONFIG_XEN_DEV_EVTCHN=m @@ -5694,7 +5688,6 @@ CONFIG_MUX_ADGS1408=m CONFIG_MUX_GPIO=m CONFIG_SIOX=m CONFIG_SIOX_BUS_GPIO=m -CONFIG_SLIM_QCOM_CTRL=m CONFIG_INTERCONNECT=y CONFIG_104_QUAD_8=m CONFIG_INTEL_QEP=m @@ -5948,7 +5941,6 @@ CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_CURVE25519=m CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_DES=m diff --git a/config/kernel/linux-uefi-x86-legacy.config b/config/kernel/linux-uefi-x86-legacy.config index b136bf407..3cdacb304 100644 --- a/config/kernel/linux-uefi-x86-legacy.config +++ b/config/kernel/linux-uefi-x86-legacy.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_KERNEL_LZ4=y CONFIG_SYSVIPC=y diff --git a/config/kernel/linux-wsl2-arm64-current.config b/config/kernel/linux-wsl2-arm64-current.config index 9cff586e6..0c0f53b59 100644 --- a/config/kernel/linux-wsl2-arm64-current.config +++ b/config/kernel/linux-wsl2-arm64-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.1 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-wsl2-arm64-edge.config b/config/kernel/linux-wsl2-arm64-edge.config index 073d516a5..978b5ed2e 100644 --- a/config/kernel/linux-wsl2-arm64-edge.config +++ b/config/kernel/linux-wsl2-arm64-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-wsl2-x86-current.config b/config/kernel/linux-wsl2-x86-current.config index e6abefdf1..fa1e7bde7 100644 --- a/config/kernel/linux-wsl2-x86-current.config +++ b/config/kernel/linux-wsl2-x86-current.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.1 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-wsl2-x86-edge.config b/config/kernel/linux-wsl2-x86-edge.config index aef698252..ecf00fa0b 100644 --- a/config/kernel/linux-wsl2-x86-edge.config +++ b/config/kernel/linux-wsl2-x86-edge.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/kernel/linux-xpressreal-t3-6.6.config b/config/kernel/linux-xpressreal-t3-6.6.config index aa93d06b3..19b15f960 100644 --- a/config/kernel/linux-xpressreal-t3-6.6.config +++ b/config/kernel/linux-xpressreal-t3-6.6.config @@ -1,3 +1,4 @@ +# Armbian defconfig generated with 6.6 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/config/sources/families/bcm2711.conf b/config/sources/families/bcm2711.conf index 82c6c172e..d67b98bbd 100644 --- a/config/sources/families/bcm2711.conf +++ b/config/sources/families/bcm2711.conf @@ -14,7 +14,7 @@ declare -g CPUMIN=500000 declare -g CPUMAX=2900000 declare -g GOVERNOR=ondemand declare -g INSTALL_ARMBIAN_FIRMWARE=no -declare -g UEFISIZE=256 # in MiB. Not really UEFI, but partition layout is the same. +declare -g UEFISIZE=512 # in MiB. Not really UEFI, but partition layout is the same. declare -g BOOTSIZE=0 # No separate /boot; instead we have /boot/firmware fat32 partition declare -g BOOTCONFIG=none # We are currently not using U-boot for Raspberry Pi boards declare -g UEFI_MOUNT_POINT="/boot/firmware" # mount uefi partition at /boot/firmware @@ -37,8 +37,8 @@ case "${BRANCH}" in edge) declare -g EXTRAWIFI="no" declare -g KERNELSOURCE='https://github.com/raspberrypi/linux' - declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel. For mainline caching. - declare -g KERNELBRANCH="branch:rpi-6.16.y" + declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel. For mainline caching. + declare -g KERNELBRANCH="branch:rpi-6.18.y" ;; esac diff --git a/config/sources/families/filogic.conf b/config/sources/families/filogic.conf index ca4969116..bdb417e21 100644 --- a/config/sources/families/filogic.conf +++ b/config/sources/families/filogic.conf @@ -59,8 +59,8 @@ case $BRANCH in ;; edge) - KERNELSOURCE='https://github.com/frank-w/BPI-Router-Linux.git' - KERNELBRANCH="branch:6.16-rsslro" + #KERNELSOURCE='https://github.com/frank-w/BPI-Router-Linux.git' + #KERNELBRANCH="branch:6.16-rsslro" declare -g KERNEL_MAJOR_MINOR="6.16" KERNELPATCHDIR="archive/${LINUXFAMILY}-${KERNEL_MAJOR_MINOR}" LINUXCONFIG="linux-${LINUXFAMILY}-${BRANCH}" diff --git a/config/sources/families/genio.conf b/config/sources/families/genio.conf index acb95b202..e72efb4af 100644 --- a/config/sources/families/genio.conf +++ b/config/sources/families/genio.conf @@ -20,7 +20,7 @@ case $BRANCH in collabora) declare -g LINUXCONFIG="linux-genio-$BRANCH" - declare -g KERNEL_MAJOR_MINOR="6.14" + declare -g KERNEL_MAJOR_MINOR="6.18" declare -g KERNELPATCHDIR='genio-1200-collabora' declare -g KERNELSOURCE='https://gitlab.collabora.com/mediatek/aiot/linux.git' declare -g KERNELBRANCH='branch:mediatek-next' diff --git a/config/sources/families/imx8m.conf b/config/sources/families/imx8m.conf index ca699ba89..aac57f45d 100644 --- a/config/sources/families/imx8m.conf +++ b/config/sources/families/imx8m.conf @@ -32,7 +32,11 @@ esac pre_config_uboot_target() { # get the firmware rm -rf ${IMX_FIRMWARE}* - wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/${IMX_FIRMWARE}.bin -O ${IMX_FIRMWARE}.bin + curl -fL "https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/${IMX_FIRMWARE}.bin" -o "${IMX_FIRMWARE}.bin" || { + echo "download of IMX_FIRMWARE failed"; + rm -f "${IMX_FIRMWARE}.bin" + exit 1 + } chmod +x ${IMX_FIRMWARE}.bin ./${IMX_FIRMWARE}.bin --auto-accept diff --git a/config/sources/families/include/k3_common.inc b/config/sources/families/include/k3_common.inc new file mode 100644 index 000000000..3745ce4a1 --- /dev/null +++ b/config/sources/families/include/k3_common.inc @@ -0,0 +1,116 @@ +# +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com +# +# This file is a part of the Armbian Build Framework +# https://github.com/armbian/build/ +# + +declare -g ARCH="arm64" +declare -g OVERLAY_DIR="/boot/dtb/ti/overlay" +declare -g BOOTSCRIPT="boot-k3.cmd:uEnv.txt" +declare -g SPD_OPTEED="SPD=opteed" + +declare -g INSTALL_HEADERS="yes" + +declare -g TI_PACKAGES=() +if [[ "${CC33XX_SUPPORT}" == "yes" ]] ; then + if [[ "${RELEASE}" == "trixie" || "${RELEASE}" == "noble" ]] ; then + TI_PACKAGES+=("cc33xx-fw" "cc33xx-target-scripts" "cc33conf" "cc33calibrator") + fi +fi + +enable_extension "ti-debpkgs" +enable_extension "apa" + +case "${BRANCH}" in + + edge) # experimental (limited testing): uses latest bleeding-edge upstream mainline version + + # KERNELSOURCE defined in mainline-config.sh + # KERNELBRANCH defined in mainline-kernel.conf.sh + declare -g KERNEL_MAJOR_MINOR="6.18" # needs updating with each minor kernel release + declare -g KERNEL_DESCRIPTION="Latest upstream mainline kernel" + declare -g ATFBRANCH="branch:master" + declare -g OPTEE_BRANCH="branch:master" + declare -g TI_LINUX_FIRMWARE_BRANCH="branch:ti-linux-firmware" + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot" + declare -g BOOTBRANCH="branch:master" + ;; + +esac + +ATF_PLAT="k3" +ATF_TARGET_MAP="PLAT=$ATF_PLAT TARGET_BOARD=$ATF_BOARD ${SPD_OPTEED} ${ATF_K3_USART_OFFSET} all;;build/$ATF_PLAT/$ATF_BOARD/release/bl31.bin:bl31.bin ${EXTRA_ATF_TARGETS}" + +UBOOT_TARGET_MAP="BL31=bl31.bin ${EXTRA_BOOT_ARGS} TEE=${SRC}/cache/sources/optee-os/out/arm-plat-k3/core/tee-raw.bin BINMAN_INDIRS=${SRC}/cache/sources/ti-linux-firmware all;;tiboot3.bin ${SYSFW_FILE:+sysfw.itb} tispl.bin u-boot.img" + +# To match what our current SDK produces +BOOT_FS_LABEL="boot" +ROOT_FS_LABEL="root" + +function add_host_dependencies__k3_python3_dep() { + display_alert "Preparing K3 U-Boot host-side dependencies" "${EXTENSION}" "info" + declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} python3-yaml python3-jsonschema yamllint python3-cryptography python3-pyelftools python3-setuptools" +} + +function compile_k3_bootgen() { + # Source code checkout + (fetch_from_repo "https://github.com/TexasInstruments/ti-linux-firmware" "ti-linux-firmware" ${TI_LINUX_FIRMWARE_BRANCH}) + + if [[ "${BOOT_SOC}" != "am62l" ]]; then + pushd ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:} || exit + run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=build-r5 ${TIBOOT3_BOOTCONFIG} + run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=build-r5 BINMAN_INDIRS=${SRC}/cache/sources/ti-linux-firmware + popd + fi +} + +function compile_k3_optee() { + (fetch_from_repo "https://github.com/OP-TEE/optee_os.git" "optee-os" ${OPTEE_BRANCH}) + pushd ${SRC}/cache/sources/optee-os || exit + run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabihf- CFG_ARM64_core=y PLATFORM=${OPTEE_PLATFORM} ${OPTEE_ARGS} + popd +} + +function pre_config_uboot_target__build_first_stage() { + # Compile first stage bootloader + compile_k3_optee + compile_k3_bootgen + + if [[ "${BOOT_SOC}" != "am62l" ]]; then + cp ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:}/build-r5/${TIBOOT3_FILE} tiboot3.bin + cp ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:}/build-r5/${SYSFW_FILE} sysfw.itb || true + fi +} + +function post_uboot_custom_postprocess__update_uboot_names() { + cp ${TISPL_FILE} tispl.bin || true + cp ${UBOOT_FILE} u-boot.img || true +} + +function pre_prepare_partitions() { + # Filesystem must fill partition regardless of alignment + mkopts[fat]='-a' +} + +function post_create_partitions() { + display_alert "Setting boot partition flags on" "${SDCARD}.raw" "debug" + + # ROM is very particular about boot flags + run_host_command_logged parted "${SDCARD}".raw set 1 boot on + run_host_command_logged parted "${SDCARD}".raw set 1 bls_boot off +} + +function format_partitions() { + # ROM is very particular about partition IDs + run_host_command_logged sfdisk --part-type ${LOOP} 1 e +} + +function write_uboot_platform() { + cp $1/tiboot3.bin ${MOUNT}/boot + cp $1/sysfw.itb ${MOUNT}/boot || true + cp $1/tispl.bin ${MOUNT}/boot + cp $1/u-boot.img ${MOUNT}/boot +} diff --git a/config/sources/families/include/meson64_common.inc b/config/sources/families/include/meson64_common.inc index e9351213b..cfc327e4a 100644 --- a/config/sources/families/include/meson64_common.inc +++ b/config/sources/families/include/meson64_common.inc @@ -6,8 +6,6 @@ # This file is a part of the Armbian Build Framework # https://github.com/armbian/build/ # -enable_extension "gxlimg" -enable_extension "amlogic-fip-blobs" UBOOT_TARGET_MAP="${UBOOT_TARGET_MAP:-u-boot-dtb.img;;u-boot.bin.sd.bin:u-boot.bin u-boot-dtb.img}" BOOTSCRIPT="boot-meson64.cmd:boot.cmd" BOOTENV_FILE='meson.txt' @@ -41,7 +39,7 @@ case $BRANCH in declare -g KERNEL_MAJOR_MINOR="6.12" ;; edge) - declare -g KERNEL_MAJOR_MINOR="6.17" + declare -g KERNEL_MAJOR_MINOR="6.18" ;; esac @@ -49,11 +47,7 @@ esac # Use custom vendor driver for wireless rtl88x2cs # See https://github.com/armbian/build/pull/6227 function custom_kernel_config__enable_rtl88x2cs_driver() { - kernel_config_modifying_hashes+=("CONFIG_RTL8822CS=m") - if [[ -f .config ]]; then - display_alert "Enabling rtl88x2cs driver in kernel config" "armbian-kernel" "wrn" - kernel_config_set_m CONFIG_RTL8822CS - fi + opts_m+=("CONFIG_RTL8822CS") } # this helper function includes postprocess for s400 and its variants. diff --git a/config/sources/families/include/rockchip64_common.inc b/config/sources/families/include/rockchip64_common.inc index 7abe372c0..553689e36 100644 --- a/config/sources/families/include/rockchip64_common.inc +++ b/config/sources/families/include/rockchip64_common.inc @@ -33,7 +33,7 @@ case $BRANCH in ;; edge) - declare -g KERNEL_MAJOR_MINOR="6.17" + declare -g KERNEL_MAJOR_MINOR="6.18" declare -g LINUXFAMILY=rockchip64 declare -g LINUXCONFIG='linux-rockchip64-'$BRANCH ;; @@ -410,7 +410,7 @@ family_tweaks_bsp() { } -# A late hook to default SERIALCON based on BRANCH; BOARD and hooks (earlier than 900) can set it to override this. +# A late hook to default SERIALCON based on BRANCH and SOC; BOARD and hooks (earlier than 900) can set it to override this. function post_family_config__900_late_default_serial_console_by_branch() { display_alert "rockchip64_common: defaulting SERIALCON" "initial SERIALCON: '${SERIALCON:-"unset"}'" "debug" @@ -426,10 +426,19 @@ function post_family_config__900_late_default_serial_console_by_branch() { SERIALCON="ttyFIQ0" ;; *) - display_alert "rockchip64_common: defaulting SERIALCON" "Setting SERIALCON to ttyS2 for BRANCH='${BRANCH}'" "info" - SERIALCON="ttyS2" + # Different Rockchip SoCs use different UART for debug console + case $BOOT_SOC in + rk3576) + display_alert "rockchip64_common: defaulting SERIALCON" "Setting SERIALCON to ttyS0 for SoC='${BOOT_SOC}' BRANCH='${BRANCH}'" "info" + SERIALCON="ttyS0" + ;; + *) + display_alert "rockchip64_common: defaulting SERIALCON" "Setting SERIALCON to ttyS2 for SoC='${BOOT_SOC}' BRANCH='${BRANCH}'" "info" + SERIALCON="ttyS2" + ;; + esac ;; esac - display_alert "rockchip64_common: defaulting SERIALCON" "final SERIALCON: '${SERIALCON}' for BRANCH='${BRANCH}'" "debug" + display_alert "rockchip64_common: defaulting SERIALCON" "final SERIALCON: '${SERIALCON}' for BRANCH='${BRANCH}' SOC='${BOOT_SOC}'" "debug" } diff --git a/config/sources/families/include/sunxi64_common.inc b/config/sources/families/include/sunxi64_common.inc index f14160a5d..8ad0fbed2 100644 --- a/config/sources/families/include/sunxi64_common.inc +++ b/config/sources/families/include/sunxi64_common.inc @@ -31,7 +31,7 @@ case $BRANCH in current) declare -g KERNEL_MAJOR_MINOR="6.12" # Major and minor versions of this kernel. - declare -g KERNELBRANCH="tag:v6.12.47" + declare -g KERNELBRANCH="tag:v6.12.58" ;; edge) diff --git a/config/sources/families/include/sunxi_common.inc b/config/sources/families/include/sunxi_common.inc index 8a0dc4047..4f811e6c3 100644 --- a/config/sources/families/include/sunxi_common.inc +++ b/config/sources/families/include/sunxi_common.inc @@ -32,7 +32,7 @@ case $BRANCH in current) declare -g KERNEL_MAJOR_MINOR="6.12" # Major and minor versions of this kernel. - declare -g KERNELBRANCH="tag:v6.12.51" + declare -g KERNELBRANCH="tag:v6.12.58" ;; edge) diff --git a/config/sources/families/include/uefi_common.inc b/config/sources/families/include/uefi_common.inc index aa7716560..2d7cfb911 100644 --- a/config/sources/families/include/uefi_common.inc +++ b/config/sources/families/include/uefi_common.inc @@ -10,6 +10,7 @@ declare -g SERIALCON="${SERIALCON:-tty1}" # Consistent serial console declare -g UEFI_GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT:-3} # Default 3-seconds timeout for GRUB menu. declare -g BOARD_FIRMWARE_INSTALL="-full" # Install full firmware for UEFI boards declare -g DISTRO_GENERIC_KERNEL=no +declare -g POWER_MANAGEMENT_FEATURES=yes # Suspend and resume might work well in UEFI, elsewhere is disabled by default case "${BRANCH}" in @@ -41,7 +42,7 @@ case "${BRANCH}" in ;; edge) - declare -g KERNEL_MAJOR_MINOR="6.17" + declare -g KERNEL_MAJOR_MINOR="6.18" ;; esac @@ -58,7 +59,7 @@ if [[ "${QEMU_UBOOT_BOOTCONFIG}" != "" ]]; then declare -g ATF_COMPILE="no" declare -g BOOTDIR="qemu-uboot-${LINUXFAMILY}" - declare -g BOOTBRANCH='tag:v2025.10-rc4' + declare -g BOOTBRANCH='tag:v2025.10' declare -g BOOTSOURCE='https://github.com/u-boot/u-boot' # Gotta set this again, it is unset by grub extension declare -g BOOTCONFIG="${QEMU_UBOOT_BOOTCONFIG}" diff --git a/config/sources/families/k3-beagle.conf b/config/sources/families/k3-beagle.conf new file mode 100644 index 000000000..999ce3336 --- /dev/null +++ b/config/sources/families/k3-beagle.conf @@ -0,0 +1,31 @@ +# +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com +# +# This file is a part of the Armbian Build Framework +# https://github.com/armbian/build/ +# + +source "${BASH_SOURCE%/*}/include/k3_common.inc" + +declare -g LINUXFAMILY="k3-beagle" # Separate kernel package from the regular `k3` family +declare -g ATFSOURCE="https://github.com/TexasInstruments/arm-trusted-firmware" + +case "${BRANCH}" in + + vendor | vendor-rt) + + declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel + declare -g KERNEL_MAJOR_MINOR="6.12" + declare -g KERNELBRANCH="branch:v6.12.49-ti-arm64-r56" + declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot + declare -g BOOTBRANCH="branch:v2025.07-am6232-pocketbeagle2" + declare -g KERNEL_DESCRIPTION="BeagleBoard.org (vendor) kernel" + declare -g ATFBRANCH="tag:11.00.09" + declare -g OPTEE_BRANCH="tag:4.6.0" + declare -g TI_LINUX_FIRMWARE_BRANCH="tag:11.00.09" + EXTRAWIFI="no" + ;; + +esac diff --git a/config/sources/families/k3.conf b/config/sources/families/k3.conf index f52444240..33b47db78 100644 --- a/config/sources/families/k3.conf +++ b/config/sources/families/k3.conf @@ -7,127 +7,54 @@ # https://github.com/armbian/build/ # -declare -g ARCH="arm64" +source "${BASH_SOURCE%/*}/include/k3_common.inc" + declare -g LINUXFAMILY="k3" -declare -g OVERLAY_DIR="/boot/dtb/ti/overlay" - -declare -g KERNELSOURCE="https://github.com/TexasInstruments/ti-linux-kernel" -declare -g ATFSOURCE="https://github.com/TexasInstruments/arm-trusted-firmware" -declare -g BOOTSOURCE="https://github.com/TexasInstruments/ti-u-boot" - -declare -g BOOTSCRIPT="boot-k3.cmd:uEnv.txt" -declare -g SPD_OPTEED="SPD=opteed" - -declare -g INSTALL_HEADERS="yes" - -declare -g TI_PACKAGES=() -if [[ "${CC33XX_SUPPORT}" == "yes" ]] ; then - if [[ "${RELEASE}" == "trixie" || "${RELEASE}" == "noble" ]] ; then - TI_PACKAGES+=("cc33xx-fw" "cc33xx-target-scripts" "cc33conf" "cc33calibrator") - fi -fi - -enable_extension "ti-debpkgs" -enable_extension "apa" +declare -g ATFSOURCE="https://github.com/ARM-software/arm-trusted-firmware" case "${BRANCH}" in - current | current-rt) + vendor | vendor-rt) # uses latest publicly released TI Processor SDK tag - declare -g CORESDK_TAG="tag:11.00.09" + declare -g TI_PSDK_TAG="11.01.16" + declare -g KERNELSOURCE="https://github.com/TexasInstruments/ti-linux-kernel" declare -g KERNEL_MAJOR_MINOR="6.12" - declare -g KERNELBRANCH="${CORESDK_TAG}" - declare -g KERNEL_DESCRIPTION="Texas Instruments currently supported SDK (vendor) kernel" - declare -g ATFBRANCH="commit:b11beb2b6bd30b75c4bfb0e9925c0e72f16ca53f" - declare -g OPTEE_BRANCH="tag:4.6.0" - declare -g TI_LINUX_FIRMWARE_BRANCH="${CORESDK_TAG}" - declare -g BOOTBRANCH="${CORESDK_TAG}" + declare -g KERNELBRANCH="tag:${TI_PSDK_TAG}" + declare -g KERNEL_DESCRIPTION="Texas Instruments currently supported Processor SDK kernel" + declare -g ATFBRANCH="commit:e0c4d3903b382bf34f552af53e6d955fae5283ab" + declare -g OPTEE_BRANCH="commit:a9690ae39995af36a31b7a4f446f27ea0787e3a4" + declare -g TI_LINUX_FIRMWARE_BRANCH="tag:${TI_PSDK_TAG}" + declare -g BOOTSOURCE="https://github.com/TexasInstruments/ti-u-boot" + declare -g BOOTBRANCH="tag:${TI_PSDK_TAG}" EXTRAWIFI="no" ;; - edge) + vendor-edge) # uses latest pre-released TI Processor SDK tag - declare -g CORESDK_TAG="tag:11.00.12" + declare -g KERNELSOURCE="https://github.com/TexasInstruments/ti-linux-kernel" declare -g KERNEL_MAJOR_MINOR="6.12" - declare -g KERNELBRANCH="${CORESDK_TAG}" - declare -g ATFBRANCH="commit:b45324936bbba464b0623c83cd5aa53e1cd4cbdb" - declare -g OPTEE_BRANCH="tag:4.6.0" - declare -g TI_LINUX_FIRMWARE_BRANCH="${CORESDK_TAG}" - declare -g BOOTBRANCH="${CORESDK_TAG}" + declare -g KERNELBRANCH="branch:ti-linux-6.12.y" + declare -g KERNEL_DESCRIPTION="Texas Instruments latest pre-released Processor SDK kernel" + declare -g ATFBRANCH="branch:master" + declare -g OPTEE_BRANCH="branch:master" + declare -g TI_LINUX_FIRMWARE_BRANCH="branch:ti-linux-firmware" + declare -g BOOTSOURCE="https://github.com/TexasInstruments/ti-u-boot" + declare -g BOOTBRANCH="branch:ti-u-boot-2025.01" EXTRAWIFI="no" - declare -g KERNEL_DESCRIPTION="Edge branch of TI Linux SDK" ;; esac -ATF_PLAT="k3" -ATF_TARGET_MAP="PLAT=$ATF_PLAT TARGET_BOARD=$ATF_BOARD ${SPD_OPTEED} ${ATF_K3_USART_OFFSET} bl31;;build/$ATF_PLAT/$ATF_BOARD/release/bl31.bin:bl31.bin" +case "${BOOT_SOC}" in -UBOOT_TARGET_MAP="BL31=bl31.bin TEE=${SRC}/cache/sources/optee-os/out/arm-plat-k3/core/tee-raw.bin BINMAN_INDIRS=${SRC}/cache/sources/ti-linux-firmware all;;tiboot3.bin ${SYSFW_FILE:+sysfw.itb} tispl.bin u-boot.img" + am62l) # update commit sha with each update of "vendor"/"vendor-rt" until 62L ATF in upstream -# To match what our current SDK produces -BOOT_FS_LABEL="boot" -ROOT_FS_LABEL="root" + declare -g ATFSOURCE="https://github.com/TexasInstruments/arm-trusted-firmware" + if [[ "${BRANCH}" == "vendor" || "${BRANCH}" == "vendor-rt" ]]; then + declare -g ATFBRANCH="commit:6c8ef67293770a59afe86f8e98cfa39d01614ab8" + elif [[ "${BRANCH}" == "vendor-edge" ]]; then + declare -g ATFBRANCH="branch:ti-master" + fi + ;; -function add_host_dependencies__k3_python3_dep() { - display_alert "Preparing K3 U-Boot host-side dependencies" "${EXTENSION}" "info" - declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} python3-yaml python3-jsonschema yamllint python3-cryptography python3-pyelftools python3-setuptools" -} - -function compile_k3_bootgen() { - # Source code checkout - (fetch_from_repo "https://github.com/TexasInstruments/ti-linux-firmware" "ti-linux-firmware" ${TI_LINUX_FIRMWARE_BRANCH}) - - pushd ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:} || exit - - run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm O=build-r5 ${TIBOOT3_BOOTCONFIG} - run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm O=build-r5 BINMAN_INDIRS=${SRC}/cache/sources/ti-linux-firmware - - popd -} - -function compile_k3_optee() { - (fetch_from_repo "https://github.com/OP-TEE/optee_os.git" "optee-os" ${OPTEE_BRANCH}) - pushd ${SRC}/cache/sources/optee-os || exit - run_host_command_logged make -j$(nproc) CROSS_COMPILE=arm-linux-gnueabihf- CFG_ARM64_core=y PLATFORM=${OPTEE_PLATFORM} ${OPTEE_ARGS} - popd -} - -function pre_config_uboot_target__build_first_stage() { - # Compile first stage bootloader - compile_k3_optee - compile_k3_bootgen - - cp ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:}/build-r5/${TIBOOT3_FILE} tiboot3.bin - cp ${SRC}/cache/sources/u-boot-worktree/${BOOTDIR}/${BOOTBRANCH##*:}/build-r5/${SYSFW_FILE} sysfw.itb || true -} - -function post_uboot_custom_postprocess__update_uboot_names() { - cp ${TISPL_FILE} tispl.bin || true - cp ${UBOOT_FILE} u-boot.img || true -} - -function pre_prepare_partitions() { - # Filesystem must fill partition regardless of alignment - mkopts[fat]='-a' -} - -function post_create_partitions() { - display_alert "Setting boot partition flags on" "${SDCARD}.raw" "debug" - - # ROM is very particular about boot flags - run_host_command_logged parted "${SDCARD}".raw set 1 boot on - run_host_command_logged parted "${SDCARD}".raw set 1 bls_boot off -} - -function format_partitions() { - # ROM is very particular about partition IDs - run_host_command_logged sfdisk --part-type ${LOOP} 1 e -} - -function write_uboot_platform() { - cp $1/tiboot3.bin ${MOUNT}/boot - cp $1/sysfw.itb ${MOUNT}/boot || true - cp $1/tispl.bin ${MOUNT}/boot - cp $1/u-boot.img ${MOUNT}/boot -} +esac diff --git a/config/sources/families/meson-s4t7.conf b/config/sources/families/meson-s4t7.conf index 81edb446a..4ebe6ae31 100644 --- a/config/sources/families/meson-s4t7.conf +++ b/config/sources/families/meson-s4t7.conf @@ -65,7 +65,7 @@ function fetch_sources_tools__meson_s4t7_download_uboot_toolchain() { mkdir -p "${tbasedir}" if [[ ! -d "${tdir}" ]]; then - run_host_command_logged wget --progress=dot:giga -O "${tbasedir}/${tfile}" "${turl}" + run_host_command_logged curl -fL#o "${tbasedir}/${tfile}" "${turl}" run_host_command_logged tar -C "${tbasedir}" -xf "${tbasedir}/${tfile}" run_host_command_logged rm -fv "${tbasedir}/${tfile}" fi @@ -87,7 +87,7 @@ function fetch_sources_tools__meson_s4t7_download_uboot_toolchain() { mkdir -p "${tbasedir}" if [[ ! -d "${tdir}" ]]; then - run_host_command_logged wget --progress=dot:giga -O "${tbasedir}/${tfile}" "${turl}" + run_host_command_logged curl -fL#o "${tbasedir}/${tfile}" "${turl}" run_host_command_logged tar -C "${tbasedir}" -xzf "${tbasedir}/${tfile}" run_host_command_logged rm -fv "${tbasedir}/${tfile}" fi @@ -121,6 +121,11 @@ function build_custom_uboot__meson_s4t7_build_custom_uboot() { } function custom_kernel_config__add_khadas_common_drivers() { + display_alert "Enabling kernel config" "DEBUG_KERNEL=y, EXPERT=y, EMBEDDED=y to fix khadas_common_drivers compilation" "info" + opts_y+=("DEBUG_KERNEL") # Unfortunately, debug kernel has to be enabled to make khadas_common_drivers compile + opts_y+=("EMBEDDED") + opts_y+=("EXPERT") + # viraniac: The kernel config hooks are always called twice, once without being in kernel directory and once with current directory being the kernel work directory. if [[ ! -f .config ]]; then display_alert "$BOARD" "Fetching khadas common drivers git info" "info" @@ -136,15 +141,6 @@ function custom_kernel_config__add_khadas_common_drivers() { # Hack to ensure that we will recreate kernel if common_drivers source changes kernel_config_modifying_hashes+=("khadas_common_drivers=${GIT_INFO_COMMON_DRIVERS[SHA1]}") - - # viraniac: kernel_config_modifying_hashes is only needed during first call of this function to calculate kernel artifact version string. It serves no purpose whatsoever during second call. - kernel_config_modifying_hashes+=("CONFIG_DEBUG_KERNEL=y" "CONFIG_EXPERT=y" "CONFIG_EMBEDDED=y") - else - # Unfortunately, debug kernel has to be enabled to make khadas_common_drivers compile - display_alert "Enabling kernel config" "DEBUG_KERNEL=y, EXPERT=y, EMBEDDED=y to fix khadas_common_drivers compilation" "info" - kernel_config_set_y DEBUG_KERNEL - kernel_config_set_y EXPERT - kernel_config_set_y EMBEDDED fi } diff --git a/config/sources/families/mvebu64.conf b/config/sources/families/mvebu64.conf index 90b0a97d4..03fac3797 100644 --- a/config/sources/families/mvebu64.conf +++ b/config/sources/families/mvebu64.conf @@ -21,14 +21,14 @@ function add_host_dependencies__mvebu64_add_32_bit_c_compiler() { } ARCH=arm64 -BOOTBRANCH='tag:v2023.01' -BOOTPATCHDIR='v2023.01' +BOOTBRANCH='tag:v2025.10' +BOOTPATCHDIR='v2025.10' BOOTENV_FILE='mvebu64.txt' BOOTSCRIPT_OUTPUT='boot.scr' OVERLAY_DIR="/boot/dtb/marvell/overlay" ATFSOURCE='https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git' ATFDIR='arm-trusted-firmware-espressobin' -ATFBRANCH='tag:v2.8' +ATFBRANCH='tag:lts-v2.12.8' ATF_USE_GCC='> 7.2' if [[ "${SKIP_EXTERNAL_TOOLCHAINS}" == "yes" ]]; then @@ -55,16 +55,17 @@ fi case $BRANCH in - current) - - declare -g KERNEL_MAJOR_MINOR="5.15" # Major and minor versions of this kernel. - KERNELBRANCH='branch:linux-5.15.y' - + legacy) + declare -g KERNEL_MAJOR_MINOR="6.6" # Major and minor versions of this kernel. + declare -g KERNELBRANCH='branch:linux-6.6.y' ;; + current) + declare -g KERNEL_MAJOR_MINOR="6.12" # Major and minor versions of this kernel. + declare -g KERNELBRANCH='branch:linux-6.12.y' + ;; edge) - declare -g KERNEL_MAJOR_MINOR="6.6" # Major and minor versions of this kernel. - KERNELBRANCH='branch:linux-6.6.y' + declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel. ;; esac @@ -73,16 +74,6 @@ CPUMIN=200000 CPUMAX=1300000 GOVERNOR=ondemand -function pre_install_kernel_debs__network_manager_ignore_devices() { - display_alert "Board: ${BOARD}: Disabling Network-Manager for all devices" "interface-name:eth*,interface-name:wan*,interface-name:lan*,interface-name:br*" "info" - - mkdir -p "${SDCARD}"/etc/NetworkManager/conf.d/ - cat <<- EOF > "${SDCARD}"/etc/NetworkManager/conf.d/99-ignore-interfaces.conf - [keyfile] - unmanaged-devices="interface-name:eth*,interface-name:wan*,interface-name:lan*,interface-name:br*" - EOF -} - write_uboot_platform() { if [[ $BOARD = macchiatobin-doubleshot ]]; then dd if=$1/flash-image.bin of=$2 bs=512 seek=1 status=noxfer > /dev/null 2>&1 @@ -93,8 +84,6 @@ write_uboot_platform() { } family_tweaks() { - [[ -f $SDCARD/etc/netplan/armbian-default.yaml ]] && sed -i "s/^ renderer.*/ renderer: networkd/" $SDCARD/etc/netplan/armbian-default.yaml - cp $SRC/packages/bsp/mvebu64/networkd/10* $SDCARD/etc/systemd/network/ if [[ $BOARD = "espressobin" ]]; then echo "#Marvell Espressobin Console" >> $SDCARD/etc/securetty echo "ttyMV0" >> $SDCARD/etc/securetty @@ -139,6 +128,8 @@ uboot_custom_postprocess() { run_host_command_logged cp -pv build/a80x0_mcbin/release/flash-image.bin $ubootdir/$FILENAME else cd $moxbootdir + [[ -f Makefile ]] && sed -i "s/aarch64-unknown-linux-gnu-/aarch64-linux-gnu-/" Makefile + [[ -f wtmi/a53_helper/Makefile ]] && sed -i "s/aarch64-unknown-linux-gnu-/aarch64-linux-gnu-/" wtmi/a53_helper/Makefile make clean # @TODO: rpardini: why? run_host_command_logged "CFLAGS=-fdiagnostics-color=always" pipetty make CROSS_CM3=$ATF2 wtmi_app.bin cd $atfdir diff --git a/config/sources/families/qcs6490.conf b/config/sources/families/qcs6490.conf index 7438b641d..d8b3b5df8 100644 --- a/config/sources/families/qcs6490.conf +++ b/config/sources/families/qcs6490.conf @@ -17,7 +17,7 @@ declare -g SERIALCON="ttyMSM0" case $BRANCH in edge) - declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel. + declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel. declare -g -i KERNEL_GIT_CACHE_TTL=120 # 2 minutes; this is a high-traffic repo ;; esac diff --git a/config/sources/families/rk35xx.conf b/config/sources/families/rk35xx.conf index 793436c35..adaea44e6 100644 --- a/config/sources/families/rk35xx.conf +++ b/config/sources/families/rk35xx.conf @@ -44,6 +44,15 @@ esac prepare_boot_configuration +pre_config_uboot_target__warn_modern_hosts() { + # Check if building Radxa U-Boot on a host other than Ubuntu Jammy + if [[ "${BOOTSOURCE}" == "https://github.com/radxa/u-boot.git" ]]; then + if [[ "${HOSTRELEASE}" != "jammy" ]]; then + display_alert "Building Rockchip BSP U-Boot from Radxa repository" "on Ubuntu ${HOSTRELEASE} (newer than Jammy) can lead to unintended bugs" "wrn" + fi + fi +} + family_tweaks_bsp() { : } diff --git a/config/sources/families/rockchip-rk3588.conf b/config/sources/families/rockchip-rk3588.conf index 589a74467..c78fad693 100644 --- a/config/sources/families/rockchip-rk3588.conf +++ b/config/sources/families/rockchip-rk3588.conf @@ -42,6 +42,15 @@ esac prepare_boot_configuration +pre_config_uboot_target__warn_modern_hosts() { + # Check if building Radxa U-Boot on a host other than Ubuntu Jammy + if [[ "${BOOTSOURCE}" == "https://github.com/radxa/u-boot.git" ]]; then + if [[ "${HOSTRELEASE}" != "jammy" ]]; then + display_alert "Building Rockchip BSP U-Boot from Radxa repository" "on Ubuntu ${HOSTRELEASE} (newer than Jammy) can lead to unintended bugs" "wrn" + fi + fi +} + family_tweaks_bsp() { : } diff --git a/config/sources/families/rockchip-rv1106.conf b/config/sources/families/rockchip-rv1106.conf new file mode 100644 index 000000000..e5541ad4b --- /dev/null +++ b/config/sources/families/rockchip-rv1106.conf @@ -0,0 +1,154 @@ +# +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2013-2025 Igor Pecovnik, igor@armbian.com +# +# This file is a part of the Armbian Build Framework +# https://github.com/armbian/build/ +# + +# +# RV1106 family: includes Rockchip RV1103 and RV1106 SoCs. +# This family is optimized for low-memory (64-256MB). +# +enable_extension "rkbin-tools" + +# BOOT_SOC has to be set in the board configuration file; if not set +# we resort to rv1106 +BOOT_SOC=${BOOT_SOC:="rv1106"} + +ARCH=armhf +BOOTDELAY=1 +SERIALCON="ttyFIQ0" +RKBIN_DIR="$SRC/cache/sources/rkbin-tools" +SRC_EXTLINUX="yes" +# Bootargs: +# cma=0 -- disable CMA allocations (used by video / ipc) to save memory +# video=off -- disable video subsystem to save memory +# udev.children-max=1 -- limit number of udev child processes to save memory early in boot +# console=ttyFIQ0,115200n8 -- set console to FIQ0 serial port at 115200 baud +SRC_CMDLINE="cma=0 video=off udev.children-max=1 console=ttyFIQ0,115200n8" +OVERLAY_PREFIX="rv1106" +OFFSET=16 +SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_optee.sh" +UBOOT_TARGET_MAP="spl/u-boot-spl.bin u-boot.dtb u-boot-nodtb.bin;;download.bin idblock.img u-boot.itb" +BOOTSOURCE="https://github.com/radxa/u-boot.git" +BOOTBRANCH="branch:next-dev-buildroot" +BOOTPATCHDIR="legacy/u-boot-rockchip-buildroot" +BOOTDIR="u-boot-rockchip" + +# Set defaults based on BOOT_SOC (overridable in board config) +if [[ "$BOOT_SOC" == "rv1103" ]]; then + DDR_BLOB="${DDR_BLOB:-"rv11/rv1103b_ddr_924MHz_v1.05.bin"}" + TEE_BLOB="${TEE_BLOB:-"rv11/rv1103b_tee_ta_v1.03.bin"}" + USBPLUG_BLOB="${USBPLUG_BLOB:-"rv11/rv1103b_usbplug_v1.00.bin"}" +elif [[ "$BOOT_SOC" == "rv1106" ]]; then + DDR_BLOB="${DDR_BLOB:-"rv11/rv1106_ddr_924MHz_v1.15.bin"}" + TEE_BLOB="${TEE_BLOB:-"rv11/rv1106_tee_ta_v1.13.bin"}" + USBPLUG_BLOB="${USBPLUG_BLOB:-"rv11/rv1106_usbplug_v1.09.bin"}" +else + display_alert "$BOARD" "Unknown BOOT_SOC: ${BOOT_SOC} in rockchip-rv1106 family" "error" + exit 1 +fi + + +case $BRANCH in + + vendor) + + declare -g KERNEL_MAJOR_MINOR="6.1" # Major and minor versions of this kernel. + KERNELSOURCE='https://github.com/armbian/linux-rockchip.git' + KERNELBRANCH='branch:rk-6.1-rkr5.1' + KERNELPATCHDIR='rv1106-vendor-6.1' + ;; + +esac + +function post_config_uboot_target__downgrade_gcc_errors_to_warnings() { + + declare -i gcc_major_version=0 + gcc_major_version=$(gcc -dumpversion | cut -d. -f1) + display_alert "$BOARD" "GCC major version: ${gcc_major_version}" "debug" + + # Rockchip/Radxa U-Boot won't build with GCC 13 due to enum-int-mismatch + if [[ ${gcc_major_version} -ge 13 ]]; then + display_alert "$BOARD" "Adding extra CFLAGS to fix vendor U-Boot building with GCC 13+" "info" + uboot_cflags_array+=("-Wno-error=enum-int-mismatch") + fi + + return 0 +} + +function pre_config_uboot_target__copy_tee() { + + # Makefiles expect 'tee.bin' in the uboot build directory + display_alert "Copy TEE blob" "info" + run_host_command_logged cp ${RKBIN_DIR}/${TEE_BLOB} tee.bin + + return 0 +} + +uboot_custom_postprocess() { + + display_alert "Generate u-boot.its" "info" + run_host_command_logged $SPL_FIT_GENERATOR -t 0x03d00000 -c lzma > u-boot.its + + display_alert "Generate u-boot.itb" "info" + # Remove uboot-generated itb if exists + rm -f u-boot.itb + run_host_command_logged tools/mkimage -f u-boot.its -E u-boot.itb + + display_alert "Generate idblock.img with u-boot SPL" "debug" + RKBOOT_INI_FILE=rv1106.ini + cp $RKBIN_DIR/rv11/RV1106MINIALL.ini $RKBOOT_INI_FILE + sed -i "s|Path1=.*rv1106_ddr.*$|Path1=${RKBIN_DIR}/${DDR_BLOB}|g" $RKBOOT_INI_FILE + sed -i "s|Path1=.*rv1106_usbplug.*$|Path1=${RKBIN_DIR}/${USBPLUG_BLOB}|g" $RKBOOT_INI_FILE + sed -i "s|FlashData=.*$|FlashData=${RKBIN_DIR}/${DDR_BLOB}|g" $RKBOOT_INI_FILE + sed -i "s|FlashBoot=.*$|FlashBoot=./spl/u-boot-spl.bin|g" $RKBOOT_INI_FILE + sed -i "s|PATH=.*$|PATH=download.bin|g" $RKBOOT_INI_FILE + sed -i "s|IDB_PATH=.*$|IDB_PATH=idblock.img|g" $RKBOOT_INI_FILE + run_host_x86_binary_logged $RKBIN_DIR/tools/boot_merger $RKBOOT_INI_FILE + rm -f $RKBOOT_INI_FILE +} + +# Note that write_uboot_platform() is also used to install +# the bootloader in the proper place during live systems upgrade. +write_uboot_platform() { + # This is run board-side too, so account for the non-existance of run_host_command_logged + local logging_prelude="" + [[ $(type -t run_host_command_logged) == function ]] && logging_prelude="run_host_command_logged" + + ${logging_prelude} dd if=$1/idblock.img of=$2 bs=512 seek=$((0x40)) conv=notrunc status=none + ${logging_prelude} dd if=$1/u-boot.itb of=$2 bs=512 seek=$((0x440)) conv=notrunc status=none +} + +family_tweaks() { + + # Create gpio and i2c groups on the build rootfs; they are matched against + # udev rules to allow non-root user access to these resources + chroot_sdcard addgroup --system --quiet --gid 900 gpio + chroot_sdcard addgroup --system --quiet --gid 901 i2c + + return 0 + +} + +family_tweaks_bsp() { + mkdir -p $destination/etc/udev/rules.d + mkdir -p $destination/usr/local/bin + + # Peripheral access for specific groups + cp $SRC/packages/bsp/rockchip/70-gpio.rules $destination/etc/udev/rules.d + cp $SRC/packages/bsp/rockchip/71-i2c.rules $destination/etc/udev/rules.d + + # Sound + cp $SRC/packages/bsp/rockchip/asound.conf $destination/etc/ + + # AP6330 (BCM4330) firmware initramfs hook for in-kernel btbcm driver + if [[ "$INSTALL_ARMBIAN_FIRMWARE" == "yes" ]]; then + mkdir -p $destination/etc/initramfs-tools/hooks + install -m 550 $SRC/packages/bsp/rockchip/ap6330-initramfs-firmware $destination/etc/initramfs-tools/hooks + fi + + return 0 # exit with success +} diff --git a/config/sources/families/rockchip.conf b/config/sources/families/rockchip.conf index 41c6eaf6e..59e73c247 100644 --- a/config/sources/families/rockchip.conf +++ b/config/sources/families/rockchip.conf @@ -14,7 +14,7 @@ BOOT_SOC=${BOOT_SOC:="rk3288"} ARCH=armhf BOOTDELAY=1 -SERIALCON=ttyS2 +SERIALCON=${SERIALCON:="ttyS2"} RKBIN_DIR="$SRC/cache/sources/rkbin-tools" if [[ "$BOOT_SOC" == "rk3288" ]]; then @@ -48,7 +48,7 @@ elif [[ "$BOOT_SOC" == "rk322x" ]]; then elif [[ "$BOOT_SOC" == "rk3506" ]]; then BOOTSCRIPT="boot-rk3506.cmd:boot.cmd" - BOOTENV_FILE='rockchip.txt' + BOOTENV_FILE='rk3506.txt' OVERLAY_PREFIX='rockchip' OFFSET=16 DDR_BLOB="${DDR_BLOB:-"rk35/rk3506_ddr_750MHz_v1.06.bin"}" diff --git a/config/sources/families/spacemit.conf b/config/sources/families/spacemit.conf index c26472755..7f7aee2ae 100644 --- a/config/sources/families/spacemit.conf +++ b/config/sources/families/spacemit.conf @@ -38,9 +38,9 @@ case "${BRANCH}" in ;; edge) declare -g KERNELSOURCE="https://github.com/jmontleon/linux-bianbu.git" - declare -g KERNELBRANCH="branch:linux-6.16.y" + declare -g KERNELBRANCH="branch:linux-6.17.y" declare -g EXTRAWIFI="no" # WiFi drivers are already included in the kernel - declare -g KERNEL_MAJOR_MINOR="6.16" + declare -g KERNEL_MAJOR_MINOR="6.17" declare -g LINUXCONFIG="linux-${LINUXFAMILY}-edge" ;; esac diff --git a/config/sources/families/uefi-x86.conf b/config/sources/families/uefi-x86.conf index 6f2665785..717e18609 100644 --- a/config/sources/families/uefi-x86.conf +++ b/config/sources/families/uefi-x86.conf @@ -12,4 +12,58 @@ declare -g LINUXFAMILY="x86" declare -g ARCH="amd64" # shellcheck source=config/sources/families/include/uefi_common.inc source "${BASH_SOURCE%/*}/include/uefi_common.inc" + +case "${BRANCH}" in + + current | edge) + display_alert "extra .config for Apple T2-based x86 machines" "x86: BRANCH=${BRANCH}" "info" + + # Extra .config stuff for the Applet T2 stuff in this kernel + function custom_kernel_config__applet2() { + # From https://github.com/t2linux/linux-t2-patches/blob/6.18/extra_config ignore DRM_KUNIT_TEST + opts_y+=( + BT_HCIUART_BCM + STAGING + ) + opts_m+=( + APPLE_BCE + APPLE_GMUX + BRCMFMAC + BT_BCM + BT_HCIBCM4377 + BT_HCIUART + HID_APPLETB_BL + HID_APPLETB_KBD + HID_APPLE + HID_MAGICMOUSE + DRM_APPLETBDRM + HID_SENSOR_ALS + SENSORS_APPLESMC + SND_PCM + APFS_FS + ) + } + + # Auto-grab patches from t2linux github if not already present + if [[ ! -d "${SRC}/patch/kernel/${KERNELPATCHDIR}" ]]; then + # Grab from github .tar.gz and extract there; patches are in the root of the archive + GH_URL="https://github.com/t2linux/linux-t2-patches/archive/refs/heads/${KERNEL_MAJOR_MINOR}.tar.gz" + display_alert "Fetching Apple T2 patches from" "GH_URL=${GH_URL}" "info" + mkdir -pv "${SRC}/patch/kernel/${KERNELPATCHDIR}" + curl -L "${GH_URL}" | tar -xz --strip-components=1 -C "${SRC}/patch/kernel/${KERNELPATCHDIR}" + tree "${SRC}/patch/kernel/${KERNELPATCHDIR}" + # remove any non-patch files and directories + # remove .github and .gitignore + rm -rf "${SRC}/patch/kernel/${KERNELPATCHDIR}/.github" "${SRC}/patch/kernel/${KERNELPATCHDIR}/.gitignore" + find "${SRC}/patch/kernel/${KERNELPATCHDIR}" -type f ! -name "*.patch" -delete + display_alert "Apple T2 patches downloaded to" "DIR=${SRC}/patch/kernel/${KERNELPATCHDIR}; go run rewrite-kernel-patches" "info" + exit 0 + else + display_alert "Apple T2 patches already present in" "DIR=${SRC}/patch/kernel/${KERNELPATCHDIR}" "info" + fi + + ;; + +esac + enable_extension "grub" diff --git a/config/sources/mainline-kernel.conf.sh b/config/sources/mainline-kernel.conf.sh index dda392049..324380170 100644 --- a/config/sources/mainline-kernel.conf.sh +++ b/config/sources/mainline-kernel.conf.sh @@ -8,7 +8,7 @@ function mainline_kernel_decide_version__upstream_release_candidate_number() { [[ -n "${KERNELBRANCH}" ]] && return 0 # if already set, don't touch it; that way other hooks can run in any order if [[ "${KERNEL_MAJOR_MINOR}" == "6.18" ]]; then # @TODO: roll over to next MAJOR.MINOR and MAJOR.MINOR-rc1 when it is released - declare -g KERNELBRANCH="tag:v6.18-rc1" + declare -g KERNELBRANCH="tag:v6.18-rc6" display_alert "mainline-kernel: upstream release candidate" "Using KERNELBRANCH='${KERNELBRANCH}' for KERNEL_MAJOR_MINOR='${KERNEL_MAJOR_MINOR}'" "info" fi } diff --git a/config/templates/customize-image.sh.template b/config/templates/customize-image.sh.template index e1bb43d5e..d4e234d41 100644 --- a/config/templates/customize-image.sh.template +++ b/config/templates/customize-image.sh.template @@ -111,7 +111,7 @@ InstallOpenMediaVault() { # install OMV extras, enable folder2ram and tweak some settings FILE=$(mktemp) - wget "$OMV_EXTRAS_URL" -qO $FILE && dpkg -i $FILE + curl "$OMV_EXTRAS_URL" -fLso "$FILE" && dpkg -i "$FILE" /usr/sbin/omv-update # Install flashmemory plugin and netatalk by default, use nice logo for the latter, @@ -208,8 +208,9 @@ InstallOpenMediaVault() { # Fix little python bug upstream Debian 9 obviously ignores if [ -f /usr/lib/python3.5/weakref.py ]; then - wget -O /usr/lib/python3.5/weakref.py \ - https://raw.githubusercontent.com/python/cpython/9cd7e17640a49635d1c1f8c2989578a8fc2c1de6/Lib/weakref.py + GITREF="9cd7e17640a49635d1c1f8c2989578a8fc2c1de6" + curl -fLo /usr/lib/python3.5/weakref.py \ + "https://raw.githubusercontent.com/python/cpython/${GITREF}/Lib/weakref.py" fi # clean up and force password change on first boot @@ -226,7 +227,7 @@ UnattendedStorageBenchmark() { apt-get -qq install time - wget -qO /usr/local/bin/sd-card-bench.sh https://raw.githubusercontent.com/ThomasKaiser/sbc-bench/master/sd-card-bench.sh + curl -fLso /usr/local/bin/sd-card-bench.sh "https://raw.githubusercontent.com/ThomasKaiser/sbc-bench/master/sd-card-bench.sh" chmod 755 /usr/local/bin/sd-card-bench.sh sed -i '/^exit\ 0$/i \ diff --git a/config/templates/targets-all-kernels.yaml b/config/templates/targets-all-kernels.yaml new file mode 100644 index 000000000..f601ef4dc --- /dev/null +++ b/config/templates/targets-all-kernels.yaml @@ -0,0 +1,12 @@ +# Target file for all kernel artifacts across all non-eos boards. + +targets: + all-kernels: + pipeline: + only-artifacts: [ "kernel" ] + vars: + BUILD_MINIMAL: "yes" + BUILD_DESKTOP: "no" + RELEASE: "sid" + items-from-inventory: + not-eos: yes # not-eos boards, all branches diff --git a/extensions/fs-cryptroot-support.sh b/extensions/fs-cryptroot-support.sh index e2259e54c..0d5f619a6 100644 --- a/extensions/fs-cryptroot-support.sh +++ b/extensions/fs-cryptroot-support.sh @@ -24,9 +24,18 @@ function extension_prepare_config__prepare_cryptroot() { function prepare_root_device__250_encrypt_root_device() { # We encrypt the rootdevice (currently a loop device) and return the new mapped rootdevice check_loop_device "$rootdevice" - display_alert "Extension: ${EXTENSION}: Encrypting root partition with LUKS..." "cryptsetup luksFormat $rootdevice" "" - echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice - - echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksOpen $rootdevice $CRYPTROOT_MAPPER - + display_alert "Extension: ${EXTENSION}: Encrypting root partition with LUKS..." "cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice" "" + if [[ $CRYPTROOT_AUTOUNLOCK == "yes" ]]; then + display_alert "Extension: ${EXTENSION}: configuring LUKS autounlock" "" + declare -g cryptroot_autounlock_key_file=$(mktemp) + openssl rand -base64 32 > "$cryptroot_autounlock_key_file" + cryptsetup luksFormat $CRYPTROOT_PARAMETERS "$rootdevice" "$cryptroot_autounlock_key_file" + cryptsetup luksOpen --key-file "$cryptroot_autounlock_key_file" "$rootdevice" $CRYPTROOT_MAPPER + else # CRYPTROOT_PASSPHRASE case + display_alert "Extension: ${EXTENSION}: configuring LUKS password" "" + echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice - + echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksOpen $rootdevice $CRYPTROOT_MAPPER - + fi add_cleanup_handler cleanup_cryptroot display_alert "Extension: ${EXTENSION}: Root partition encryption complete." "" "ext" # TODO: pass /dev/mapper to Docker @@ -90,4 +99,4 @@ function post_umount_final_image__750_cryptroot_cleanup(){ function cleanup_cryptroot(){ cryptsetup luksClose "${CRYPTROOT_MAPPER}" 2>&1 display_alert "Cryptroot closed ${CRYPTROOT_MAPPER}" "${EXTENSION}" "info" -} \ No newline at end of file +} diff --git a/extensions/gen-sample-extension-docs.sh b/extensions/gen-sample-extension-docs.sh index 03963f112..fb8dd1aa9 100644 --- a/extensions/gen-sample-extension-docs.sh +++ b/extensions/gen-sample-extension-docs.sh @@ -58,6 +58,7 @@ MULTIPLE_CALLS_WARNING cat << PRE_HOOKS_HEADER ## Hooks +- Individual/specific hook functions can be [skipped/ignored/opted-out](/Developer-Guide_Extensions#opt-out-of-individual-hook-functions). - Hooks are listed in the order they are called. PRE_HOOKS_HEADER diff --git a/extensions/grub-riscv64.sh b/extensions/grub-riscv64.sh index 8455c83ac..b665291eb 100644 --- a/extensions/grub-riscv64.sh +++ b/extensions/grub-riscv64.sh @@ -15,6 +15,10 @@ function extension_prepare_config__prepare_grub-riscv64() { declare -g IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff. declare -g UEFISIZE=256 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions declare -g BOOTSIZE=0 # No separate /boot when using UEFI. + if [[ $BOOTPART_REQUIRED == "yes" ]]; then + # It is important to place this into /boot to have unified boot partition, especially when CRYPTROOT is used + declare -g UEFI_MOUNT_POINT=/boot + fi declare -g CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub. declare -g EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name. declare -g UEFI_GRUB_TARGET="riscv64-efi" # Default for x86_64 @@ -55,14 +59,19 @@ pre_umount_final_image__install_grub() { # Irony: let's use grub-probe to find out the UUID of the root partition, and then create a symlink to it. # Another: on some systems (eg, not Docker) the thing might already exist due to udev actually working. # shellcheck disable=SC2016 # some wierd escaping going on there. + # Root is needed so that UUID of the unlocked /dev/mapper/armbian-root is discovered by grub-update, + # UUID is then put into grub.cfg instead of raw /dev/mapper/armbian-root which will fail further sanity check chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /)"' "||" true + # Include /boot that might point to a separate boot partition in case one exists (lvm, cryptroot) + # Even if boot partition doesn't exist - the command will be the same as mkdir for / above + chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /boot)"' "||" true display_alert "Extension: ${EXTENSION}: Creating GRUB config..." "${EXTENSION}: grub-mkconfig / update-grub" chroot_custom "$chroot_target" update-grub || { exit_with_error "update-grub failed!" } - local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --no-nvram --removable" # nvram is global to the host, even across chroot. take care. + local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --efi-directory=${UEFI_MOUNT_POINT} --no-nvram --removable" # nvram is global to the host, even across chroot. take care. display_alert "Extension: ${EXTENSION}: Installing GRUB EFI..." "${EXTENSION}: ${UEFI_GRUB_TARGET}" chroot_custom "$chroot_target" "$install_grub_cmdline" || { exit_with_error "Extension: ${EXTENSION}: ${install_grub_cmdline} failed!" @@ -124,8 +133,11 @@ configure_grub() { GRUB_TIMEOUT_STYLE=menu # Show the menu with Kernel options (Armbian or -generic)... GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT} # ... for ${UEFI_GRUB_TIMEOUT} seconds, then boot the Armbian default. GRUB_DISTRIBUTOR="${UEFI_GRUB_DISTRO_NAME}" # On GRUB menu will show up as "Armbian GNU/Linux" (will show up in some UEFI BIOS boot menu (F8?) as "armbian", not on others) + GRUB_DISABLE_OS_PROBER=false # Have to be explicit about enabling os-prober GRUB_GFXMODE=1024x768 GRUB_GFXPAYLOAD=keep + GRUB_DISABLE_UUID=false # Be explicit about wanting UUID + GRUB_DISABLE_LINUX_UUID=false # Be explicit about wanting UUID grubCfgFrag if [[ "a${UEFI_GRUB_DISABLE_OS_PROBER}" != "a" ]]; then diff --git a/extensions/grub.sh b/extensions/grub.sh index fb64beba8..28ad270d5 100644 --- a/extensions/grub.sh +++ b/extensions/grub.sh @@ -16,14 +16,16 @@ function extension_prepare_config__prepare_grub_standard() { if [[ "${UEFI_GRUB}" != "skip" ]]; then # User config overrides for GRUB. - declare -g BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot. - unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot. - declare -g IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff. - declare -g UEFISIZE=260 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions - declare -g BOOTSIZE=0 # No separate /boot when using UEFI. - declare -g CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub. - declare -g EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name. - declare -g UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64 + declare -g BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot. + unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot. + declare -g IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff. + declare -g UEFISIZE=260 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions + declare -g BOOTSIZE=0 # No separate /boot when using UEFI. + if [[ $BOOTPART_REQUIRED == "yes" ]]; then # It is important to place this into /boot to have unified boot partition, especially when CRYPTROOT is used + declare -g UEFI_MOUNT_POINT=/boot + fi + declare -g EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name. + declare -g UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64 packages+=(efibootmgr efivar cloud-initramfs-growroot busybox) # Use growroot(+busybox for it to work on Bookworm), add some efi-related packages packages+=(os-prober "grub-efi-${ARCH}-bin") # This works for Ubuntu and Debian, by sheer luck; common for EFI and BIOS @@ -163,7 +165,7 @@ pre_umount_final_image__install_grub() { } fi - local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --no-nvram --removable" # nvram is global to the host, even across chroot. take care. + local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --efi-directory=${UEFI_MOUNT_POINT} --no-nvram --removable" # nvram is global to the host, even across chroot. take care. display_alert "Extension: ${EXTENSION}: Installing GRUB EFI..." "${UEFI_GRUB_TARGET}" "" chroot_custom "$chroot_target" "$install_grub_cmdline" || { exit_with_error "${install_grub_cmdline} failed!" @@ -175,7 +177,12 @@ pre_umount_final_image__install_grub() { # Irony: let's use grub-probe to find out the UUID of the root partition, and then create a symlink to it. # Another: on some systems (eg, not Docker) the thing might already exist due to udev actually working. # shellcheck disable=SC2016 # some wierd escaping going on there. + # Root is needed so that UUID of the unlocked /dev/mapper/armbian-root is discovered by grub-update, + # UUID is then put into grub.cfg instead of raw /dev/mapper/armbian-root which will fail further sanity check chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /)"' "||" true + # Include /boot that might point to a separate boot partition in case one exists (lvm, cryptroot) + # Even if boot partition doesn't exist - the command will be the same as mkdir for / above + chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /boot)"' "||" true display_alert "Extension: ${EXTENSION}: Creating GRUB config..." "grub-mkconfig" "" chroot_custom "$chroot_target" update-grub || { @@ -286,6 +293,8 @@ configure_grub() { GRUB_DISABLE_OS_PROBER=false # Have to be explicit about enabling os-prober GRUB_FONT="/usr/share/grub/unicode.pf2" # Be explicit about the font to use so Ubuntu does not freak out and mess gfxterm GRUB_GFXPAYLOAD=keep + GRUB_DISABLE_UUID=false # Be explicit about wanting UUID + GRUB_DISABLE_LINUX_UUID=false # Be explicit about wanting UUID grubCfgFrag if [[ "a${UEFI_GRUB_DISABLE_OS_PROBER}" != "a" ]]; then diff --git a/extensions/gxlimg.sh b/extensions/gxlimg.sh index 7342e92fe..e5a25ea41 100644 --- a/extensions/gxlimg.sh +++ b/extensions/gxlimg.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash function fetch_sources_tools__gxlimg() { - fetch_from_repo "https://github.com/retro98boy/gxlimg" "gxlimg" "commit:fde6a3dd0e13875a5b219389c0a6137616eaebdb" + # Branch: master, Commit date: Nov 10, 2025 (please update when updating commit ref) + fetch_from_repo "${GITHUB_SOURCE}/repk/gxlimg" "gxlimg" "commit:37a3ea072ca81bb3872441a09fe758340fd67dcb" } function build_host_tools__compile_gxlimg() { @@ -16,3 +17,91 @@ function build_host_tools__compile_gxlimg() { git rev-parse @ 2> /dev/null > .commit_id fi } + +# This function extracts bl2 and bl3x from the old FIP and repackages them with the new u-boot.bin into a FIP +# $1 path to old FIP file +# $2 SoC family +function gxlimg_repack_fip_with_new_uboot() { + display_alert "${BOARD}" "Repacking FIP with new u-boot.bin" "info" + + if [[ ! -f "$1" ]]; then + exit_with_error "FIP file $1 does not exist" + fi + if [[ ! -f u-boot.bin ]]; then + exit_with_error "u-boot.bin not found under $(pwd)" + fi + + mv u-boot.bin raw-u-boot.bin + EXTRACT_DIR=$(mktemp -d) + trap 'rm -rf "$EXTRACT_DIR"' EXIT + run_host_command_logged gxlimg -e "$1" "$EXTRACT_DIR" + rm -f "${EXTRACT_DIR}/bl33.enc" + + case $2 in + gxl) + run_host_command_logged gxlimg \ + -t bl3x \ + -c raw-u-boot.bin \ + "${EXTRACT_DIR}/bl33.enc" + + run_host_command_logged gxlimg \ + -t fip \ + --bl2 "${EXTRACT_DIR}/bl2.sign" \ + --bl30 "${EXTRACT_DIR}/bl30.enc" \ + --bl301 "${EXTRACT_DIR}/bl301.enc" \ + --bl31 "${EXTRACT_DIR}/bl31.enc" \ + --bl33 "${EXTRACT_DIR}/bl33.enc" \ + u-boot.bin + ;; + + g12a | g12b) + run_host_command_logged gxlimg \ + -t bl3x \ + -s raw-u-boot.bin \ + "${EXTRACT_DIR}/bl33.enc" + + if [ -e "${EXTRACT_DIR}/lpddr3_1d.fw" ]; then + run_host_command_logged gxlimg \ + -t fip \ + --bl2 "${EXTRACT_DIR}/bl2.sign" \ + --ddrfw "${EXTRACT_DIR}/ddr4_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/ddr4_2d.fw" \ + --ddrfw "${EXTRACT_DIR}/ddr3_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/piei.fw" \ + --ddrfw "${EXTRACT_DIR}/lpddr4_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/lpddr4_2d.fw" \ + --ddrfw "${EXTRACT_DIR}/diag_lpddr4.fw" \ + --ddrfw "${EXTRACT_DIR}/aml_ddr.fw" \ + --ddrfw "${EXTRACT_DIR}/lpddr3_1d.fw" \ + --bl30 "${EXTRACT_DIR}/bl30.enc" \ + --bl31 "${EXTRACT_DIR}/bl31.enc" \ + --bl33 "${EXTRACT_DIR}/bl33.enc" \ + --rev v3 u-boot.bin + else + run_host_command_logged gxlimg \ + -t fip \ + --bl2 "${EXTRACT_DIR}/bl2.sign" \ + --ddrfw "${EXTRACT_DIR}/ddr4_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/ddr4_2d.fw" \ + --ddrfw "${EXTRACT_DIR}/ddr3_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/piei.fw" \ + --ddrfw "${EXTRACT_DIR}/lpddr4_1d.fw" \ + --ddrfw "${EXTRACT_DIR}/lpddr4_2d.fw" \ + --ddrfw "${EXTRACT_DIR}/diag_lpddr4.fw" \ + --ddrfw "${EXTRACT_DIR}/aml_ddr.fw" \ + --bl30 "${EXTRACT_DIR}/bl30.enc" \ + --bl31 "${EXTRACT_DIR}/bl31.enc" \ + --bl33 "${EXTRACT_DIR}/bl33.enc" \ + --rev v3 u-boot.bin + fi + ;; + + *) + exit_with_error "Unsupported SoC family: $2" + ;; + esac + + if [ ! -s u-boot.bin ]; then + exit_with_error "FIP repack produced empty u-boot.bin" + fi +} diff --git a/extensions/image-output-utm.sh b/extensions/image-output-utm.sh index f800fb160..994c65431 100644 --- a/extensions/image-output-utm.sh +++ b/extensions/image-output-utm.sh @@ -9,9 +9,10 @@ function extension_prepare_config__prepare_utm_config() { } function user_config__metadata_cloud_config() { - display_alert "Preparing UTM config" "${EXTENSION}" "info" - declare -g SERIALCON="ttyS0" # UTM's serial at ttyS0, for x86 @TODO: arm64? ttyAML0? - display_alert "Prepared UTM config" "${EXTENSION}: SERIALCON: '${SERIALCON}'" "debug" + display_alert "Preparing UTM config for serial console" "${EXTENSION}" "info" + declare -g SERIALCON="ttyAMA0" + [[ "${ARCH}" == "amd64" ]] && declare -g SERIALCON="ttyS0" + display_alert "Prepared UTM config for serial console" "${EXTENSION}: SERIALCON: '${SERIALCON}'" "debug" } #### *custom post build hook* diff --git a/extensions/lowmem.sh b/extensions/lowmem.sh new file mode 100644 index 000000000..a0a45ee65 --- /dev/null +++ b/extensions/lowmem.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# +# Armbian Optimizations for Low-Memory Boards +# +# Boards with less than *256MB* RAM need special optimizations to run Armbian smoothly. +# This extension applies the necessary *userland* (not-kernel) optimizations +# at build time. +# + +function post_family_tweaks_bsp__initramfs() { + local LOWMEM_TMPFS_RUN_MB=${LOWMEM_TMPFS_RUN_MB:-20} + display_alert "${EXTENSION}" "Set initramfs config for low memory" "debug" + + # Create /etc/initramfs-tools/conf.d/armbian-lowmem.conf configuration file + if [ ! -f "$destination/etc/initramfs-tools/conf.d/armbian-lowmem.conf" ]; then + mkdir -p "$destination/etc/initramfs-tools/conf.d" + install -m 644 /dev/null "$destination/etc/initramfs-tools/conf.d/armbian-lowmem.conf" + + # Load only modules needed for boot + echo "MODULES=dep" >> "$destination/etc/initramfs-tools/conf.d/armbian-lowmem.conf" + + # /run is 10% of RAM by default + # systemd throws errors when <16MB is *free* in this partition + # during daemon-reload operations. + # Address with a fixed /run size of ${LOWMEM_TMPFS_RUN_MB} + echo "RUNSIZE=${LOWMEM_TMPFS_RUN_MB}M" >> "$destination/etc/initramfs-tools/conf.d/armbian-lowmem.conf" + fi + + return 0 +} + +function post_family_tweaks_bsp__copy_lowmem_config() { + display_alert "${EXTENSION}" "Installing default configuration" "debug" + + # Copy /etc/default/armbian-lowmem configuration file + # Allows user to customize swapfile size / location + if [ ! -f "$destination/etc/default/armbian-lowmem" ]; then + install -m 664 "$SRC/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist" "$destination/etc/default/armbian-lowmem" + fi + + return 0 +} + +function post_family_tweaks_bsp__copy_lowmem_mkswap() { + local service_name="lowmem-mkswap" + # Devices with very low memory need a swapfile to operate smoothly (apt, locale-gen, etc) + display_alert "${EXTENSION}" "Installing ${service_name}.service" "debug" + + # Copy systemd service and script to create swapfile + install -m 755 "$SRC/packages/bsp/armbian-lowmem/${service_name}.sh" "$destination/usr/bin/${service_name}.sh" + install -m 644 "$SRC/packages/bsp/armbian-lowmem/${service_name}.service" "$destination/lib/systemd/system/${service_name}.service" + + return 0 +} + +function post_family_tweaks__enable_lowmem_mkswap() { + local service_name="lowmem-mkswap" + display_alert "${EXTENSION}" "Enabling ${service_name}.service" "debug" + chroot_sdcard systemctl enable "${service_name}.service" + + return 0 +} + +function pre_umount_final_image__memory_optimize_defaults() { + # Optimize /etc/default settings to reduce memory usage + display_alert "${EXTENSION}" "Disabling ramlog by default to save memory" "debug" + sed -i "s/^ENABLED=.*/ENABLED=false/" "${MOUNT}"/etc/default/armbian-ramlog + + display_alert "${EXTENSION}" "Disabling zram swap by default" "debug" + sed -i "s/^#\?\s*SWAP=.*/SWAP=false/" "${MOUNT}"/etc/default/armbian-zram-config + + return 0 +} diff --git a/extensions/radxa-aic8800.sh b/extensions/radxa-aic8800.sh index 28cc032fe..db4ef8eb8 100644 --- a/extensions/radxa-aic8800.sh +++ b/extensions/radxa-aic8800.sh @@ -10,7 +10,7 @@ function extension_finish_config__install_kernel_headers_for_aic8800_dkms() { function post_install_kernel_debs__install_aic8800_dkms_package() { - if linux-version compare "${KERNEL_MAJOR_MINOR}" ge 6.18; then + if linux-version compare "${KERNEL_MAJOR_MINOR}" ge 6.19; then display_alert "Kernel version is too recent" "skipping aic8800 dkms for kernel v${KERNEL_MAJOR_MINOR}" "warn" return 0 fi diff --git a/extensions/ti-debpkgs.sh b/extensions/ti-debpkgs.sh index 116cd3d62..fccaf6a9d 100644 --- a/extensions/ti-debpkgs.sh +++ b/extensions/ti-debpkgs.sh @@ -1,6 +1,6 @@ function extension_prepare_config__add_packages() { if [[ ${#TI_PACKAGES[@]} -gt 0 ]] ; then - add_packages_to_rootfs "${TI_PACKAGES[@]}" + add_packages_to_image "${TI_PACKAGES[@]}" fi } diff --git a/extensions/ufs.sh b/extensions/ufs.sh index ac5c6a45b..fdb311739 100644 --- a/extensions/ufs.sh +++ b/extensions/ufs.sh @@ -1,18 +1,21 @@ # Create UFS aligned image (requires >= Debian 13 (Trixie) Host) -declare -g DOCKER_ARMBIAN_BASE_IMAGE=debian:trixie +# declare -g DOCKER_ARMBIAN_BASE_IMAGE=debian:trixie # Use this env variable manually function extension_prepare_config__ufs { - # Check sfdisk version is >= 2.41 for UFS support - local sfdisk_version - if ! command -v sfdisk >/dev/null 2>&1; then - exit_with_error "sfdisk not found. Please install util-linux (provides sfdisk) >= 2.41." - fi - # Extract the util-linux version and strip any non-numeric characters for robustness - sfdisk_version="$(sfdisk --version 2>/dev/null | awk '/util-linux/ {print $NF}' | tr -cd '0-9.')" - if [[ -z "${sfdisk_version}" ]]; then - exit_with_error "Unable to determine util-linux version from 'sfdisk --version'." - fi - if linux-version compare "${sfdisk_version}" lt "2.41"; then - exit_with_error "UFS extension requires sfdisk >= 2.41 (from util-linux). Current version: ${sfdisk_version}" + # Skip version check if only generating config definitions + if [[ "${CONFIG_DEFS_ONLY}" != "yes" ]]; then + # Check sfdisk version is >= 2.41 for UFS support + local sfdisk_version + if ! command -v sfdisk >/dev/null 2>&1; then + exit_with_error "sfdisk not found. Please install util-linux (provides sfdisk) >= 2.41." + fi + # Extract the util-linux version and strip any non-numeric characters for robustness + sfdisk_version="$(sfdisk --version 2>/dev/null | awk '/util-linux/ {print $NF}' | tr -cd '0-9.')" + if [[ -z "${sfdisk_version}" ]]; then + exit_with_error "Unable to determine util-linux version from 'sfdisk --version'." + fi + if linux-version compare "${sfdisk_version}" lt "2.41"; then + exit_with_error "UFS extension requires sfdisk >= 2.41 (from util-linux). Current version: ${sfdisk_version}" + fi fi EXTRA_IMAGE_SUFFIXES+=("-ufs") declare -g SECTOR_SIZE=4096 diff --git a/lib/functions/artifacts/artifact-armbian-base-files.sh b/lib/functions/artifacts/artifact-armbian-base-files.sh index 64aa055d7..4fc3258e3 100644 --- a/lib/functions/artifacts/artifact-armbian-base-files.sh +++ b/lib/functions/artifacts/artifact-armbian-base-files.sh @@ -29,7 +29,7 @@ function artifact_armbian-base-files_prepare_version() { sleep_seconds="15" do_with_retries 10 apt_find_upstream_package_version_and_download_url "base-files" # download the file, but write it to /dev/null (just for testing it is correct) - # wget --timeout=15 --output-document=/dev/null "${found_package_down_url}" || exit_with_error "Could not download '${found_package_down_url}'" + # curl -fLo /dev/null "${found_package_down_url}" || exit_with_error "Could not download '${found_package_down_url}'" # Set readonly globals with the wanted info; will be used during the actual build of this artifact declare -g -r base_files_wanted_upstream_version="${found_package_version}" @@ -88,7 +88,7 @@ function compile_armbian-base-files() { # Download the deb file declare deb_file="${destination}/${base_files_wanted_upstream_filename}" - run_host_command_logged wget --no-verbose --timeout=60 --output-document="${deb_file}" "${base_files_wanted_deb_down_url}" || exit_with_error "Could not download '${base_files_wanted_deb_down_url}'" + run_host_command_logged curl -fLo "${deb_file}" "${base_files_wanted_deb_down_url}" || exit_with_error "Could not download '${base_files_wanted_deb_down_url}'" # Raw-Extract (with DEBIAN dir) the contents of the deb file into "${destination}" run_host_command_logged dpkg-deb --raw-extract "${deb_file}" "${destination}" || exit_with_error "Could not raw-extract '${deb_file}'" diff --git a/lib/functions/artifacts/artifact-kernel.sh b/lib/functions/artifacts/artifact-kernel.sh index 232f3d7b3..d44aefe10 100644 --- a/lib/functions/artifacts/artifact-kernel.sh +++ b/lib/functions/artifacts/artifact-kernel.sh @@ -10,6 +10,8 @@ function artifact_kernel_config_dump() { # BOARD is NOT included. See explanation below. artifact_input_variables[LINUXFAMILY]="${LINUXFAMILY}" + artifact_input_variables[LINUXCONFIG]="${LINUXCONFIG}" + artifact_input_variables[ARMBIAN_KERNEL_DEB_NAME]="${LINUXFAMILY}-${BRANCH}" artifact_input_variables[BRANCH]="${BRANCH}" artifact_input_variables[KERNEL_MAJOR_MINOR]="${KERNEL_MAJOR_MINOR}" artifact_input_variables[KERNELSOURCE]="${KERNELSOURCE}" diff --git a/lib/functions/artifacts/artifact-rootfs.sh b/lib/functions/artifacts/artifact-rootfs.sh index 5548723c0..ae1be1fa7 100644 --- a/lib/functions/artifacts/artifact-rootfs.sh +++ b/lib/functions/artifacts/artifact-rootfs.sh @@ -15,6 +15,7 @@ function artifact_rootfs_config_dump() { artifact_input_variables[DESKTOP_ENVIRONMENT]="${DESKTOP_ENVIRONMENT:-"no_DESKTOP_ENVIRONMENT_set"}" artifact_input_variables[DESKTOP_ENVIRONMENT_CONFIG_NAME]="${DESKTOP_ENVIRONMENT_CONFIG_NAME:-"no_DESKTOP_ENVIRONMENT_CONFIG_NAME_set"}" artifact_input_variables[DESKTOP_APPGROUPS_SELECTED]="${DESKTOP_APPGROUPS_SELECTED:-"no_DESKTOP_APPGROUPS_SELECTED_set"}" + artifact_input_variables[LEGACY_DEBOOTSTRAP]="${LEGACY_DEBOOTSTRAP:-"no"}" # Hash of the packages added/removed by extensions declare pkgs_hash="undetermined" pkgs_hash="$(echo "${REMOVE_PACKAGES[*]} ${EXTRA_PACKAGES_ROOTFS[*]} ${PACKAGE_LIST_BOARD_REMOVE} ${PACKAGE_LIST_FAMILY_REMOVE}" | sha256sum | cut -d' ' -f1)" diff --git a/lib/functions/bsp/armbian-bsp-cli-deb.sh b/lib/functions/bsp/armbian-bsp-cli-deb.sh index 6682dcd8e..b24d1bf48 100644 --- a/lib/functions/bsp/armbian-bsp-cli-deb.sh +++ b/lib/functions/bsp/armbian-bsp-cli-deb.sh @@ -141,7 +141,22 @@ function compile_armbian-bsp-cli() { EOF # Using bootscript, copy it to /usr/share/armbian - run_host_command_logged cp -pv "${bootscript_info[bootscript_file_fullpath]}" "${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" + + case "${bootscript_info[bootscript_src]}" in + *'.template') + display_alert "Rendering boot script template" "${bootscript_info[bootscript_file_fullpath]} -> ${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" "info" + run_host_command_logged cat "${bootscript_info[bootscript_file_fullpath]}" | + render_bootscript_template > "${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" + + if ! proof_rendered_bootscript_template "${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" ; then + exit_with_error "Render of bootscript template was not successful. Inspect '${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}' for unrendered variables." + fi + ;; + *) + display_alert "Deploying boot script" "${bootscript_info[bootscript_file_fullpath]} -> ${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" "info" + run_host_command_logged cp -pv "${bootscript_info[bootscript_file_fullpath]}" "${destination}/usr/share/armbian/${bootscript_info[bootscript_dst]}" + ;; + esac if [[ "${bootscript_info[has_bootenv]}" == "yes" ]]; then run_host_command_logged cp -pv "${bootscript_info[bootenv_file_fullpath]}" "${destination}"/usr/share/armbian/armbianEnv.txt diff --git a/lib/functions/cli/cli-jsoninfo.sh b/lib/functions/cli/cli-jsoninfo.sh index 22ee241e6..581bae92f 100644 --- a/lib/functions/cli/cli-jsoninfo.sh +++ b/lib/functions/cli/cli-jsoninfo.sh @@ -17,10 +17,12 @@ function cli_json_info_run() { prep_conf_main_minimal_ni + # shellcheck disable=SC2317 function json_info_logged() { # logging wrapper LOG_SECTION="json_info" do_with_logging json_info_only } + # shellcheck disable=SC2317 function json_info_only() { prepare_python_and_pip # requires HOSTRELEASE @@ -113,6 +115,9 @@ function cli_json_info_run() { declare IMAGE_INFO_CSV_FILE="${BASE_INFO_OUTPUT_DIR}/image-info.csv" declare INVENTORY_BOARDS_CSV_FILE="${BASE_INFO_OUTPUT_DIR}/boards-inventory.csv" declare REDUCED_ARTIFACTS_FILE="${BASE_INFO_OUTPUT_DIR}/artifacts-reduced.json" + declare REDUCED_KERNELS_FILE="${BASE_INFO_OUTPUT_DIR}/kernels.ndjson" + declare REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE="${BASE_INFO_OUTPUT_DIR}/kernels-duplicate-config.json" + declare REDUCED_UBOOTS_FILE="${BASE_INFO_OUTPUT_DIR}/uboots.ndjson" declare ARTIFACTS_INFO_FILE="${BASE_INFO_OUTPUT_DIR}/artifacts-info.json" declare ARTIFACTS_INFO_UPTODATE_FILE="${BASE_INFO_OUTPUT_DIR}/artifacts-info-uptodate.json" declare OUTDATED_ARTIFACTS_IMAGES_FILE="${BASE_INFO_OUTPUT_DIR}/outdated-artifacts-images.json" @@ -199,6 +204,29 @@ function cli_json_info_run() { if [[ ! -f "${REDUCED_ARTIFACTS_FILE}" ]]; then display_alert "Reducing info into artifacts" "artifact-reducer" "info" run_host_command_logged "${PYTHON3_VARS[@]}" "${PYTHON3_INFO[BIN]}" "${INFO_TOOLS_DIR}"/artifact-reducer.py "${IMAGE_INFO_FILE}" ">" "${REDUCED_ARTIFACTS_FILE}" + + # Simple jq to get reduced kernels, with board and branch coordinates and number of images for each; NDJSON (newline-delimited JSON) format. + jq -c '.[] | select(.artifact_name == "kernel") | {"vars": .original_inputs.vars,"kernel":.inputs.LINUXFAMILY,"needed_by":.needed_by,"ARMBIAN_KERNEL_DEB_NAME":.inputs.ARMBIAN_KERNEL_DEB_NAME,"LINUXCONFIG":.inputs.LINUXCONFIG,"KERNELSOURCE":.inputs.KERNELSOURCE,"KERNELBRANCH":.inputs.KERNELBRANCH} | {"BOARD":.vars.BOARD,"BRANCH":.vars.BRANCH,"kernel":.kernel,"needed_by":.needed_by,"ARMBIAN_KERNEL_DEB_NAME":.ARMBIAN_KERNEL_DEB_NAME,"LINUXCONFIG":.LINUXCONFIG,"KERNELSOURCE":.KERNELSOURCE,"KERNELBRANCH":.KERNELBRANCH}' < "${REDUCED_ARTIFACTS_FILE}" > "${REDUCED_KERNELS_FILE}" + + # Similar, but for u-boot's. + jq -c '.[] | select(.artifact_name == "uboot") | {"vars": .original_inputs.vars,"needed_by":.needed_by} | {"BOARD":.vars.BOARD,"BRANCH":.vars.BRANCH,"needed_by":.needed_by}' < "${REDUCED_ARTIFACTS_FILE}" > "${REDUCED_UBOOTS_FILE}" + + # Kernels: find duplicate LINUXCONFIG's across the kernels, which is a mistake. Each LINUXFAMILY should have its own LINUXCONFIG, otherwise rewrites will go insane. + display_alert "Checking for duplicate LINUXCONFIG's across kernels" "kernel-dup-linuxconfig-check" "info" + jq -s 'to_entries | map(.value) | group_by(.LINUXCONFIG) | map(select(length > 1)) | map({LINUXCONFIG: .[0].LINUXCONFIG,duplicates: map({BOARD, ARMBIAN_KERNEL_DEB_NAME, BRANCH, KERNELSOURCE, KERNELBRANCH})})' "${REDUCED_KERNELS_FILE}" > "${REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE}" + + # if "${REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE}" is larger than 3 bytes, we have duplicates; spit an error (don't exit) + if [[ $(stat -c%s "${REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE}") -gt 3 ]]; then + display_alert "Duplicate LINUXCONFIG's found!" "See ${REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE} for details" "err" + run_host_command_logged jq -C '.' "${REDUCED_KERNELS_DUPLICATE_LINUXCONFIG_FILE}" + else + display_alert "No duplicate LINUXCONFIG's found" "all good" "info" + fi + fi + + if [[ "${ARMBIAN_COMMAND}" == "inventory-artifacts" ]]; then + display_alert "Done with" "inventory-artifacts" "info" + return 0 fi # The artifact info extractor. diff --git a/lib/functions/cli/commands.sh b/lib/functions/cli/commands.sh index 6345ef4e6..d1c8bf7f1 100644 --- a/lib/functions/cli/commands.sh +++ b/lib/functions/cli/commands.sh @@ -27,15 +27,16 @@ function armbian_register_commands() { ["config-dump-json"]="config_dump_json" # implemented in cli_config_dump_json_pre_run and cli_config_dump_json_run ["config-dump-no-json"]="config_dump_json" # implemented in cli_config_dump_json_pre_run and cli_config_dump_json_run - ["inventory"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["targets"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["targets-dashboard"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["inventory-boards"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["targets-composed"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["debs-to-repo-json"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["gha-matrix"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["gha-workflow"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run - ["gha-template"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["inventory"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["targets"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["targets-dashboard"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["inventory-boards"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["inventory-artifacts"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["targets-composed"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["debs-to-repo-json"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["gha-matrix"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["gha-workflow"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run + ["gha-template"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run # These probably should be in their own separate CLI commands file, but for now they're together in jsoninfo. ["debs-to-repo-download"]="json_info" # implemented in cli_json_info_pre_run and cli_json_info_run @@ -118,6 +119,7 @@ function armbian_register_commands() { # inventory ["inventory-boards"]="TARGETS_FILE='something_that_does_not_exist_so_defaults_are_used'" + ["inventory-artifacts"]="TARGETS_FILE='something_that_does_not_exist_so_defaults_are_used'" # patching ["rewrite-kernel-patches"]="REWRITE_PATCHES='yes'" # rewrite the patches after round-tripping to git: "rebase patches" diff --git a/lib/functions/compilation/armbian-kernel.sh b/lib/functions/compilation/armbian-kernel.sh index 17bf4f5e8..0ac42c788 100644 --- a/lib/functions/compilation/armbian-kernel.sh +++ b/lib/functions/compilation/armbian-kernel.sh @@ -8,93 +8,72 @@ # https://github.com/armbian/build/ # Forced .config options for all Armbian kernels. + +# IMPORTANT: +# armbian_kernel_config hooks are called twice: once for obtaining the version via hashing, +# and once for actually modifying the kernel .config. They *must* be consistent, and can't depend on +# the contents of the .config (which is not available during version calculation). +# +# To facilitate this, use the arrays opts_n/opts_y/opts_m and/or the opts_val dictionary. +# those will be hashed and applied at the correct moments automatically. +# +# Be consistent -- both the versioning/hashing mechanism and the fast-rebuild principles depend on it. +# +# A word on modules or built-in: try use modules if possible. Certain things should be built-in, +# specially if they're needed before the initramfs is available. +# +# The exact same also applies to custom_kernel_config hooks. + # Please note: Manually changing options doesn't check the validity of the .config file. This is done at next make time. Check for warnings in build log. # Enables additional wireless configuration options for Wi-Fi drivers on kernels 6.13 and later. -# -# This internal function updates the kernel configuration by adding necessary wireless options -# to a global modification list, and if a .config file exists, it applies these changes directly. -# It ensures that settings for wireless drivers (e.g. cfg80211 and mac80211) are properly enabled +# ensures that settings for wireless drivers (e.g. cfg80211 and mac80211) are properly enabled # to avoid build errors due to recent kernel updates. -# -# Globals: -# KERNEL_MAJOR_MINOR - Current kernel version in major.minor format. -# kernel_config_modifying_hashes - Array accumulating configuration changes. -# function armbian_kernel_config__extrawifi_enable_wifi_opts_80211() { if linux-version compare "${KERNEL_MAJOR_MINOR}" ge 6.13; then - kernel_config_modifying_hashes+=("CONFIG_CFG80211=m" "CONFIG_MAC80211=m" "CONFIG_MAC80211_MESH=y" "CONFIG_CFG80211_WEXT=y") - if [[ -f .config ]]; then - # Required by many wifi drivers; otherwise "error: 'struct net_device' has no member named 'ieee80211_ptr'" - # In 6.13 something changed ref CONFIG_MAC80211 and CONFIG_CFG80211; enable both to preserve wireless drivers - kernel_config_set_m CONFIG_CFG80211 - kernel_config_set_m CONFIG_MAC80211 - kernel_config_set_y CONFIG_MAC80211_MESH - kernel_config_set_y CONFIG_CFG80211_WEXT - fi + # Required by many wifi drivers; otherwise "error: 'struct net_device' has no member named 'ieee80211_ptr'" + # In 6.13 something changed ref MAC80211 and CFG80211; enable both to preserve wireless drivers + opts_m+=("CFG80211") + opts_m+=("MAC80211") + opts_y+=("MAC80211_MESH") + opts_y+=("CFG80211_WEXT") fi } # Enables the NETKIT kernel configuration option for kernels version 6.7 and above. -# -# Globals: -# KERNEL_MAJOR_MINOR - The kernel version string used to verify the minimum required version. -# -# This function checks if the current kernel's version is at least 6.7 and confirms the presence of a .config file. -# If both conditions are met, it alerts the user about enabling NETKIT and sets the NETKIT option to 'y' in the kernel configuration. -# function armbian_kernel_config__netkit() { if linux-version compare "${KERNEL_MAJOR_MINOR}" ge 6.7; then - if [[ -f .config ]]; then - display_alert "Enable NETKIT=y" "armbian-kernel" "debug" - kernel_config_set_y NETKIT - fi + opts_y+=("NETKIT") fi } # Disables various kernel configuration options that conflict with Armbian's kernel build requirements. -# -# Globals: -# kernel_config_modifying_hashes - Array tracking the configuration option changes. -# -# Outputs: -# Displays alerts to notify about the configuration changes being applied. -# -# Description: -# This function disables several kernel configuration options such as -# module signing and automatic versioning to speed up the build -# process and ensure compatibility with Armbian requirements. -# Additionally, it forces EXPERT mode (EXPERT=y) to ensure otherwise -# hidden configurations are visible. All modifications are only -# performed if the .config file exists. -# +# This function disables several kernel configuration options such as +# module signing and automatic versioning to speed up the build +# process and ensure compatibility with Armbian requirements. +# Additionally, it forces EXPERT mode (EXPERT=y) to ensure otherwise +# hidden configurations are visible. function armbian_kernel_config__disable_various_options() { - kernel_config_modifying_hashes+=("CONFIG_MODULE_SIG=n" "CONFIG_LOCALVERSION_AUTO=n" "EXPERT=y") - if [[ -f .config ]]; then - display_alert "Enable CONFIG_EXPERT=y" "armbian-kernel" "debug" - kernel_config_set_y EXPERT # Too many config options are hidden behind EXPERT=y, lets have it always on + display_alert "Enable EXPERT=y" "armbian-kernel" "debug" + opts_y+=("EXPERT") # Too many config options are hidden behind EXPERT=y, lets have it always on - display_alert "Disabling module signing / debug / auto version" "armbian-kernel" "debug" - kernel_config_set_n CONFIG_SECURITY_LOCKDOWN_LSM - kernel_config_set_n CONFIG_MODULE_SIG # No use signing modules - kernel_config_set_n CONFIG_MODULE_SIG_ALL # No use auto-signing modules - kernel_config_set_n MODULE_SIG_FORCE # No forcing of module sign verification - kernel_config_set_n IMA_APPRAISE_MODSIG # No appraisal module-style either + display_alert "Disabling module signing / debug / auto version" "armbian-kernel" "debug" + opts_n+=("SECURITY_LOCKDOWN_LSM") + opts_n+=("MODULE_SIG") # No use signing modules + opts_n+=("MODULE_SIG_ALL") # No use auto-signing modules + opts_n+=("MODULE_SIG_FORCE") # No forcing of module sign verification + opts_n+=("IMA_APPRAISE_MODSIG") # No appraisal module-style either - # DONE: Disable: version shenanigans - kernel_config_set_n CONFIG_LOCALVERSION_AUTO # This causes a mismatch between what Armbian wants and what make produces. - kernel_config_set_string CONFIG_LOCALVERSION '""' # Must be empty; make is later invoked with LOCALVERSION and it adds up - fi + # DONE: Disable: version shenanigans + opts_n+=("LOCALVERSION_AUTO") # This causes a mismatch between what Armbian wants and what make produces. + opts_val["LOCALVERSION"]='""' # Must be empty; make is later invoked with LOCALVERSION and it adds up } function armbian_kernel_config__force_pa_va_48_bits_on_arm64() { - declare -A opts_val=() - declare -a opts_y=() opts_n=() if [[ "${ARCH}" == "arm64" ]]; then - opts_y+=("CONFIG_ARM64_VA_BITS_48") - opts_val["CONFIG_ARM64_PA_BITS"]="48" + opts_y+=("ARM64_VA_BITS_48") + opts_val["ARM64_PA_BITS"]="48" fi - armbian_kernel_config_apply_opts_from_arrays } # Configures kernel options to enable or disable eBPF and BTF debug information. @@ -118,15 +97,11 @@ function armbian_kernel_config__force_pa_va_48_bits_on_arm64() { # # Returns: # 0 on successful configuration application. -# function armbian_kernel_config__600_enable_ebpf_and_btf_info() { - declare -A opts_val=() - declare -a opts_y=() opts_n=() - if [[ "${KERNEL_BTF}" == "no" ]]; then # If user is explicit by passing "KERNEL_BTF=no", then actually disable all debug info. display_alert "Disabling eBPF and BTF info for kernel" "as requested by KERNEL_BTF=no" "info" - opts_y+=("CONFIG_DEBUG_INFO_NONE") # Enable the "none" option - opts_n+=("CONFIG_DEBUG_INFO" "CONFIG_DEBUG_INFO_DWARF5" "CONFIG_DEBUG_INFO_BTF" "CONFIG_DEBUG_INFO_BTF_MODULES") # BTF & CO-RE == off + opts_y+=("DEBUG_INFO_NONE") # Enable the "none" option + opts_n+=("DEBUG_INFO" "DEBUG_INFO_DWARF5" "DEBUG_INFO_BTF" "DEBUG_INFO_BTF_MODULES") # BTF & CO-RE == off # We don't disable the eBPF options, as eBPF itself doesn't require BTF (debug info) and doesnt' consume as much memory during build as BTF debug info does. else declare -i available_physical_memory_mib @@ -142,362 +117,325 @@ function armbian_kernel_config__600_enable_ebpf_and_btf_info() { fi display_alert "Enabling eBPF and BTF info" "for fully BTF & CO-RE enabled kernel" "info" - opts_n+=("CONFIG_DEBUG_INFO_NONE") # Make sure the "none" option is disabled + opts_n+=("DEBUG_INFO_NONE") # Make sure the "none" option is disabled opts_y+=( - "CONFIG_BPF_JIT" "CONFIG_BPF_JIT_DEFAULT_ON" "CONFIG_FTRACE_SYSCALLS" "CONFIG_PROBE_EVENTS_BTF_ARGS" "CONFIG_BPF_KPROBE_OVERRIDE" # eBPF == on - "CONFIG_DEBUG_INFO" "CONFIG_DEBUG_INFO_DWARF5" "CONFIG_DEBUG_INFO_BTF" "CONFIG_DEBUG_INFO_BTF_MODULES" # BTF & CO-RE == off + "BPF_JIT" "BPF_JIT_DEFAULT_ON" "FTRACE_SYSCALLS" "PROBE_EVENTS_BTF_ARGS" "BPF_KPROBE_OVERRIDE" # eBPF == on + "DEBUG_INFO" "DEBUG_INFO_DWARF5" "DEBUG_INFO_BTF" "DEBUG_INFO_BTF_MODULES" # BTF & CO-RE == off ) fi - armbian_kernel_config_apply_opts_from_arrays - - return 0 } # Enables ZRAM support by configuring the kernel for compressed memory swap. -# -# This function appends "CONFIG_ZRAM=y" to the global array tracking kernel modifications. -# If a .config file is present, it sets several related kernel options: # - Enables compressed swap space (ZSWAP). # - Sets the default compression pool for ZSWAP to ZBUD. # - Activates the compressed memory allocator (ZSMALLOC). # - Enables in-memory compression for swap or temporary storage (ZRAM). # - Allows write-back of compressed ZRAM data (ZRAM_WRITEBACK). # - Enables memory usage tracking for ZRAM (ZRAM_MEMORY_TRACKING). -# -# Globals: -# kernel_config_modifying_hashes - Array used to store configuration changes. -# +# - Enables various ZRAM compression backend algorithms (LZ4, LZ4HC, ZSTD, DEFLATE, 842, LZO). function armbian_kernel_config__enable_zram_support() { - kernel_config_modifying_hashes+=("CONFIG_ZRAM=y") - if [[ -f .config ]]; then - kernel_config_set_y ZSWAP # Enables compressed swap space in memory - kernel_config_set_y ZSWAP_ZPOOL_DEFAULT_ZBUD # Sets default compression pool for ZSWAP to ZBUD - kernel_config_set_m ZSMALLOC # Enables compressed memory allocator for better memory usage - kernel_config_set_m ZRAM # Enables in-memory block device compression for swap or temporary storage - kernel_config_set_y ZRAM_WRITEBACK # Allows write-back of compressed ZRAM data to storage - kernel_config_set_y ZRAM_MEMORY_TRACKING # Enables tracking of memory usage in ZRAM - fi + opts_y+=("ZSWAP") # Enables compressed swap space in memory + opts_y+=("ZSWAP_ZPOOL_DEFAULT_ZBUD") # Sets default compression pool for ZSWAP to ZBUD + opts_m+=("ZSMALLOC") # Enables compressed memory allocator for better memory usage + opts_m+=("ZRAM") # Enables in-memory block device compression for swap or temporary storage + opts_y+=("ZRAM_WRITEBACK") # Allows write-back of compressed ZRAM data to storage + opts_y+=("ZRAM_MEMORY_TRACKING") # Enables tracking of memory usage in ZRAM + opts_y+=("ZRAM_BACKEND_LZ4") + opts_y+=("ZRAM_BACKEND_LZ4HC") + opts_y+=("ZRAM_BACKEND_ZSTD") + opts_y+=("ZRAM_BACKEND_DEFLATE") + opts_y+=("ZRAM_BACKEND_842") + opts_y+=("ZRAM_BACKEND_LZO") } -# Enables almost all IPTABLES/NFTABLES options as modules [whilst -# allowing them to be built-in]. no particular modules are intentionally -# excluded, but this author doesn't want to claim it's 100.00% -# comprehensive, in case more are added or some oversight is found. -# split in part from armbian_kernel_config__enable_docker_support. -# +# Enables almost all IPTABLES/NFTABLES options as modules. function armbian_kernel_config__select_nftables() { - if [[ -f .config ]]; then - kernel_config_set_m BRIDGE_NETFILTER # Enables netfilter support for the bridge - kernel_config_set_m IP6_NF_FILTER # Enables IPv6 netfilter filtering support - kernel_config_set_m IP6_NF_IPTABLES # IP6 tables support (required for filtering) - kernel_config_set_m IP6_NF_MANGLE # Enables IPv6 netfilter mangling support - kernel_config_set_m IP6_NF_MATCH_AH # "ah" match support - kernel_config_set_m IP6_NF_MATCH_EUI64 # "eui64" address check - kernel_config_set_m IP6_NF_MATCH_FRAG # "frag" Fragmentation header match support - kernel_config_set_m IP6_NF_MATCH_HL # "hl" hoplimit match support - kernel_config_set_m IP6_NF_MATCH_IPV6HEADER # "ipv6header" IPv6 Extension Headers Match - kernel_config_set_m IP6_NF_MATCH_MH # "mh" match support - kernel_config_set_m IP6_NF_MATCH_OPTS # "hbh" hop-by-hop and "dst" opts header match support - kernel_config_set_m IP6_NF_MATCH_RPFILTER # "rpfilter" reverse path filter match support - kernel_config_set_m IP6_NF_MATCH_RT # "rt" Routing header match support - kernel_config_set_m IP6_NF_MATCH_SRH # "srh" Segment Routing header match support - kernel_config_set_m IP6_NF_NAT # Enables IPv6 network address translation support - kernel_config_set_m IP6_NF_RAW # Enables raw support for IPv6 netfilter - kernel_config_set_m IP6_NF_SECURITY # Enables IPv6 netfilter security features - kernel_config_set_m IP6_NF_TARGET_HL # "HL" hoplimit target support - kernel_config_set_m IP6_NF_TARGET_MASQUERADE # Enables IPv6 netfilter target for masquerading (NAT) - kernel_config_set_m IP6_NF_TARGET_NPT # NPT (Network Prefix translation) target support - kernel_config_set_m IP6_NF_TARGET_REJECT # REJECT target support - kernel_config_set_m IP6_NF_TARGET_SYNPROXY # SYNPROXY target support - kernel_config_set_m IP_NF_IPTABLES # Enables iptables for IPv4 - kernel_config_set_m IP_NF_FILTER # filter table - kernel_config_set_m IP_NF_MANGLE # mangle table - kernel_config_set_m IP_NF_TARGET_MASQUERADE # Enables IPv4 netfilter target for masquerading (NAT) - kernel_config_set_m IP_NF_TARGET_NETMAP # Enables IPv4 netfilter target for netmap - kernel_config_set_m IP_NF_TARGET_REDIRECT # Enables IPv4 netfilter target for redirect - kernel_config_set_m IP_NF_NAT # Enables NAT (Network Address Translation) support for IPv4 - kernel_config_set_m IP_NF_RAW # Enables raw support for IPv4 netfilter - kernel_config_set_m IP_NF_SECURITY # Enables security features for IPv4 netfilter - kernel_config_set_m NET_ACT_IPT - kernel_config_set_m NET_EMATCH_IPT # IPtables Matches - kernel_config_set_y NETFILTER_BPF_LINK # BPF link support for netfilter hooks - kernel_config_set_m NETFILTER_CONNCOUNT - kernel_config_set_y NETFILTER_EGRESS # Netfilter egress support - kernel_config_set_y NETFILTER_FAMILY_ARP - kernel_config_set_y NETFILTER_FAMILY_BRIDGE - kernel_config_set_y NETFILTER_INGRESS # Netfilter ingress support - kernel_config_set_m NETFILTER_NETLINK_ACCT # Netfilter NFACCT over NFNETLINK interface - kernel_config_set_y NETFILTER_NETLINK_GLUE_CT - kernel_config_set_m NETFILTER_NETLINK_HOOK # Netfilter base hook dump support - kernel_config_set_m NETFILTER_NETLINK_LOG # Netfilter LOG over NFNETLINK interface - kernel_config_set_m NETFILTER_NETLINK - kernel_config_set_m NETFILTER_NETLINK_OSF # Netfilter OSF over NFNETLINK interface - kernel_config_set_m NETFILTER_NETLINK_QUEUE # Netfilter NFQUEUE over NFNETLINK interface - kernel_config_set_m NETFILTER_SYNPROXY - kernel_config_set_y NETFILTER_XTABLES_COMPAT # Netfilter Xtables 32bit support - kernel_config_set_m NETFILTER_XTABLES # Enables x_tables support in netfilter - kernel_config_set_m NETFILTER_XT_CONNMARK # ctmark target and match support - kernel_config_set_m NETFILTER_XT_MARK # Enables mark matching for netfilter - kernel_config_set_m NETFILTER_XT_MATCH_ADDRTYPE # Enables address type matching for netfilter - kernel_config_set_m NETFILTER_XT_MATCH_BPF # Enables BPF match support in netfilter - kernel_config_set_m NETFILTER_XT_MATCH_CGROUP # "control group" match support - kernel_config_set_m NETFILTER_XT_MATCH_CLUSTER # "cluster" match support - kernel_config_set_m NETFILTER_XT_MATCH_COMMENT # "comment" match support - kernel_config_set_m NETFILTER_XT_MATCH_CONNBYTES # "connbytes" per-connection counter match support - kernel_config_set_m NETFILTER_XT_MATCH_CONNLABEL # "connlabel" match support - kernel_config_set_m NETFILTER_XT_MATCH_CONNLIMIT # "connlimit" match support - kernel_config_set_m NETFILTER_XT_MATCH_CONNMARK # "connmark" connection mark match support - kernel_config_set_m NETFILTER_XT_MATCH_CONNTRACK # Enables connection tracking match support in netfilter - kernel_config_set_m NETFILTER_XT_MATCH_CPU # "cpu" match support - kernel_config_set_m NETFILTER_XT_MATCH_DCCP # "dccp" protocol match support - kernel_config_set_m NETFILTER_XT_MATCH_DEVGROUP # "devgroup" match support - kernel_config_set_m NETFILTER_XT_MATCH_DSCP # "dscp" and "tos" match support - kernel_config_set_m NETFILTER_XT_MATCH_ECN # "ecn" match support - kernel_config_set_m NETFILTER_XT_MATCH_ESP # "esp" match support - kernel_config_set_m NETFILTER_XT_MATCH_HASHLIMIT # "hashlimit" match support - kernel_config_set_m NETFILTER_XT_MATCH_HELPER # "helper" match support - kernel_config_set_m NETFILTER_XT_MATCH_HL # "hl" hoplimit/TTL match support - kernel_config_set_m NETFILTER_XT_MATCH_IPCOMP # "ipcomp" match support - kernel_config_set_m NETFILTER_XT_MATCH_IPRANGE # "iprange" address range match support - kernel_config_set_m NETFILTER_XT_MATCH_IPVS # Enables IPVS match support in netfilter - kernel_config_set_m NETFILTER_XT_MATCH_L2TP # "l2tp" match support - kernel_config_set_m NETFILTER_XT_MATCH_LENGTH # "length" match support - kernel_config_set_m NETFILTER_XT_MATCH_LIMIT # "limit" match support - kernel_config_set_m NETFILTER_XT_MATCH_MAC # "mac" address match support - kernel_config_set_m NETFILTER_XT_MATCH_MARK # "mark" match support - kernel_config_set_m NETFILTER_XT_MATCH_MULTIPORT # "multiport" Multiple port match support - kernel_config_set_m NETFILTER_XT_MATCH_NFACCT # "nfacct" match support - kernel_config_set_m NETFILTER_XT_MATCH_OSF # "osf" Passive OS fingerprint match - kernel_config_set_m NETFILTER_XT_MATCH_OWNER # "owner" match support - kernel_config_set_m NETFILTER_XT_MATCH_PHYSDEV # "physdev" match support - kernel_config_set_m NETFILTER_XT_MATCH_PKTTYPE # "pkttype" packet type match support - kernel_config_set_m NETFILTER_XT_MATCH_POLICY # IPsec "policy" match support - kernel_config_set_m NETFILTER_XT_MATCH_QUOTA # "quota" match support - kernel_config_set_m NETFILTER_XT_MATCH_RATEEST # "rateest" match support - kernel_config_set_m NETFILTER_XT_MATCH_REALM # "realm" match support - kernel_config_set_m NETFILTER_XT_MATCH_RECENT # "recent" match support - kernel_config_set_m NETFILTER_XT_MATCH_SCTP # "sctp" protocol match support - kernel_config_set_m NETFILTER_XT_MATCH_SOCKET # "socket" match support - kernel_config_set_m NETFILTER_XT_MATCH_STATE # "state" match support - kernel_config_set_m NETFILTER_XT_MATCH_STATISTIC # "statistic" match support - kernel_config_set_m NETFILTER_XT_MATCH_STRING # "string" match support - kernel_config_set_m NETFILTER_XT_MATCH_TCPMSS # "tcpmss" match support - kernel_config_set_m NETFILTER_XT_MATCH_TIME # "time" match support - kernel_config_set_m NETFILTER_XT_MATCH_U32 # "u32" match support - kernel_config_set_m NETFILTER_XT_NAT # "SNAT and DNAT" targets support - kernel_config_set_m NETFILTER_XT_SET # set target and match support - kernel_config_set_m NETFILTER_XT_TARGET_AUDIT # AUDIT target support - kernel_config_set_m NETFILTER_XT_TARGET_CHECKSUM # CHECKSUM target support - kernel_config_set_m NETFILTER_XT_TARGET_CLASSIFY # "CLASSIFY" target support - kernel_config_set_m NETFILTER_XT_TARGET_CONNMARK # "CONNMARK" target support - kernel_config_set_m NETFILTER_XT_TARGET_CONNSECMARK # "CONNSECMARK" target support - kernel_config_set_m NETFILTER_XT_TARGET_CT # "CT" target support - kernel_config_set_m NETFILTER_XT_TARGET_DSCP # "DSCP" and "TOS" target support - kernel_config_set_m NETFILTER_XT_TARGET_FLOWOFFLOAD - kernel_config_set_m NETFILTER_XT_TARGET_HL # "HL" hoplimit target support - kernel_config_set_m NETFILTER_XT_TARGET_HMARK # "HMARK" target support - kernel_config_set_m NETFILTER_XT_TARGET_IDLETIMER # IDLETIMER target support - kernel_config_set_m NETFILTER_XT_TARGET_LED # "LED" target support - kernel_config_set_m NETFILTER_XT_TARGET_LOG # LOG target support - kernel_config_set_m NETFILTER_XT_TARGET_MARK # "MARK" target support - kernel_config_set_m NETFILTER_XT_TARGET_MASQUERADE # Enables masquerade target for netfilter - kernel_config_set_m NETFILTER_XT_TARGET_NETMAP # "NETMAP" target support - kernel_config_set_m NETFILTER_XT_TARGET_NFLOG # "NFLOG" target support - kernel_config_set_m NETFILTER_XT_TARGET_NFQUEUE # "NFQUEUE" target Support - kernel_config_set_m NETFILTER_XT_TARGET_NOTRACK # "NOTRACK" target support (DEPRECATED) - kernel_config_set_m NETFILTER_XT_TARGET_RATEEST # "RATEEST" target support - kernel_config_set_m NETFILTER_XT_TARGET_REDIRECT # REDIRECT target support - kernel_config_set_m NETFILTER_XT_TARGET_SECMARK # "SECMARK" target support - kernel_config_set_m NETFILTER_XT_TARGET_TCPMSS # "TCPMSS" target support - kernel_config_set_m NETFILTER_XT_TARGET_TCPOPTSTRIP # "TCPOPTSTRIP" target support - kernel_config_set_m NETFILTER_XT_TARGET_TEE # "TEE" - packet cloning to alternate destination - kernel_config_set_m NETFILTER_XT_TARGET_TPROXY # "TPROXY" target transparent proxying support - kernel_config_set_m NETFILTER_XT_TARGET_TRACE # "TRACE" target support - kernel_config_set_y NETFILTER # Enables support for netfilter framework - kernel_config_set_y NETFILTER_ADVANCED # Enables advanced netfilter options - kernel_config_set_m NET_IP_TUNNEL - kernel_config_set_y NF_TABLES_ARP # ARP nf_tables support - kernel_config_set_m NF_TABLES_BRIDGE - kernel_config_set_y NF_TABLES_INET # Enables IPv4 and IPv6 support for nf_tables - kernel_config_set_y NF_TABLES_IPV4 - kernel_config_set_y NF_TABLES_IPV6 - kernel_config_set_m NF_TABLES # Enables nf_tables framework support - kernel_config_set_y NF_TABLES_NETDEV # Enables netdevice support for nf_tables - kernel_config_set_m NF_CONNTRACK # Enables connection tracking support - kernel_config_set_m NF_CONNTRACK_FTP # Enables FTP connection tracking support - kernel_config_set_m NF_CONNTRACK_IRC # Enables IRC connection tracking support - kernel_config_set_y NF_CONNTRACK_MARK # Enables connection mark support in netfilter - kernel_config_set_m NF_CONNTRACK_PPTP # Enables PPTP connection tracking support - kernel_config_set_m NF_CONNTRACK_TFTP # Enables TFTP connection tracking support - kernel_config_set_y NF_CONNTRACK_ZONES # Enables connection tracking zones support - kernel_config_set_y NF_CONNTRACK_EVENTS # Enables connection tracking events support - kernel_config_set_y NF_CONNTRACK_LABELS # Enables connection tracking labels support - kernel_config_set_m NF_NAT # Enables NAT support in nf_conntrack - kernel_config_set_m NF_NAT_MASQUERADE_IPV4 # Enables IPv4 masquerading for NAT in nf_conntrack - kernel_config_set_m NF_NAT_IPV4 # Enables IPv4 NAT support in nf_conntrack - kernel_config_set_m NF_NAT_FTP # Enables FTP NAT support in nf_conntrack - kernel_config_set_m NF_NAT_TFTP # Enables TFTP NAT support in nf_conntrack - kernel_config_set_m NFT_BRIDGE_META # Netfilter nf_table bridge meta support - kernel_config_set_m NFT_BRIDGE_REJECT # Netfilter nf_tables bridge reject support - kernel_config_set_m NFT_COMPAT_ARP - kernel_config_set_m NFT_COMPAT # Enables compatibility support for older nftables versions - kernel_config_set_m NFT_CONNLIMIT # Netfilter nf_tables connlimit module - kernel_config_set_m NFT_COUNTER - kernel_config_set_m NFT_CT # Netfilter nf_tables conntrack module - kernel_config_set_m NFT_DUP_IPV4 # IPv4 nf_tables packet duplication support - kernel_config_set_m NFT_DUP_IPV6 # IPv6 nf_tables packet duplication support - kernel_config_set_m NFT_DUP_NETDEV # Enables duplicate netdev (network device) support in nftables - kernel_config_set_m NFT_FIB_INET - kernel_config_set_m NFT_FIB_IPV4 # nf_tables fib / ip route lookup support - kernel_config_set_m NFT_FIB_IPV6 # nf_tables fib / ipv6 route lookup support - kernel_config_set_m NFT_FIB - kernel_config_set_m NFT_FIB_NETDEV # Netfilter nf_tables netdev fib lookups support - kernel_config_set_m NFT_FLOW_OFFLOAD # Netfilter nf_tables hardware flow offload module - kernel_config_set_m NFT_FWD_NETDEV # Enables forward netdev support in nftables - kernel_config_set_m NFT_HASH # Enables hash-based set operations support in nftables - kernel_config_set_m NFT_LIMIT # Netfilter nf_tables limit module - kernel_config_set_m NFT_LOG # Netfilter nf_tables log module - kernel_config_set_m NFT_MASQ - kernel_config_set_m NFT_NAT # Enables NAT (Network Address Translation) support in nftables - kernel_config_set_m NFT_NUMGEN # Netfilter nf_tables number generator module - kernel_config_set_m NFT_OBJREF - kernel_config_set_m NFT_OSF - kernel_config_set_m NFT_QUEUE # Netfilter nf_tables queue module - kernel_config_set_m NFT_QUOTA # Enables quota support in nftables - kernel_config_set_m NFT_REDIR - kernel_config_set_m NFT_REJECT_INET - kernel_config_set_m NFT_REJECT_IPV4 - kernel_config_set_m NFT_REJECT_IPV6 - kernel_config_set_m NFT_REJECT # Enables reject target support in nftables - kernel_config_set_m NFT_REJECT_NETDEV # Enables reject netdev support in nftables - kernel_config_set_m NFT_SOCKET # Enables socket operations support in nftables - kernel_config_set_m NFT_SYNPROXY # Enables SYN proxy support in nftables - kernel_config_set_m NFT_TPROXY # Enables transparent proxy support in nftables - kernel_config_set_m NFT_TUNNEL # Enables tunneling support in nftables - kernel_config_set_m NFT_XFRM # Enables transformation support in nftables - kernel_config_set_m IP_SET # IP Set core - kernel_config_set_m IP_SET_HASH_IP - kernel_config_set_m IP_SET_HASH_NET - kernel_config_set_m IP_SET_HASH_IPPORT - kernel_config_set_m IP_SET_HASH_NETPORT - kernel_config_set_m IP_SET_HASH_IPPORTNET - kernel_config_set_m IP_SET_BITMAP_IP - kernel_config_set_m IP_SET_BITMAP_PORT - fi + opts_m+=("BRIDGE_NETFILTER") # Enables netfilter support for the bridge + opts_m+=("IP6_NF_FILTER") # Enables IPv6 netfilter filtering support + opts_m+=("IP6_NF_IPTABLES") # IP6 tables support (required for filtering) + opts_m+=("IP6_NF_MANGLE") # Enables IPv6 netfilter mangling support + opts_m+=("IP6_NF_MATCH_AH") # "ah" match support + opts_m+=("IP6_NF_MATCH_EUI64") # "eui64" address check + opts_m+=("IP6_NF_MATCH_FRAG") # "frag" Fragmentation header match support + opts_m+=("IP6_NF_MATCH_HL") # "hl" hoplimit match support + opts_m+=("IP6_NF_MATCH_IPV6HEADER") # "ipv6header" IPv6 Extension Headers Match + opts_m+=("IP6_NF_MATCH_MH") # "mh" match support + opts_m+=("IP6_NF_MATCH_OPTS") # "hbh" hop-by-hop and "dst" opts header match support + opts_m+=("IP6_NF_MATCH_RPFILTER") # "rpfilter" reverse path filter match support + opts_m+=("IP6_NF_MATCH_RT") # "rt" Routing header match support + opts_m+=("IP6_NF_MATCH_SRH") # "srh" Segment Routing header match support + opts_m+=("IP6_NF_NAT") # Enables IPv6 network address translation support + opts_m+=("IP6_NF_RAW") # Enables raw support for IPv6 netfilter + opts_m+=("IP6_NF_SECURITY") # Enables IPv6 netfilter security features + opts_m+=("IP6_NF_TARGET_HL") # "HL" hoplimit target support + opts_m+=("IP6_NF_TARGET_MASQUERADE") # Enables IPv6 netfilter target for masquerading (NAT) + opts_m+=("IP6_NF_TARGET_NPT") # NPT (Network Prefix translation) target support + opts_m+=("IP6_NF_TARGET_REJECT") # REJECT target support + opts_m+=("IP6_NF_TARGET_SYNPROXY") # SYNPROXY target support + opts_m+=("IP_NF_IPTABLES") # Enables iptables for IPv4 + opts_m+=("IP_NF_FILTER") # filter table + opts_m+=("IP_NF_MANGLE") # mangle table + opts_m+=("IP_NF_TARGET_MASQUERADE") # Enables IPv4 netfilter target for masquerading (NAT) + opts_m+=("IP_NF_TARGET_NETMAP") # Enables IPv4 netfilter target for netmap + opts_m+=("IP_NF_TARGET_REDIRECT") # Enables IPv4 netfilter target for redirect + opts_m+=("IP_NF_NAT") # Enables NAT (Network Address Translation) support for IPv4 + opts_m+=("IP_NF_RAW") # Enables raw support for IPv4 netfilter + opts_m+=("IP_NF_SECURITY") # Enables security features for IPv4 netfilter + opts_m+=("NET_ACT_IPT") + opts_m+=("NET_EMATCH_IPT") # IPtables Matches + opts_y+=("NETFILTER_BPF_LINK") # BPF link support for netfilter hooks + opts_m+=("NETFILTER_CONNCOUNT") + opts_y+=("NETFILTER_EGRESS") # Netfilter egress support + opts_y+=("NETFILTER_FAMILY_ARP") + opts_y+=("NETFILTER_FAMILY_BRIDGE") + opts_y+=("NETFILTER_INGRESS") # Netfilter ingress support + opts_m+=("NETFILTER_NETLINK_ACCT") # Netfilter NFACCT over NFNETLINK interface + opts_y+=("NETFILTER_NETLINK_GLUE_CT") + opts_m+=("NETFILTER_NETLINK_HOOK") # Netfilter base hook dump support + opts_m+=("NETFILTER_NETLINK_LOG") # Netfilter LOG over NFNETLINK interface + opts_m+=("NETFILTER_NETLINK") + opts_m+=("NETFILTER_NETLINK_OSF") # Netfilter OSF over NFNETLINK interface + opts_m+=("NETFILTER_NETLINK_QUEUE") # Netfilter NFQUEUE over NFNETLINK interface + opts_m+=("NETFILTER_SYNPROXY") + opts_y+=("NETFILTER_XTABLES_COMPAT") # Netfilter Xtables 32bit support + opts_m+=("NETFILTER_XTABLES") # Enables x_tables support in netfilter + opts_m+=("NETFILTER_XT_CONNMARK") # ctmark target and match support + opts_m+=("NETFILTER_XT_MARK") # Enables mark matching for netfilter + opts_m+=("NETFILTER_XT_MATCH_ADDRTYPE") # Enables address type matching for netfilter + opts_m+=("NETFILTER_XT_MATCH_BPF") # Enables BPF match support in netfilter + opts_m+=("NETFILTER_XT_MATCH_CGROUP") # "control group" match support + opts_m+=("NETFILTER_XT_MATCH_CLUSTER") # "cluster" match support + opts_m+=("NETFILTER_XT_MATCH_COMMENT") # "comment" match support + opts_m+=("NETFILTER_XT_MATCH_CONNBYTES") # "connbytes" per-connection counter match support + opts_m+=("NETFILTER_XT_MATCH_CONNLABEL") # "connlabel" match support + opts_m+=("NETFILTER_XT_MATCH_CONNLIMIT") # "connlimit" match support + opts_m+=("NETFILTER_XT_MATCH_CONNMARK") # "connmark" connection mark match support + opts_m+=("NETFILTER_XT_MATCH_CONNTRACK") # Enables connection tracking match support in netfilter + opts_m+=("NETFILTER_XT_MATCH_CPU") # "cpu" match support + opts_m+=("NETFILTER_XT_MATCH_DCCP") # "dccp" protocol match support + opts_m+=("NETFILTER_XT_MATCH_DEVGROUP") # "devgroup" match support + opts_m+=("NETFILTER_XT_MATCH_DSCP") # "dscp" and "tos" match support + opts_m+=("NETFILTER_XT_MATCH_ECN") # "ecn" match support + opts_m+=("NETFILTER_XT_MATCH_ESP") # "esp" match support + opts_m+=("NETFILTER_XT_MATCH_HASHLIMIT") # "hashlimit" match support + opts_m+=("NETFILTER_XT_MATCH_HELPER") # "helper" match support + opts_m+=("NETFILTER_XT_MATCH_HL") # "hl" hoplimit/TTL match support + opts_m+=("NETFILTER_XT_MATCH_IPCOMP") # "ipcomp" match support + opts_m+=("NETFILTER_XT_MATCH_IPRANGE") # "iprange" address range match support + opts_m+=("NETFILTER_XT_MATCH_IPVS") # Enables IPVS match support in netfilter + opts_m+=("NETFILTER_XT_MATCH_L2TP") # "l2tp" match support + opts_m+=("NETFILTER_XT_MATCH_LENGTH") # "length" match support + opts_m+=("NETFILTER_XT_MATCH_LIMIT") # "limit" match support + opts_m+=("NETFILTER_XT_MATCH_MAC") # "mac" address match support + opts_m+=("NETFILTER_XT_MATCH_MARK") # "mark" match support + opts_m+=("NETFILTER_XT_MATCH_MULTIPORT") # "multiport" Multiple port match support + opts_m+=("NETFILTER_XT_MATCH_NFACCT") # "nfacct" match support + opts_m+=("NETFILTER_XT_MATCH_OSF") # "osf" Passive OS fingerprint match + opts_m+=("NETFILTER_XT_MATCH_OWNER") # "owner" match support + opts_m+=("NETFILTER_XT_MATCH_PHYSDEV") # "physdev" match support + opts_m+=("NETFILTER_XT_MATCH_PKTTYPE") # "pkttype" packet type match support + opts_m+=("NETFILTER_XT_MATCH_POLICY") # IPsec "policy" match support + opts_m+=("NETFILTER_XT_MATCH_QUOTA") # "quota" match support + opts_m+=("NETFILTER_XT_MATCH_RATEEST") # "rateest" match support + opts_m+=("NETFILTER_XT_MATCH_REALM") # "realm" match support + opts_m+=("NETFILTER_XT_MATCH_RECENT") # "recent" match support + opts_m+=("NETFILTER_XT_MATCH_SCTP") # "sctp" protocol match support + opts_m+=("NETFILTER_XT_MATCH_SOCKET") # "socket" match support + opts_m+=("NETFILTER_XT_MATCH_STATE") # "state" match support + opts_m+=("NETFILTER_XT_MATCH_STATISTIC") # "statistic" match support + opts_m+=("NETFILTER_XT_MATCH_STRING") # "string" match support + opts_m+=("NETFILTER_XT_MATCH_TCPMSS") # "tcpmss" match support + opts_m+=("NETFILTER_XT_MATCH_TIME") # "time" match support + opts_m+=("NETFILTER_XT_MATCH_U32") # "u32" match support + opts_m+=("NETFILTER_XT_NAT") # "SNAT and DNAT" targets support + opts_m+=("NETFILTER_XT_SET") # set target and match support + opts_m+=("NETFILTER_XT_TARGET_AUDIT") # AUDIT target support + opts_m+=("NETFILTER_XT_TARGET_CHECKSUM") # CHECKSUM target support + opts_m+=("NETFILTER_XT_TARGET_CLASSIFY") # "CLASSIFY" target support + opts_m+=("NETFILTER_XT_TARGET_CONNMARK") # "CONNMARK" target support + opts_m+=("NETFILTER_XT_TARGET_CONNSECMARK") # "CONNSECMARK" target support + opts_m+=("NETFILTER_XT_TARGET_CT") # "CT" target support + opts_m+=("NETFILTER_XT_TARGET_DSCP") # "DSCP" and "TOS" target support + opts_m+=("NETFILTER_XT_TARGET_FLOWOFFLOAD") + opts_m+=("NETFILTER_XT_TARGET_HL") # "HL" hoplimit target support + opts_m+=("NETFILTER_XT_TARGET_HMARK") # "HMARK" target support + opts_m+=("NETFILTER_XT_TARGET_IDLETIMER") # IDLETIMER target support + opts_m+=("NETFILTER_XT_TARGET_LED") # "LED" target support + opts_m+=("NETFILTER_XT_TARGET_LOG") # LOG target support + opts_m+=("NETFILTER_XT_TARGET_MARK") # "MARK" target support + opts_m+=("NETFILTER_XT_TARGET_MASQUERADE") # Enables masquerade target for netfilter + opts_m+=("NETFILTER_XT_TARGET_NETMAP") # "NETMAP" target support + opts_m+=("NETFILTER_XT_TARGET_NFLOG") # "NFLOG" target support + opts_m+=("NETFILTER_XT_TARGET_NFQUEUE") # "NFQUEUE" target Support + opts_m+=("NETFILTER_XT_TARGET_NOTRACK") # "NOTRACK" target support (DEPRECATED) + opts_m+=("NETFILTER_XT_TARGET_RATEEST") # "RATEEST" target support + opts_m+=("NETFILTER_XT_TARGET_REDIRECT") # REDIRECT target support + opts_m+=("NETFILTER_XT_TARGET_SECMARK") # "SECMARK" target support + opts_m+=("NETFILTER_XT_TARGET_TCPMSS") # "TCPMSS" target support + opts_m+=("NETFILTER_XT_TARGET_TCPOPTSTRIP") # "TCPOPTSTRIP" target support + opts_m+=("NETFILTER_XT_TARGET_TEE") # "TEE" - packet cloning to alternate destination + opts_m+=("NETFILTER_XT_TARGET_TPROXY") # "TPROXY" target transparent proxying support + opts_m+=("NETFILTER_XT_TARGET_TRACE") # "TRACE" target support + opts_y+=("NETFILTER") # Enables support for netfilter framework + opts_y+=("NETFILTER_ADVANCED") # Enables advanced netfilter options + opts_m+=("NET_IP_TUNNEL") + opts_y+=("NF_TABLES_ARP") # ARP nf_tables support + opts_m+=("NF_TABLES_BRIDGE") + opts_y+=("NF_TABLES_INET") # Enables IPv4 and IPv6 support for nf_tables + opts_y+=("NF_TABLES_IPV4") + opts_y+=("NF_TABLES_IPV6") + opts_m+=("NF_TABLES") # Enables nf_tables framework support + opts_y+=("NF_TABLES_NETDEV") # Enables netdevice support for nf_tables + opts_m+=("NF_CONNTRACK") # Enables connection tracking support + opts_m+=("NF_CONNTRACK_FTP") # Enables FTP connection tracking support + opts_m+=("NF_CONNTRACK_IRC") # Enables IRC connection tracking support + opts_y+=("NF_CONNTRACK_MARK") # Enables connection mark support in netfilter + opts_m+=("NF_CONNTRACK_PPTP") # Enables PPTP connection tracking support + opts_m+=("NF_CONNTRACK_TFTP") # Enables TFTP connection tracking support + opts_y+=("NF_CONNTRACK_ZONES") # Enables connection tracking zones support + opts_y+=("NF_CONNTRACK_EVENTS") # Enables connection tracking events support + opts_y+=("NF_CONNTRACK_LABELS") # Enables connection tracking labels support + opts_m+=("NF_NAT") # Enables NAT support in nf_conntrack + opts_m+=("NF_NAT_MASQUERADE_IPV4") # Enables IPv4 masquerading for NAT in nf_conntrack + opts_m+=("NF_NAT_IPV4") # Enables IPv4 NAT support in nf_conntrack + opts_m+=("NF_NAT_FTP") # Enables FTP NAT support in nf_conntrack + opts_m+=("NF_NAT_TFTP") # Enables TFTP NAT support in nf_conntrack + opts_m+=("NFT_BRIDGE_META") # Netfilter nf_table bridge meta support + opts_m+=("NFT_BRIDGE_REJECT") # Netfilter nf_tables bridge reject support + opts_m+=("NFT_COMPAT_ARP") + opts_m+=("NFT_COMPAT") # Enables compatibility support for older nftables versions + opts_m+=("NFT_CONNLIMIT") # Netfilter nf_tables connlimit module + opts_m+=("NFT_COUNTER") + opts_m+=("NFT_CT") # Netfilter nf_tables conntrack module + opts_m+=("NFT_DUP_IPV4") # IPv4 nf_tables packet duplication support + opts_m+=("NFT_DUP_IPV6") # IPv6 nf_tables packet duplication support + opts_m+=("NFT_DUP_NETDEV") # Enables duplicate netdev (network device) support in nftables + opts_m+=("NFT_FIB_INET") + opts_m+=("NFT_FIB_IPV4") # nf_tables fib / ip route lookup support + opts_m+=("NFT_FIB_IPV6") # nf_tables fib / ipv6 route lookup support + opts_m+=("NFT_FIB") + opts_m+=("NFT_FIB_NETDEV") # Netfilter nf_tables netdev fib lookups support + opts_m+=("NFT_FLOW_OFFLOAD") # Netfilter nf_tables hardware flow offload module + opts_m+=("NFT_FWD_NETDEV") # Enables forward netdev support in nftables + opts_m+=("NFT_HASH") # Enables hash-based set operations support in nftables + opts_m+=("NFT_LIMIT") # Netfilter nf_tables limit module + opts_m+=("NFT_LOG") # Netfilter nf_tables log module + opts_m+=("NFT_MASQ") + opts_m+=("NFT_NAT") # Enables NAT (Network Address Translation) support in nftables + opts_m+=("NFT_NUMGEN") # Netfilter nf_tables number generator module + opts_m+=("NFT_OBJREF") + opts_m+=("NFT_OSF") + opts_m+=("NFT_QUEUE") # Netfilter nf_tables queue module + opts_m+=("NFT_QUOTA") # Enables quota support in nftables + opts_m+=("NFT_REDIR") + opts_m+=("NFT_REJECT_INET") + opts_m+=("NFT_REJECT_IPV4") + opts_m+=("NFT_REJECT_IPV6") + opts_m+=("NFT_REJECT") # Enables reject target support in nftables + opts_m+=("NFT_REJECT_NETDEV") # Enables reject netdev support in nftables + opts_m+=("NFT_SOCKET") # Enables socket operations support in nftables + opts_m+=("NFT_SYNPROXY") # Enables SYN proxy support in nftables + opts_m+=("NFT_TPROXY") # Enables transparent proxy support in nftables + opts_m+=("NFT_TUNNEL") # Enables tunneling support in nftables + opts_m+=("NFT_XFRM") # Enables transformation support in nftables + opts_m+=("IP_SET") # IP Set core + opts_m+=("IP_SET_HASH_IP") + opts_m+=("IP_SET_HASH_NET") + opts_m+=("IP_SET_HASH_IPPORT") + opts_m+=("IP_SET_HASH_NETPORT") + opts_m+=("IP_SET_HASH_IPPORTNET") + opts_m+=("IP_SET_BITMAP_IP") + opts_m+=("IP_SET_BITMAP_PORT") } # Enables Docker support by configuring a comprehensive set of kernel options required for Docker functionality. -# -# Globals: -# kernel_config_modifying_hashes - Global array that tracks configuration changes to be applied. -# -# Description: -# This function appends "CONFIG_DOCKER=y" to the global modification array. If the .config file exists, -# it sets a wide range of kernel configuration options necessary for Docker, including support for -# filesystems (e.g., BTRFS, EXT4), control groups (cgroups), networking, security, and various netfilter +# sets a wide range of kernel configuration options necessary for Docker, including support for +# control groups (cgroups), networking, security, and various netfilter # components. These settings ensure that the kernel is properly configured to support containerized environments. -# +# ATTENTION: filesystems like EXT4 and BTRFS are now omitted, so it's each kernel's .config responsibility to enable +# them as builtin or modules as each sees fit. function armbian_kernel_config__enable_docker_support() { - kernel_config_modifying_hashes+=("CONFIG_DOCKER=y") - if [[ -f .config ]]; then - kernel_config_set_m BTRFS_FS # Enables the BTRFS file system support - kernel_config_set_y BTRFS_FS_POSIX_ACL # Enables POSIX ACL support for BTRFS - kernel_config_set_y BLK_CGROUP # Enables block layer control groups (cgroups) - kernel_config_set_y BLK_DEV_THROTTLING # Enables block device IO throttling - kernel_config_set_y BRIDGE_VLAN_FILTERING # Enables VLAN filtering on network bridges - kernel_config_set_y BRIDGE # Enables support for Ethernet bridges - kernel_config_set_y CFQ_GROUP_IOSCHED # Enables CFQ (Completely Fair Queueing) I/O scheduler for cgroups - kernel_config_set_y CGROUP_BPF # Enables BPF-based control groups - kernel_config_set_y CGROUP_CPUACCT # Enables CPU accounting in cgroups - kernel_config_set_y CGROUP_DEVICE # Enables device control in cgroups - kernel_config_set_y CGROUP_FREEZER # Enables freezer for suspending tasks in cgroups - kernel_config_set_y CGROUP_HUGETLB # Enables huge page control in cgroups - kernel_config_set_y CGROUP_NET_CLASSID # Enables network classid control in cgroups - kernel_config_set_y CGROUP_NET_PRIO # Enables network priority control in cgroups - kernel_config_set_y CGROUP_PERF # Enables performance counter control in cgroups - kernel_config_set_y CGROUP_PIDS # Enables process ID control in cgroups - kernel_config_set_y CGROUP_SCHED # Enables scheduler control in cgroups - kernel_config_set_y CGROUPS # Enables general cgroup functionality - kernel_config_set_y CPUSETS # Enables CPU set support for cgroups - kernel_config_set_m CRYPTO # Enables cryptographic algorithms support as modules - kernel_config_set_m CRYPTO_AEAD # Enables AEAD (Authenticated Encryption with Associated Data) algorithms support - kernel_config_set_m CRYPTO_GCM # Enables GCM (Galois/Counter Mode) cipher support - kernel_config_set_m CRYPTO_GHASH # Enables GHASH algorithm support - kernel_config_set_m CRYPTO_SEQIV # Enables sequential initialization vector support for cryptographic operations - kernel_config_set_y EVENTFD # Enables eventfd system calls for event notification - kernel_config_set_y BPF_SYSCALL # Enables BPF (Berkeley Packet Filter) system call support - kernel_config_set_y CFS_BANDWIDTH # Enables bandwidth control for CFS (Completely Fair Scheduler) - kernel_config_set_m DUMMY # Enables dummy network driver module - kernel_config_set_y DEVPTS_MULTIPLE_INSTANCES # Enables multiple instances of devpts (pseudo-terminal master/slave pairs) - kernel_config_set_y ENCRYPTED_KEYS # Enables support for encrypted keys in the kernel - kernel_config_set_m EXT4_FS # Enables EXT4 file system support as a module - kernel_config_set_y EXT4_FS_POSIX_ACL # Enables POSIX ACL support for EXT4 - kernel_config_set_y EXT4_FS_SECURITY # Enables security extensions for EXT4 file system - kernel_config_set_m IPVLAN # Enables IPvlan network driver support - kernel_config_set_y INET # Enables Internet protocol (IPv4) support - kernel_config_set_y FAIR_GROUP_SCHED # Enables fair group scheduling support - kernel_config_set_m INET_ESP # Enables ESP (Encapsulating Security Payload) for IPv4 - kernel_config_set_y IP_VS_NFCT # Enables connection tracking for IPVS (IP Virtual Server) - kernel_config_set_y IP_VS_PROTO_TCP # Enables TCP protocol support for IPVS - kernel_config_set_y IP_VS_PROTO_UDP # Enables UDP protocol support for IPVS - kernel_config_set_m IP_VS # Enables IPVS (IP Virtual Server) support as a module - kernel_config_set_m IP_VS_RR # Enables round-robin scheduling for IPVS - kernel_config_set_y KEY_DH_OPERATIONS # Enables Diffie-Hellman key exchange operations - kernel_config_set_y KEYS # Enables key management framework support - kernel_config_set_m MACVLAN # Enables MACVLAN network driver support - kernel_config_set_y MEMCG # Enables memory controller for cgroups - kernel_config_set_y MEMCG_KMEM # Enables memory controller for kmem (kernel memory) cgroups - kernel_config_set_m NET_CLS_CGROUP # Enables network classification using cgroups - kernel_config_set_y NET_CORE # Enables core networking stack support - kernel_config_set_y NET_L3_MASTER_DEV # Enables master device support for Layer 3 (L3) networking - kernel_config_set_y NET_NS # Enables network namespace support - kernel_config_set_y NET_SCHED # Enables network scheduler support - kernel_config_set_y NETDEVICES # Enables support for network devices - kernel_config_set_y NAMESPACES # Enables support for namespaces (including network namespaces) - kernel_config_set_m OVERLAY_FS # Enables support for OverlayFS - kernel_config_set_y PID_NS # Enables PID (Process ID) namespace support - kernel_config_set_y POSIX_MQUEUE # Enables POSIX message queues support - kernel_config_set_y PROC_PID_CPUSET # Enables CPU set control for /proc/{pid}/cpuset - kernel_config_set_y PERSISTENT_KEYRINGS # Enables persistent keyring support - kernel_config_set_m RESOURCE_COUNTERS # Enables resource counters support in cgroups - kernel_config_set_y RT_GROUP_SCHED # Enables real-time group scheduling - kernel_config_set_y SECURITY_APPARMOR # Enables AppArmor security module support - kernel_config_set_y SECCOMP # Enables seccomp (secure computing) support - kernel_config_set_y SECCOMP_FILTER # Enables seccomp filtering - kernel_config_set_y USER_NS # Enables user namespace support - kernel_config_set_m VXLAN # Enables VXLAN network driver support - kernel_config_set_m VETH # Enables Virtual Ethernet (veth) network driver support - kernel_config_set_m VLAN_8021Q # Enables 802.1Q VLAN tagging support - kernel_config_set_y XFRM # Enables transform (XFRM) framework support - kernel_config_set_m XFRM_ALGO # Enables cryptographic algorithm support for XFRM - kernel_config_set_m XFRM_USER # Enables user space XFRM framework support - fi + opts_m+=("BTRFS_FS") # Enables the BTRFS file system support + opts_y+=("BTRFS_FS_POSIX_ACL") # Enables POSIX ACL support for BTRFS + opts_y+=("BLK_CGROUP") # Enables block layer control groups (cgroups) + opts_y+=("BLK_DEV_THROTTLING") # Enables block device IO throttling + opts_y+=("BRIDGE_VLAN_FILTERING") # Enables VLAN filtering on network bridges + opts_y+=("BRIDGE") # Enables support for Ethernet bridges + opts_y+=("CFQ_GROUP_IOSCHED") # Enables CFQ (Completely Fair Queueing) I/O scheduler for cgroups + opts_y+=("CGROUP_BPF") # Enables BPF-based control groups + opts_y+=("CGROUP_CPUACCT") # Enables CPU accounting in cgroups + opts_y+=("CGROUP_DEVICE") # Enables device control in cgroups + opts_y+=("CGROUP_FREEZER") # Enables freezer for suspending tasks in cgroups + opts_y+=("CGROUP_HUGETLB") # Enables huge page control in cgroups + opts_y+=("CGROUP_NET_CLASSID") # Enables network classid control in cgroups + opts_y+=("CGROUP_NET_PRIO") # Enables network priority control in cgroups + opts_y+=("CGROUP_PERF") # Enables performance counter control in cgroups + opts_y+=("CGROUP_PIDS") # Enables process ID control in cgroups + opts_y+=("CGROUP_SCHED") # Enables scheduler control in cgroups + opts_y+=("CGROUPS") # Enables general cgroup functionality + opts_y+=("CPUSETS") # Enables CPU set support for cgroups + opts_m+=("CRYPTO") # Enables cryptographic algorithms support as modules + opts_m+=("CRYPTO_AEAD") # Enables AEAD (Authenticated Encryption with Associated Data) algorithms support + opts_m+=("CRYPTO_GCM") # Enables GCM (Galois/Counter Mode) cipher support + opts_m+=("CRYPTO_GHASH") # Enables GHASH algorithm support + opts_m+=("CRYPTO_SEQIV") # Enables sequential initialization vector support for cryptographic operations + opts_y+=("EVENTFD") # Enables eventfd system calls for event notification + opts_y+=("BPF_SYSCALL") # Enables BPF (Berkeley Packet Filter) system call support + opts_y+=("CFS_BANDWIDTH") # Enables bandwidth control for CFS (Completely Fair Scheduler) + opts_m+=("DUMMY") # Enables dummy network driver module + opts_y+=("DEVPTS_MULTIPLE_INSTANCES") # Enables multiple instances of devpts (pseudo-terminal master/slave pairs) + opts_y+=("ENCRYPTED_KEYS") # Enables support for encrypted keys in the kernel + opts_m+=("EXT4_FS") # Enables EXT4 file system support as a module + opts_y+=("EXT4_FS_POSIX_ACL") # Enables POSIX ACL support for EXT4 + opts_y+=("EXT4_FS_SECURITY") # Enables security extensions for EXT4 file system + opts_m+=("IPVLAN") # Enables IPvlan network driver support + opts_y+=("INET") # Enables Internet protocol (IPv4) support + opts_y+=("FAIR_GROUP_SCHED") # Enables fair group scheduling support + opts_m+=("INET_ESP") # Enables ESP (Encapsulating Security Payload) for IPv4 + opts_y+=("IP_VS_NFCT") # Enables connection tracking for IPVS (IP Virtual Server) + opts_y+=("IP_VS_PROTO_TCP") # Enables TCP protocol support for IPVS + opts_y+=("IP_VS_PROTO_UDP") # Enables UDP protocol support for IPVS + opts_m+=("IP_VS") # Enables IPVS (IP Virtual Server) support as a module + opts_m+=("IP_VS_RR") # Enables round-robin scheduling for IPVS + opts_y+=("KEY_DH_OPERATIONS") # Enables Diffie-Hellman key exchange operations + opts_y+=("KEYS") # Enables key management framework support + opts_m+=("MACVLAN") # Enables MACVLAN network driver support + opts_y+=("MEMCG") # Enables memory controller for cgroups + opts_y+=("MEMCG_KMEM") # Enables memory controller for kmem (kernel memory) cgroups + opts_m+=("NET_CLS_CGROUP") # Enables network classification using cgroups + opts_y+=("NET_CORE") # Enables core networking stack support + opts_y+=("NET_L3_MASTER_DEV") # Enables master device support for Layer 3 (L3) networking + opts_y+=("NET_NS") # Enables network namespace support + opts_y+=("NET_SCHED") # Enables network scheduler support + opts_y+=("NETDEVICES") # Enables support for network devices + opts_y+=("NAMESPACES") # Enables support for namespaces (including network namespaces) + opts_m+=("OVERLAY_FS") # Enables support for OverlayFS + opts_y+=("PID_NS") # Enables PID (Process ID) namespace support + opts_y+=("POSIX_MQUEUE") # Enables POSIX message queues support + opts_y+=("PROC_PID_CPUSET") # Enables CPU set control for /proc/{pid}/cpuset + opts_y+=("PERSISTENT_KEYRINGS") # Enables persistent keyring support + opts_m+=("RESOURCE_COUNTERS") # Enables resource counters support in cgroups + opts_y+=("RT_GROUP_SCHED") # Enables real-time group scheduling + opts_y+=("SECURITY_APPARMOR") # Enables AppArmor security module support + opts_y+=("SECCOMP") # Enables seccomp (secure computing) support + opts_y+=("SECCOMP_FILTER") # Enables seccomp filtering + opts_y+=("USER_NS") # Enables user namespace support + opts_m+=("VXLAN") # Enables VXLAN network driver support + opts_m+=("VETH") # Enables Virtual Ethernet (veth) network driver support + opts_m+=("VLAN_8021Q") # Enables 802.1Q VLAN tagging support + opts_y+=("XFRM") # Enables transform (XFRM) framework support + opts_m+=("XFRM_ALGO") # Enables cryptographic algorithm support for XFRM + opts_m+=("XFRM_USER") # Enables user space XFRM framework support } - # Enables live system access to the kernel configuration via /proc/config.gz. -# -# This function appends "CONFIG_IKCONFIG_PROC=y" to the global list of kernel -# configuration modifications. If the ".config" file exists, it ensures that both -# CONFIG_IKCONFIG and CONFIG_IKCONFIG_PROC are enabled, allowing the current kernel's -# configuration to be accessible and extracted for further use. -# -# Globals: -# kernel_config_modifying_hashes - Array holding pending kernel configuration changes. -# function armbian_kernel_config__enable_config_access_in_live_system() { - kernel_config_modifying_hashes+=("CONFIG_IKCONFIG_PROC=y") - if [[ -f .config ]]; then - kernel_config_set_y CONFIG_IKCONFIG # This information can be extracted from the kernel image file with the script scripts/extract-ikconfig and used as input to rebuild the current kernel or to build another kernel - kernel_config_set_y CONFIG_IKCONFIG_PROC # This option enables access to the kernel configuration file through /proc/config.gz - fi + opts_y+=("IKCONFIG") # This information can be extracted from the kernel image file with the script scripts/extract-ikconfig and used as input to rebuild the current kernel or to build another kernel + opts_y+=("IKPROC") # This option enables access to the kernel configuration file through /proc/config.gz } function armbian_kernel_config__restore_enable_gpio_sysfs() { - kernel_config_modifying_hashes+=("CONFIG_GPIO_SYSFS=y") - if [[ -f .config ]]; then - kernel_config_set_y CONFIG_GPIO_SYSFS # This was a victim of not having EXPERT=y due to some _DEBUG conflicts in old times. Re-enable it forcefully. - fi + opts_y+=("GPIO_SYSFS") # This was a victim of not having EXPERT=y due to some _DEBUG conflicts in old times. Re-enable it forcefully. } # +++++++++++ HELPERS CORNER +++++++++++ @@ -506,14 +444,8 @@ function armbian_kernel_config__restore_enable_gpio_sysfs() { # function kernel_config_set_m() { declare module="$1" - state=$(./scripts/config --state "$module") - - if [ "$state" == "y" ]; then - display_alert "${module} is already enabled as built-in" - else - display_alert "Enabling kernel module" "${module}=m" "debug" - run_host_command_logged ./scripts/config --module "$module" - fi + display_alert "Enabling kernel module" "${module}=m" "debug" + run_host_command_logged ./scripts/config --module "${module}" } function kernel_config_set_y() { @@ -525,16 +457,7 @@ function kernel_config_set_y() { function kernel_config_set_n() { declare config="$1" display_alert "Disabling kernel config/module" "${config}=n" "debug" - - # Only set to "n" if the config option can be found in the config file. - # Otherwise the option would maybe be considered as misconfiguration. - if grep -qE "(\b${config}\=|CONFIG_${config}\=)" .config; then - run_host_command_logged ./scripts/config --disable "${config}" - elif grep -qE "(\b${config} is not set|\bCONFIG_${config} is not set)" .config; then - display_alert "Kernel config/module was already disabled" "${config}=n skipped" "debug" - else - display_alert "Kernel config/module was not found in the config file" "${config}=n was not added to prevent misconfiguration" "debug" - fi + run_host_command_logged ./scripts/config --disable "${config}" } @@ -555,7 +478,7 @@ function kernel_config_set_val() { # This takes opts_n, opts_y, arrays from parent scope; also the opts_val dictionary; # it and applies them to the hashes and to the .config if it exists. function armbian_kernel_config_apply_opts_from_arrays() { - declare opt_y opt_val opt_n + declare opt_y opt_val opt_n opt_m for opt_n in "${opts_n[@]}"; do kernel_config_modifying_hashes+=("${opt_n}=n") done @@ -564,6 +487,18 @@ function armbian_kernel_config_apply_opts_from_arrays() { kernel_config_modifying_hashes+=("${opt_y}=y") done + for opt_m in "${opts_m[@]}"; do + actual_opt_value='m' + # NOTE: this isn't perfect, there may be something already + # in defconfig, but we can't see it from here. + if egrep -q "(CONFIG_)?${opt_m}=m" "${kernel_config_source_filename}"; then + : # do nothing + elif egrep -q "(CONFIG_)?${opt_m}=y" "${kernel_config_source_filename}"; then + actual_opt_value='y' + fi + kernel_config_modifying_hashes+=("${opt_m}=${actual_opt_value}") + done + for opt_val in "${!opts_val[@]}"; do kernel_config_modifying_hashes+=("${opt_val}=${opts_val[$opt_val]}") done @@ -579,6 +514,17 @@ function armbian_kernel_config_apply_opts_from_arrays() { kernel_config_set_y "${opt_y}" done + for opt_m in "${opts_m[@]}"; do + actual_opt_value='m' + if egrep -q "(CONFIG_)?${opt_m}=y" "${kernel_config_source_filename}" .config; then + actual_opt_value='y' + kernel_config_set_y "${opt_m}" + else + kernel_config_set_m "${opt_m}" + fi + display_alert "Enabling kernel opt" "${opt_m}=${actual_opt_value}" "debug" + done + for opt_val in "${!opts_val[@]}"; do display_alert "Setting kernel opt" "${opt_val}=${opts_val[$opt_val]}" "debug" kernel_config_set_val "${opt_val}" "${opts_val[$opt_val]}" diff --git a/lib/functions/compilation/atf.sh b/lib/functions/compilation/atf.sh index 46a5ee101..a218c816b 100644 --- a/lib/functions/compilation/atf.sh +++ b/lib/functions/compilation/atf.sh @@ -72,12 +72,9 @@ compile_atf() { if linux-version compare "${binutils_version}" gt "2.39" && linux-version compare "${binutils_version}" lt "2.42"; then display_alert "Binutils version for ATF" ">= 2.39 and < 2.42, adding -Wl,--no-warn-rwx-segment" "info" - binutils_flags_atf="-Wl,--no-warn-rwx-segment" - elif linux-version compare "${binutils_version}" ge "2.42"; then - display_alert "Binutils version for ATF" ">= 2.42, adding -Wl,--no-warn-rwx-segments" "info" - binutils_flags_atf="-Wl,--no-warn-rwx-segments" + binutils_flags_atf="--no-warn-rwx-segment" fi - + # - ENABLE_BACKTRACE="0" has been added to workaround a regression in ATF. Check: https://github.com/armbian/build/issues/1157 run_host_command_logged "CROSS_COMPILE='ccache ${ATF_COMPILER}'" CCACHE_BASEDIR="$(pwd)" "CC='ccache ${ATF_COMPILER}gcc'" PATH="${toolchain}:${toolchain2}:${PATH}" \ diff --git a/lib/functions/compilation/kernel-config.sh b/lib/functions/compilation/kernel-config.sh index 7aabd9d55..e562ebbed 100644 --- a/lib/functions/compilation/kernel-config.sh +++ b/lib/functions/compilation/kernel-config.sh @@ -86,6 +86,13 @@ function kernel_config_initialize() { # These kernel config hooks are always called twice, once without being in kernel directory and once with current directory being the kernel work directory. # You must check with "if [[ -f .config ]]; then" in which of the two phases you are. Otherwise, functions like "kernel_config_set_y" won't work. function call_extensions_kernel_config() { + # Prepare arrays and dict for modifications. + # Those will be used by the hooks called below. + # shellcheck disable=SC2034 + declare -A opts_val=() + # shellcheck disable=SC2034 + declare -a opts_y=() opts_n=() opts_m=() + # Run the core-armbian config modifications here, built-in extensions: call_extension_method "armbian_kernel_config" <<- 'ARMBIAN_KERNEL_CONFIG' *Armbian-core default hook point for pre-olddefconfig Kernel config modifications* @@ -108,6 +115,9 @@ function call_extensions_kernel_config() { Either way, the hook _must_ add representative changes to the `kernel_config_modifying_hashes` array, for kernel config hashing. Please note: Manually changing options doesn't check the validity of the .config file. Check for warnings in your build log. CUSTOM_KERNEL_CONFIG + + # Apply the modifications set in the arrays/dict + armbian_kernel_config_apply_opts_from_arrays } function kernel_config_finalize() { @@ -136,11 +146,12 @@ function kernel_config_export() { # store kernel defconfig in easily reachable place (output dir) mkdir -p "${DEST}"/config display_alert "Exporting new kernel defconfig" "$DEST/config/$LINUXCONFIG.config" "info" - run_host_command_logged cp -pv defconfig "${DEST}/config/${LINUXCONFIG}.config" + echo "# Armbian defconfig generated with ${KERNEL_MAJOR_MINOR}" > "${DEST}/config/${LINUXCONFIG}.config" + run_host_command_logged cat defconfig >> "${DEST}/config/${LINUXCONFIG}.config" # store back into original LINUXCONFIG too, if it came from there, so it's pending commits when done. if [[ "${kernel_config_source_filename}" != "" ]]; then display_alert "Exporting new kernel config - git commit pending" "${kernel_config_source_filename}" "info" - run_host_command_logged cp -pv defconfig "${kernel_config_source_filename}" + run_host_command_logged cp -pv "${DEST}/config/${LINUXCONFIG}.config" "${kernel_config_source_filename}" fi } diff --git a/lib/functions/compilation/patch/drivers_network.sh b/lib/functions/compilation/patch/drivers_network.sh index ae0df5a8a..661eb6e36 100644 --- a/lib/functions/compilation/patch/drivers_network.sh +++ b/lib/functions/compilation/patch/drivers_network.sh @@ -233,7 +233,7 @@ driver_xradio_xr819() { # Wireless drivers for Xradio XR819 chipsets - if linux-version compare "${version}" ge 4.19 && [[ "$LINUXFAMILY" == sunxi* ]]; then + if linux-version compare "${version}" ge 4.19 && [[ "$LINUXFAMILY" == sun* ]]; then # Attach to specific commit (is branch:master) local xradio_xr819_ver="commit:684a91a3692a964c5886dcf4369874cc7c19c0a4" # Commit date: Aug 7, 2025 (please update when updating commit ref) @@ -372,13 +372,11 @@ driver_rtw88() { } driver_rtl8852bs() { - # Wireless driver for Realtek 8852BS SDIO Wireless driver used in BananaPi F3 and Armsom Sige5 - if linux-version compare "${version}" ge 6.1 && [[ "${LINUXFAMILY}" == spacemit || "${LINUXFAMILY}" == rk35xx || "${LINUXFAMILY}" == rockchip64 ]]; then # Attach to specific commit - local rtl8852bs_ver='commit:15811ffdf575baabbd1cd46a306e9544a7f02846' # Commit date: Oct 2, 2025 (please update when updating commit ref) + local rtl8852bs_ver='commit:72c75150d7422eda3f0b3f543cce65114efcb4fe' # Commit date: Oct 18, 2025 (please update when updating commit ref) display_alert "Adding" "Wireless drivers for Realtek 8852BS SDIO chipset ${rtl8852bs_ver}" "info" @@ -484,7 +482,7 @@ driver_uwe5622() { # Wireless drivers for Unisoc uwe5622 wireless - if linux-version compare "${version}" ge 5.15 && [[ "$LINUXFAMILY" == sunxi* || "$LINUXFAMILY" == rockchip64 || "$LINUXFAMILY" == rk35xx ]]; then + if linux-version compare "${version}" ge 5.15 && [[ "$LINUXFAMILY" == sun* || "$LINUXFAMILY" == rockchip64 || "$LINUXFAMILY" == rk35xx ]]; then display_alert "Adding" "Drivers for Unisoc uwe5622 found on some Allwinner and Rockchip boards" "info" @@ -524,7 +522,7 @@ driver_uwe5622() { process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-v6.6-fix-tty-sdio.patch" "applying" fi - if [[ "$LINUXFAMILY" == sunxi* ]]; then + if [[ "$LINUXFAMILY" == sun* ]]; then process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-fix-setting-mac-address-for-netdev.patch" "applying" fi @@ -554,7 +552,7 @@ driver_uwe5622() { fi if linux-version compare "${version}" ge 6.15; then - if [[ "$LINUXFAMILY" == sunxi* ]]; then + if [[ "$LINUXFAMILY" == sun* ]]; then process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-fix-timer-api-changes-for-6.15-only-sunxi.patch" "applying" else process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-v6.15-timer-api-changes.patch" "applying" @@ -575,7 +573,7 @@ driver_uwe5622() { driver_rtl8723cs() { # Wireless drivers for Realtek rtl8723cs chipsets - # Driver has been borrowed from sunxi 6.1 megous patch archive. + # Driver has been borrowed from sun* 6.1 megous patch archive. # Applies only from linux 6.1 onwards, so older kernel archives does not require to be altered # It was disabled from d1/bcm2711 as that kernel is not fully in sync with mainline and as its probably not needed there anyway @@ -670,7 +668,7 @@ driver_rtl8723DS() { if linux-version compare "${version}" ge 5.0; then # Attach to specific commit (was "branch:master") - local rtl8723dsver='commit:39d0eedf4eaedfcf6e133413a389c5f8a70a7d1f' # Commit date: 2025-10-02 (please update when updating commit ref) + local rtl8723dsver='commit:8e1aa4d865e6f8709fd07cceb20b5c6eb993875b' # Commit date: 2025-10-18 (please update when updating commit ref) display_alert "Adding" "Wireless drivers for Realtek 8723DS chipsets ${rtl8723dsver}" "info" diff --git a/lib/functions/compilation/uboot.sh b/lib/functions/compilation/uboot.sh index 507930a82..6f9f6a8ec 100644 --- a/lib/functions/compilation/uboot.sh +++ b/lib/functions/compilation/uboot.sh @@ -94,10 +94,6 @@ function compile_uboot_target() { "KCFLAGS=-fdiagnostics-color=always" \ pipetty make "${CTHREADS}" "${BOOTCONFIG}" "CROSS_COMPILE=\"${CCACHE} ${UBOOT_COMPILER}\"" - # armbian specifics u-boot settings - [[ -f .config ]] && sed -i "s/CONFIG_LOCALVERSION=\"\"/CONFIG_LOCALVERSION=\"-armbian-${artifact_version}\"/g" .config - [[ -f .config ]] && sed -i 's/CONFIG_LOCALVERSION_AUTO=.*/# CONFIG_LOCALVERSION_AUTO is not set/g' .config - # for modern (? 2018-2019?) kernel and non spi targets @TODO: this does not belong here if [[ ${BOOTBRANCH} =~ ^tag:v201[8-9](.*) && ${target} != "spi" && -f .config ]]; then display_alert "Hacking ENV stuff in u-boot config 2018-2019" "for ${target}" "debug" @@ -124,6 +120,9 @@ function compile_uboot_target() { # $BOOTDELAY can be set in board family config, ensure autoboot can be stopped even if set to 0 [[ $BOOTDELAY == 0 ]] && echo -e "CONFIG_ZERO_BOOTDELAY_CHECK=y" >> .config [[ -n $BOOTDELAY ]] && sed -i "s/^CONFIG_BOOTDELAY=.*/CONFIG_BOOTDELAY=${BOOTDELAY}/" .config || [[ -f .config ]] && echo "CONFIG_BOOTDELAY=${BOOTDELAY}" >> .config + # armbian specifics u-boot settings; configure the version so UART boot logs show exactly what's in there + [[ -f .config ]] && sed -i "s/CONFIG_LOCALVERSION=\"\"/CONFIG_LOCALVERSION=\"_armbian-${artifact_version}\"/g" .config + [[ -f .config ]] && sed -i 's/CONFIG_LOCALVERSION_AUTO=.*/# CONFIG_LOCALVERSION_AUTO is not set/g' .config else display_alert "scripts/config found" "u-boot ${version} $BOOTCONFIG ${target_make}" "debug" @@ -142,6 +141,10 @@ function compile_uboot_target() { # Hack, up the log level to 6: "info" (default is 4: "warning") display_alert "Hacking log level in u-boot config" "LOGLEVEL=6 for ${target}" "info" run_host_command_logged scripts/config --set-val CONFIG_LOGLEVEL 6 + + # Include Armbian version so UART bootlogs are drastically more useful + run_host_command_logged ./scripts/config --disable "LOCALVERSION_AUTO" + run_host_command_logged ./scripts/config --set-str "LOCALVERSION" "_armbian-${artifact_version}" # crazy quotes! fi if [[ "${UBOOT_DEBUGGING}" == "yes" ]]; then @@ -203,19 +206,20 @@ function compile_uboot_target() { pipetty make "${CTHREADS}" "olddefconfig" "CROSS_COMPILE=\"${CCACHE} ${UBOOT_COMPILER}\"" if [[ "${UBOOT_CONFIGURE:-"no"}" == "yes" ]]; then + display_alert "Saving pre-config u-boot defconfig" "UBOOT_CONFIGURE=yes; experimental" "warn" + run_host_command_logged make savedefconfig + run_host_command_logged mv -v defconfig defconfig.pre.menuconfig + display_alert "Configuring u-boot" "UBOOT_CONFIGURE=yes; experimental" "warn" run_host_command_dialog make menuconfig display_alert "Exporting saved config" "UBOOT_CONFIGURE=yes; experimental" "warn" run_host_command_logged make savedefconfig run_host_command_logged cp -v defconfig "${DEST}/defconfig-uboot-${BOARD}-${BRANCH}" - # check if we can find configs/${BOOTCONFIG}, and if so, output a diff between that and the new saved defconfig - if [[ -f "configs/${BOOTCONFIG}" ]]; then - display_alert "Diffing ${BOOTCONFIG} and new defconfig" "UBOOT_CONFIGURE=yes; experimental" "warn" - run_host_command_logged diff -u --color=always "configs/${BOOTCONFIG}" "${DEST}/defconfig-uboot-${BOARD}-${BRANCH}" "2>&1" "|| true" # no errors please, all to stdout - fi + display_alert "Diffing before and after defconfigs" "UBOOT_CONFIGURE=yes; experimental" "warn" + run_host_command_logged diff -u --color=always "defconfig.pre.menuconfig" "${DEST}/defconfig-uboot-${BOARD}-${BRANCH}" "2>&1" "|| true" # no errors please, all to stdout - display_alert "Exporting saved config (experimental)" "${DEST}/defconfig-uboot-${BOARD}-${BRANCH}" "warn" + display_alert "Exported saved config (experimental)" "${DEST}/defconfig-uboot-${BOARD}-${BRANCH}" "warn" return 0 # exit after this fi diff --git a/lib/functions/configuration/interactive.sh b/lib/functions/configuration/interactive.sh index c16dced63..1f0b438de 100644 --- a/lib/functions/configuration/interactive.sh +++ b/lib/functions/configuration/interactive.sh @@ -156,8 +156,9 @@ function interactive_config_ask_board_list() { if [[ $STATUS == 3 ]]; then if [[ $WIP_STATE == supported ]]; then [[ $SHOW_WARNING == yes ]] && show_developer_warning - STATE_DESCRIPTION=' - \Z1(CSC)\Zn - Community Supported Configuration\n - \Z1(WIP)\Zn - Work In Progress - \n - \Z1(EOS)\Zn - End Of Support\n - \Z1(TVB)\Zn - TV boxes' + STATE_DESCRIPTION=' - \Z1(conf)\Zn - Boards with high level of software maturity + \n - \Z1(CSC)\Zn - Community Supported Configuration\n - \Z1(WIP)\Zn - Work In Progress + \n - \Z1(EOS)\Zn - End Of Support\n - \Z1(TVB)\Zn - TV boxes' WIP_STATE=unsupported WIP_BUTTON='matured' EXPERT=yes diff --git a/lib/functions/configuration/main-config.sh b/lib/functions/configuration/main-config.sh index 878bf5708..ac3760f01 100644 --- a/lib/functions/configuration/main-config.sh +++ b/lib/functions/configuration/main-config.sh @@ -169,8 +169,8 @@ function do_main_configuration() { # Support for LUKS / cryptroot if [[ $CRYPTROOT_ENABLE == yes ]]; then enable_extension "fs-cryptroot-support" # add the tooling needed, cryptsetup - if [[ -z $CRYPTROOT_PASSPHRASE ]]; then # a passphrase is mandatory if rootfs encryption is enabled - exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE is not set" + if [[ -z $CRYPTROOT_PASSPHRASE ]] && [[ -z $CRYPTROOT_AUTOUNLOCK ]]; then # a passphrase is mandatory if rootfs encryption is enabled, unless CRYPTROOT_AUTOUNLOCK is wanted + exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE or CRYPTROOT_AUTOUNLOCK is not set" fi [[ -z $CRYPTROOT_MAPPER ]] && CRYPTROOT_MAPPER="armbian-root" # TODO: fixed name can't be used for parallel image building (rpardini: ?) [[ -z $CRYPTROOT_SSH_UNLOCK ]] && CRYPTROOT_SSH_UNLOCK=yes @@ -368,7 +368,7 @@ function do_extra_configuration() { [[ -z $BOOTPATCHDIR ]] && BOOTPATCHDIR="u-boot-$LINUXFAMILY" # @TODO move to hook [[ -z $ATFPATCHDIR ]] && ATFPATCHDIR="atf-$LINUXFAMILY" - if [[ "$RELEASE" =~ ^(focal|jammy|noble|oracular|plucky)$ ]]; then + if [[ "$RELEASE" =~ ^(focal|jammy|noble|oracular|plucky|questing|resolute)$ ]]; then DISTRIBUTION="Ubuntu" else DISTRIBUTION="Debian" diff --git a/lib/functions/general/bat-cat.sh b/lib/functions/general/bat-cat.sh index 1dc448604..a4a4c3135 100644 --- a/lib/functions/general/bat-cat.sh +++ b/lib/functions/general/bat-cat.sh @@ -9,7 +9,7 @@ function run_tool_batcat() { # Default version - BATCAT_VERSION=${BATCAT_VERSION:-0.25.0} # https://github.com/sharkdp/bat/releases + BATCAT_VERSION=${BATCAT_VERSION:-0.26.0} # https://github.com/sharkdp/bat/releases declare non_cache_dir="/armbian-tools/batcat" # To deploy/reuse cached batcat in a Docker image. @@ -117,7 +117,7 @@ function try_download_batcat_tooling() { display_alert "BATCAT_FN: ${BATCAT_FN}" "batcat" "debug" display_alert "Downloading required" "batcat tooling${RETRY_FMT_MORE_THAN_ONCE}" "info" - run_host_command_logged wget --no-verbose --progress=dot:giga -O "${BATCAT_BIN}.tar.gz.tmp" "${DOWN_URL}" || { + run_host_command_logged curl -L#o "${BATCAT_BIN}.tar.gz.tmp" "${DOWN_URL}" || { return 1 } run_host_command_logged mv "${BATCAT_BIN}.tar.gz.tmp" "${BATCAT_BIN}.tar.gz" @@ -125,7 +125,7 @@ function try_download_batcat_tooling() { run_host_command_logged rm -rf "${BATCAT_BIN}.tar.gz" # EXTRA: get more syntaxes for batcat. We need Debian syntax for CONTROL files, etc. - run_host_command_logged wget --no-verbose --progress=dot:giga -O "${DIR_BATCAT}/sublime-debian.tar.gz.tmp" "${GITHUB_SOURCE:-"https://github.com"}/barnumbirr/sublime-debian/archive/refs/heads/master.tar.gz" + run_host_command_logged curl -L#o "${DIR_BATCAT}/sublime-debian.tar.gz.tmp" "${GITHUB_SOURCE:-"https://github.com"}/barnumbirr/sublime-debian/archive/refs/heads/master.tar.gz" run_host_command_logged mkdir -p "${DIR_BATCAT}/temp-debian-syntax" run_host_command_logged tar -xzf "${DIR_BATCAT}/sublime-debian.tar.gz.tmp" -C "${DIR_BATCAT}/temp-debian-syntax" sublime-debian-master/Syntaxes diff --git a/lib/functions/general/git.sh b/lib/functions/general/git.sh index b6c3f16ce..57e7395a4 100644 --- a/lib/functions/general/git.sh +++ b/lib/functions/general/git.sh @@ -276,20 +276,29 @@ function fetch_from_repo() { else display_alert "Updating submodules" "" "ext" # FML: http://stackoverflow.com/a/17692710 - for i in $(git config -f .gitmodules --get-regexp path | awk '{ print $2 }'); do + while read -r key path; do + # key is like: submodule.libfoo.path + # extract "libfoo" from "submodule.libfoo.path" + local name=${key#submodule.} # -> libfoo.path + name=${name%.path} # -> libfoo + cd "${git_work_dir}" || exit + local surl sref - surl=$(git config -f .gitmodules --get "submodule.$i.url") - sref=$(git config -f .gitmodules --get "submodule.$i.branch" || true) + surl=$(git config -f .gitmodules --get "submodule.${name}.url") + sref=$(git config -f .gitmodules --get "submodule.${name}.branch" || true) + if [[ -n $sref ]]; then sref="branch:$sref" else sref="head" fi - display_alert "Updating submodule" "$i - $surl - $sref" "git" - git_ensure_safe_directory "$workdir/$i" - fetch_from_repo "$surl" "$workdir/$i" "$sref" - done + + display_alert "Updating submodule" "${name} - ${surl} - ${sref}" "git" + git_ensure_safe_directory "$workdir/$path" + fetch_from_repo "$surl" "$workdir/$path" "$sref" + + done < <(git config -f .gitmodules --get-regexp 'submodule\..*\.path') fi fi else diff --git a/lib/functions/general/oci-oras.sh b/lib/functions/general/oci-oras.sh index 307537dee..ae84a501c 100644 --- a/lib/functions/general/oci-oras.sh +++ b/lib/functions/general/oci-oras.sh @@ -109,7 +109,7 @@ function try_download_oras_tooling() { display_alert "ORAS_BIN: ${ORAS_BIN}" "ORAS" "debug" display_alert "Downloading required" "ORAS tooling${RETRY_FMT_MORE_THAN_ONCE}" "info" - run_host_command_logged wget --no-verbose --progress=dot:giga -O "${ORAS_BIN}.tar.gz.tmp" "${DOWN_URL}" || { + run_host_command_logged curl -fL#o "${ORAS_BIN}.tar.gz.tmp" "${DOWN_URL}" || { return 1 } run_host_command_logged mv "${ORAS_BIN}.tar.gz.tmp" "${ORAS_BIN}.tar.gz" diff --git a/lib/functions/general/shellcheck.sh b/lib/functions/general/shellcheck.sh index 6eca96489..d4cb10a2f 100644 --- a/lib/functions/general/shellcheck.sh +++ b/lib/functions/general/shellcheck.sh @@ -136,7 +136,7 @@ function try_download_shellcheck_tooling() { display_alert "SHELLCHECK_BIN: ${SHELLCHECK_BIN}" "SHELLCHECK" "debug" display_alert "Downloading required" "SHELLCHECK tooling${RETRY_FMT_MORE_THAN_ONCE}" "info" - run_host_command_logged wget --no-verbose --progress=dot:giga -O "${SHELLCHECK_BIN}.tar.xz.tmp" "${DOWN_URL}" || { + run_host_command_logged curl -fL#o "${SHELLCHECK_BIN}.tar.xz.tmp" "${DOWN_URL}" || { return 1 } diff --git a/lib/functions/host/basic-deps.sh b/lib/functions/host/basic-deps.sh index 20bad3b14..6dbcc0d86 100644 --- a/lib/functions/host/basic-deps.sh +++ b/lib/functions/host/basic-deps.sh @@ -26,7 +26,6 @@ function prepare_host_basic() { "linux-version:linux-base" "locale-gen:locales" "git:git" - "wget:wget" ) for check_pack in "${checklist[@]}"; do diff --git a/lib/functions/host/prepare-host.sh b/lib/functions/host/prepare-host.sh index 7d32b2141..ab8efaa89 100644 --- a/lib/functions/host/prepare-host.sh +++ b/lib/functions/host/prepare-host.sh @@ -187,7 +187,7 @@ function adaptative_prepare_host_dependencies() { dwarves # dwarves has been replaced by "pahole" and is now a transitional package e2fsprogs flex - gawk gnupg gpg + gawk gettext gnupg gpg imagemagick # required for plymouth: converting images / spinners jq # required for parsing JSON, specially rootfs-caching related. kmod # this causes initramfs rebuild, but is usually pre-installed, so no harm done unless it's an upgrade @@ -210,7 +210,7 @@ function adaptative_prepare_host_dependencies() { colorized-logs # for ansi2html, ansi2txt, pipetty unzip zip pigz xz-utils pbzip2 lzop zstd # compressors et al parted gdisk fdisk # partition tools @TODO why so many? - aria2 curl axel # downloaders et al + aria2 curl axel wget # downloaders et al parallel # do things in parallel (used for fast md5 hashing in initrd cache) rdfind # armbian-firmware-full/linux-firmware symlink creation step ) diff --git a/lib/functions/image/initrd.sh b/lib/functions/image/initrd.sh index 476ae8417..eaea5d121 100644 --- a/lib/functions/image/initrd.sh +++ b/lib/functions/image/initrd.sh @@ -62,6 +62,7 @@ update_initramfs() { [[ -d "${chroot_target}/etc/dropbear-initramfs/" ]] && initrd_files_to_hash+=("${chroot_target}/etc/dropbear-initramfs/") [[ -d "${chroot_target}/etc/dropbear/initramfs/" ]] && initrd_files_to_hash+=("${chroot_target}/etc/dropbear/initramfs/") fi + initrd_files_to_hash+=("${chroot_target}/etc/crypttab") # for updates to rootdev UUID fi # Find all the affected files; parallel md5sum sum them; invert hash and path, and remove chroot prefix. diff --git a/lib/functions/image/partitioning.sh b/lib/functions/image/partitioning.sh index 5cfaa42be..c93172440 100644 --- a/lib/functions/image/partitioning.sh +++ b/lib/functions/image/partitioning.sh @@ -113,7 +113,7 @@ function prepare_partitions() { fi # Check if we need boot partition # Specialized storage extensions like cryptroot or lvm may require a boot partition - if [[ $BOOTSIZE != "0" && (-n $BOOTFS_TYPE || $ROOTFS_TYPE != ext4 || $BOOTPART_REQUIRED == yes) ]]; then + if [[ $BOOTSIZE != "0" && (-n $BOOTFS_TYPE || $BOOTPART_REQUIRED == yes) ]]; then local bootpart=$((next++)) local bootfs=${BOOTFS_TYPE:-ext4} [[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE} @@ -324,9 +324,19 @@ function prepare_partitions() { # create fstab (and crypttab) entry if [[ $CRYPTROOT_ENABLE == yes ]]; then + luks_key_file="none" + if [[ $CRYPTROOT_AUTOUNLOCK == yes ]]; then + luks_key_file="/etc/rootfs.key" + display_alert "Saving rootfs.key and configuration for autounlock" "(location=${luks_key_file})" + mv ${cryptroot_autounlock_key_file:?} ${SDCARD}${luks_key_file} + mkdir -p $SDCARD/etc/initramfs-tools/conf.d/ + echo "UMASK=0077" > $SDCARD/etc/initramfs-tools/conf.d/key-umask.conf + echo "" >> $SDCARD/etc/cryptsetup-initramfs/conf-hook + echo "KEYFILE_PATTERN=${luks_key_file}" >> $SDCARD/etc/cryptsetup-initramfs/conf-hook + fi # map the LUKS container partition via its UUID to be the 'cryptroot' device physical_root_part_uuid="$(blkid -s UUID -o value $physical_rootdevice)" - echo "$CRYPTROOT_MAPPER UUID=${physical_root_part_uuid} none luks" >> $SDCARD/etc/crypttab + echo "$CRYPTROOT_MAPPER UUID=${physical_root_part_uuid} ${luks_key_file} luks" >> $SDCARD/etc/crypttab run_host_command_logged cat $SDCARD/etc/crypttab fi diff --git a/lib/functions/rootfs/create-cache.sh b/lib/functions/rootfs/create-cache.sh index 2438c67ac..a809a3e45 100644 --- a/lib/functions/rootfs/create-cache.sh +++ b/lib/functions/rootfs/create-cache.sh @@ -28,7 +28,8 @@ function calculate_rootfs_cache_id() { declare -a extension_hooks_to_hash=("custom_apt_repo") declare -a extension_hooks_hashed=("$(dump_extension_method_sources_functions "${extension_hooks_to_hash[@]}")") declare hash_hooks="undetermined" - hash_hooks="$(echo "${extension_hooks_hashed[@]}" | sha256sum | cut -d' ' -f1)" + declare legacy_debootstrap="${LEGACY_DEBOOTSTRAP:-"no"}" + hash_hooks="$(echo "${extension_hooks_hashed[@]}" LDB=${legacy_debootstrap,,} | sha256sum | cut -d' ' -f1)" declare hash_hooks_short="${hash_hooks:0:${short_hash_size}}" # AGGREGATED_ROOTFS_HASH is produced by aggregation.py diff --git a/lib/functions/rootfs/distro-agnostic.sh b/lib/functions/rootfs/distro-agnostic.sh index 21201b38b..3ce2de462 100644 --- a/lib/functions/rootfs/distro-agnostic.sh +++ b/lib/functions/rootfs/distro-agnostic.sh @@ -7,6 +7,72 @@ # This file is a part of the Armbian Build Framework # https://github.com/armbian/build/ +function bootscript_export_display_console() { + unset BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE + typeset ITEM + typeset CONSOLEARGS + + for ITEM in ${DISPLAYCON//,/ } ; do + CONSOLEARGS="${CONSOLEARGS:-}${CONSOLEARGS:+ }console=${ITEM//:/,}" + done + + for ITEM in $SRC_CMDLINE ; do + if [[ ! 'console' == "${ITEM%%=*}" ]] ; then + continue + fi + if [[ "${ITEM#*=}" =~ 'tty'[AGSU]* ]] ; then + continue + fi + CONSOLEARGS="${CONSOLEARGS:-}${CONSOLEARGS:+ }${ITEM:?}" + done + CONSOLEARGS="$(echo "${CONSOLEARGS:-}" | xargs -n1 | sort -u | xargs)" + + export BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE="${CONSOLEARGS:-}" +} + +function bootscript_export_serial_console() { + unset BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE + typeset ITEM + typeset CONSOLEARGS + + for ITEM in ${SERIALCON//,/ } ; do + CONSOLEARGS="${CONSOLEARGS:-}${CONSOLEARGS:+ }console=${ITEM//:/,}" + done + + for ITEM in $SRC_CMDLINE ; do + if [[ ! 'console' == "${ITEM%%=*}" ]] ; then + continue + fi + if [[ ! "${ITEM#*=}" =~ 'tty'[AGSU]* ]] ; then + continue + fi + CONSOLEARGS="${CONSOLEARGS:-}${CONSOLEARGS:+ }${ITEM:?}" + done + CONSOLEARGS="$(echo "${CONSOLEARGS:-}" | xargs -n1 | sort -u | xargs)" + + export BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE="${CONSOLEARGS:-}" +} + +function render_bootscript_template() { ( + typeset BOOTSCRIPT_TEMPLATE__CREATE_DATE + typeset SHELL_FORMAT + + BOOTSCRIPT_TEMPLATE__CREATE_DATE="$(date -Ru)" + + bootscript_export_display_console + bootscript_export_serial_console + + SHELL_FORMAT="$(set | sed -En '/^BOOTSCRIPT_TEMPLATE__/ { s/=.*$//; s/^/$/; p; }')" + display_alert "Bootscript template variables to be rendered" "${SHELL_FORMAT:-N/A}" "debug" + + export $(set | sed -En '/^BOOTSCRIPT_TEMPLATE__/s/=.*$//p') + envsubst "'${SHELL_FORMAT}'" +) } + +function proof_rendered_bootscript_template() { + ! egrep '\$\{?BOOTSCRIPT_TEMPLATE__' "${1:?}" +} + function install_distribution_agnostic() { display_alert "Installing distro-agnostic part of rootfs" "install_distribution_agnostic" "debug" @@ -109,15 +175,28 @@ function install_distribution_agnostic() { # display welcome message at first root login which is ready by /usr/sbin/armbian/armbian-firstlogin touch "${SDCARD}"/root/.not_logged_in_yet + # use user provided firstboot config + if [[ -f "${USERPATCHES_PATH}/firstboot.conf" ]]; then + display_alert "Use user provided firstboot config" "" "info" + cp "${USERPATCHES_PATH}/firstboot.conf" "${SDCARD}"/root/.not_logged_in_yet + fi + if [[ ${DESKTOP_AUTOLOGIN} == yes ]]; then # set desktop autologin touch "${SDCARD}"/root/.desktop_autologin fi # NOTE: this needs to be executed before family_tweaks + local bootscript_src_path local bootscript_src=${BOOTSCRIPT%%:*} local bootscript_dst=${BOOTSCRIPT##*:} + if [[ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]]; then + bootscript_src_path="${USERPATCHES_PATH}/bootscripts" + else + bootscript_src_path="${SRC}/config/bootscripts" + fi + # create extlinux config file @TODO: refactor into extensions u-boot, extlinux if [[ $SRC_EXTLINUX == yes ]]; then display_alert "Using extlinux, SRC_EXTLINUX: ${SRC_EXTLINUX}" "$NAME_KERNEL - $NAME_INITRD" "info" @@ -153,12 +232,20 @@ function install_distribution_agnostic() { else # ... not extlinux ... if [[ -n "${BOOTSCRIPT}" ]]; then # @TODO: && "${BOOTCONFIG}" != "none" - display_alert "Deploying boot script" "$bootscript_src" "info" - if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then - run_host_command_logged cp -pv "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}" - else - run_host_command_logged cp -pv "${SRC}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}" - fi + case "${bootscript_src}" in + *'.template') + display_alert "Rendering boot script template" "${bootscript_src_path}/${bootscript_src}" "info" + run_host_command_logged cat "${bootscript_src_path}/${bootscript_src}" | render_bootscript_template > "${SDCARD}/boot/${bootscript_dst}" + + if ! proof_rendered_bootscript_template "${SDCARD}/boot/${bootscript_dst}" ; then + exit_with_error "Render of bootscript template was not successful. Inspect '${SDCARD}/boot/${bootscript_dst}' for unrendered variables." + fi + ;; + *) + display_alert "Deploying boot script" "${bootscript_src_path}/${bootscript_src}" "info" + run_host_command_logged cp -pv "${bootscript_src_path}/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}" + ;; + esac fi if [[ -n $BOOTENV_FILE ]]; then diff --git a/lib/functions/rootfs/distro-specific.sh b/lib/functions/rootfs/distro-specific.sh index 81350da96..4e720fe0c 100644 --- a/lib/functions/rootfs/distro-specific.sh +++ b/lib/functions/rootfs/distro-specific.sh @@ -35,6 +35,26 @@ function install_distribution_specific() { truncate --size=0 "${SDCARD}"/etc/apt/apt.conf.d/20apt-esm-hook.conf fi + # Add power-management override. + # Suspend / hibernate / hybrid-sleep are known to be unreliable or completely + # non-functional on the majority of single board computers due to incomplete + # vendor kernels, broken device drivers, or lack of proper firmware support. + # To avoid random lockups, data loss, or boards failing to wake up, we disable + # all systemd sleep modes by default. + # Users who understand the risks and have hardware that supports stable sleep + # states can re-enable them by setting: + # POWER_MANAGEMENT_FEATURES=yes + if [[ "${POWER_MANAGEMENT_FEATURES:-"no"}" != "yes" ]]; then + mkdir -p "${SDCARD}/etc/systemd/sleep.conf.d" + cat <<- EOF > "${SDCARD}/etc/systemd/sleep.conf.d/00-disable.conf" + [Sleep] + AllowSuspend=no + AllowHibernation=no + AllowHybridSleep=no + AllowSuspendThenHibernate=no + EOF + fi + # install our base-files package (this replaces the original from Debian/Ubuntu) if [[ "${KEEP_ORIGINAL_OS_RELEASE:-"no"}" != "yes" ]]; then install_artifact_deb_chroot "armbian-base-files" "--allow-downgrades" @@ -66,10 +86,87 @@ function install_distribution_specific() { fi } +#fetch_distro_keyring +# +# : debian or ubuntu release name +# +function fetch_distro_keyring() { + declare release="${1}" + declare distro="" + + case $release in + buster | bullseye | bookworm | trixie | forky | sid) + distro="debian" + ;; + focal | jammy | noble | oracular | plucky | questing | resolute ) + distro="ubuntu" + ;; + *) + exit_with_error "fetch_distro_keyring failed" "unrecognized release: $release" + esac + + CACHEDIR="/armbian/cache/keyrings/$distro" + mkdir -p "${CACHEDIR}" + case $distro in + #FIXME: there may be a point where we need an *older* keyring pkg + # NOTE: this will be most likely an unsupported case like a user wanting to build using an ancient debian/ubuntu release + debian) + if [ -e "${CACHEDIR}/debian-archive-keyring.gpg" ]; then + display_alert "fetch_distro_keyring($release)" "cache found, skipping" "info" + else + # for details of how this gets into this mirror, see + # github.com/armbian/armbian.github.io/ .github/workflows/generate-keyring-data.yaml + for p in debian-archive-keyring debian-ports-archive-keyring; do + # if we use http://, we'll get a 301 to https://, but this means we can't use a caching proxy like ACNG + PKG_URL="https://github.armbian.com/keyrings/latest-${p}.deb" + run_host_command_logged curl -fLOJ --output-dir "${CACHEDIR}" "${PKG_URL}" || \ + exit_with_error "fetch_distro_keyring failed" "unable to download ${PKG_URL}" + KEYRING_DEB=$(basename "${PKG_URL}") + # We ignore errors from dpkg-deb/tar b/c we cannot tell the difference between unpack failures and chmod/chgrp failures + dpkg-deb -x "${CACHEDIR}/${KEYRING_DEB}" "${CACHEDIR}" || /bin/true # ignore failures, we'll check a few lines down + if [[ -e "${CACHEDIR}/usr/share/keyrings/${p}.pgp" ]]; then + # yes, the canonical name is .pgp, but our tools expect .gpg. + # the package contains the .pgp and a .gpg symlink to it. + cp -l "${CACHEDIR}/usr/share/keyrings/${p}.pgp" "${CACHEDIR}/${p}.gpg" + elif [[ -e "${CACHEDIR}/usr/share/keyrings/${p}.gpg" ]]; then + cp -l "${CACHEDIR}/usr/share/keyrings/${p}.gpg" "${CACHEDIR}/${p}.gpg" + else + exit_with_error "fetch_distro_keyring" "unable to find ${p}.gpg" + fi + done + display_alert "fetch_distro_keyring($release)" "extracted" "info" + fi + ;; + ubuntu) + if [ -e "${CACHEDIR}/ubuntu-archive-keyring.gpg" ]; then + display_alert "fetch_distro_keyring($release)" "cache found, skipping" "info" + else + PKG_URL="https://github.armbian.com/keyrings/latest-ubuntu-keyring.deb" + run_host_command_logged curl -fLOJ --output-dir "${CACHEDIR}" "${PKG_URL}" || \ + exit_with_error "fetch_distro_keyring failed" "unable to download ${PKG_URL}" + KEYRING_DEB=$(basename "${PKG_URL}") + dpkg-deb -x "${CACHEDIR}/${KEYRING_DEB}" "${CACHEDIR}" || /bin/true # see above in debian block about ignoring errors + if [[ ! -e "${CACHEDIR}/usr/share/keyrings/ubuntu-archive-keyring.gpg" ]]; then + exit_with_error "fetch_distro_keyring" "unable to find ubuntu-archive-keyring.gpg" + fi + cp -l "${CACHEDIR}/usr/share/keyrings/ubuntu-archive-keyring.gpg" "${CACHEDIR}/" + display_alert "fetch_distro_keyring($release)" "extracted" "info" + fi + debootstrap_arguments+=("--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg") + ;; + *) + exit_with_error "fetch_distro_keyring" "unrecognized distro: $distro" + esac + # cp -l may break here if it's cross-filesystem + # copy everything to the "host" inside the container + cp -r "${CACHEDIR}"/{etc,usr} / || exit_with_error "fetch_distro_keyring" "failed to copy keyrings to host" + debootstrap_arguments+=("--setup-hook='copy-in ${CACHEDIR}/usr ${CACHEDIR}/etc /'") +} + # create_sources_list_and_deploy_repo_key # # : rootfs|image -# : bullseye|bookworm|sid|focal|jammy|noble|oracular|plucky +# : bullseye|bookworm|trixie|forky|sid|focal|jammy|noble|oracular|plucky|questing|resolute # : path to root directory # function create_sources_list_and_deploy_repo_key() { @@ -85,7 +182,7 @@ function create_sources_list_and_deploy_repo_key() { # Add upstream (Debian/Ubuntu) APT repository case $release in - buster | bullseye | bookworm | trixie) + buster | bullseye | bookworm | trixie | forky) distro="debian" declare -a suites=("${release}" "${release}-updates") @@ -151,7 +248,7 @@ function create_sources_list_and_deploy_repo_key() { fi ;; - focal | jammy | noble | oracular | plucky) + focal | jammy | noble | oracular | plucky | questing | resolute) distro="ubuntu" cat <<- EOF > "${basedir}/etc/apt/sources.list.d/${distro}.sources" diff --git a/lib/functions/rootfs/rootfs-create.sh b/lib/functions/rootfs/rootfs-create.sh index 0f0ab0374..9606c969d 100644 --- a/lib/functions/rootfs/rootfs-create.sh +++ b/lib/functions/rootfs/rootfs-create.sh @@ -45,92 +45,173 @@ function create_new_rootfs_cache_tarball() { display_alert "rootfs cache created" "${cache_fname} [${cache_size}]" "info" } +# create_new_rootfs_cache_via_debootstrap populates a root FS into +# SDCARD using mmdebstrap [or debootstrap if LEGACY_DEBOOTSTRAP], +# configures locales and apt sources, installs additional packages (and +# optionally desktop packages), performs chroot setup and cleanup +# (policy diverts, qemu-binfmt handling, resolvconf, machine-id +# masking), and prepares the rootfs for packaging & caching. function create_new_rootfs_cache_via_debootstrap() { + LOG_NAME="" + case "${LEGACY_DEBOOTSTRAP,,}" in + "yes") + LOG_NAME="debootstrap" + ;; + "no") + LOG_NAME="mmdebstrap" + ;; + "") + LOG_NAME="mmdebstrap" + LEGACY_DEBOOTSTRAP="no" + ;; + *) + exit_with_error "invalid value for LEGACY_DEBOOTSTRAP: ${LEGACY_DEBOOTSTRAP}" + ;; + esac [[ ! -d "${SDCARD:?}" ]] && exit_with_error "create_new_rootfs_cache_via_debootstrap: ${SDCARD} is not a directory" # this is different between debootstrap and regular apt-get; here we use acng as a prefix to the real repo declare debootstrap_apt_mirror="http://${APT_MIRROR}" - if [[ "${MANAGE_ACNG}" == "yes" ]]; then - local debootstrap_apt_mirror="http://localhost:3142/${APT_MIRROR}" - acng_check_status_or_restart - fi - - # @TODO: one day: https://gitlab.mister-muffin.de/josch/mmdebstrap/src/branch/main/mmdebstrap - - # Obtain the latest debootstrap (which is just a shell script) from Debian or Ubuntu's git at the latest development version - declare debootstrap_bin="" debootstrap_version="" debootstrap_wanted_dir="" debootstrap_default_script="" - - display_alert "Preparing debootstrap" "for ${DISTRIBUTION}'s ${RELEASE}" "info" - case "${DISTRIBUTION}" in - Ubuntu) - GIT_FIXED_WORKDIR="debootstrap-ubuntu-devel" fetch_from_repo "https://git.launchpad.net/ubuntu/+source/debootstrap" "debootstrap-ubuntu-devel" "tag:import/1.0.118ubuntu1.13" - debootstrap_wanted_dir="${SRC}/cache/sources/debootstrap-ubuntu-devel" - debootstrap_default_script="gutsy" - ;; - Debian) - GIT_FIXED_WORKDIR="debootstrap-debian-devel" fetch_from_repo "https://salsa.debian.org/installer-team/debootstrap.git" "debootstrap-debian-devel" "branch:master" - debootstrap_wanted_dir="${SRC}/cache/sources/debootstrap-debian-devel" - debootstrap_default_script="sid" + case "${MANAGE_ACNG}" in + yes) + local debootstrap_apt_mirror="http://localhost:3142/${APT_MIRROR}" + acng_check_status_or_restart ;; + no) ;& # do nothing, fallthrough + "") + : # still do nothing + ;; # stop falling *) - exit_with_error "Unknown distribution for debootstrap" "${DISTRIBUTION}" + if [[ ! "${MANAGE_ACNG}" =~ ^https?:// ]]; then + exit_with_error "MANAGE_ACNG must be yes/no OR be a full URL with http/https" "${MANAGE_ACNG}" + else + # FIXME: although this works with mmdebstrap, there's a more idiomatic way with `--aptopt` + local debootstrap_apt_mirror="${MANAGE_ACNG}/${APT_MIRROR}" + fi + ;; + esac + + # @TODO: one day: https://gitlab.mister-muffin.de/josch/mmdebstrap/src/branch/main/mmdebstrap + + # Obtain the latest debootstrap/mmdebstrap (which is just a shell script) from mister-muffin or Ubuntu's git + declare debootstrap_bin="" debootstrap_version="" debootstrap_wanted_dir="" debootstrap_default_script="" + + display_alert "Preparing ${LOG_NAME}" "for ${DISTRIBUTION}'s ${RELEASE}" "info" + case "${DISTRIBUTION}" in + Ubuntu) + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "yes" ]]; then + export GIT_FIXED_WORKDIR="debootstrap-ubuntu-devel" + fetch_from_repo "https://git.launchpad.net/ubuntu/+source/debootstrap" "debootstrap-ubuntu-devel" "tag:import/1.0.118ubuntu1.13" + debootstrap_wanted_dir="${SRC}/cache/sources/${GIT_FIXED_WORKDIR}" + debootstrap_default_script="gutsy" + debootstrap_version="$(sed 's/.*(\(.*\)).*/\1/; q' "${debootstrap_wanted_dir}/debian/changelog")" + debootstrap_bin="${debootstrap_wanted_dir}/debootstrap" + else + export GIT_FIXED_WORKDIR="mmdebstrap-ubuntu-devel" + #FIXME: branch should be a variable eventually + fetch_from_repo "https://git.launchpad.net/ubuntu/+source/mmdebstrap" "${GIT_FIXED_WORKDIR}" "branch:ubuntu/noble" + debootstrap_wanted_dir="${SRC}/cache/sources/${GIT_FIXED_WORKDIR}" + debootstrap_version="$(sed 's/.*(\(.*\)).*/\1/; q' "${debootstrap_wanted_dir}/debian/changelog")" + debootstrap_bin="${debootstrap_wanted_dir}/mmdebstrap" + fi + ;; + Debian) + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "yes" ]]; then + export GIT_FIXED_WORKDIR="debootstrap-debian-devel" + fetch_from_repo "https://salsa.debian.org/installer-team/debootstrap.git" "debootstrap-debian-devel" "branch:master" + debootstrap_wanted_dir="${SRC}/cache/sources/${GIT_FIXED_WORKDIR}" + debootstrap_default_script="sid" + debootstrap_version="$(sed 's/.*(\(.*\)).*/\1/; q' "${debootstrap_wanted_dir}/debian/changelog")" + debootstrap_bin="${debootstrap_wanted_dir}/debootstrap" + else + export GIT_FIXED_WORKDIR="mmdebstrap-debian-devel" + #FIXME: branch should be a variable eventually + fetch_from_repo "https://gitlab.mister-muffin.de/josch/mmdebstrap" "${GIT_FIXED_WORKDIR}" "branch:main" + debootstrap_wanted_dir="${SRC}/cache/sources/${GIT_FIXED_WORKDIR}" + debootstrap_default_script="sid" + debootstrap_version="$(sed 's/^## \[\([^]]*\)\].*/\1/; q' "${debootstrap_wanted_dir}/CHANGELOG.md")" + debootstrap_bin="${debootstrap_wanted_dir}/mmdebstrap" + fi + ;; + *) + exit_with_error "Unknown distribution for ${LOG_NAME}" "${DISTRIBUTION}" ;; esac - debootstrap_bin="${debootstrap_wanted_dir}/debootstrap" - debootstrap_version="$(sed 's/.*(\(.*\)).*/\1/; q' "${debootstrap_wanted_dir}/debian/changelog")" run_host_command_logged chmod a+x "${debootstrap_bin}" - display_alert "Debootstrap version" "'${debootstrap_version}' for ${debootstrap_bin}" "info" + display_alert "${LOG_NAME} version" "'${debootstrap_version}' for ${debootstrap_bin}" "info" - # check if the debootstrap has the scripts/${RELEASE} script present, otherwise symlink it to debootstrap_default_script - if [[ ! -f "${debootstrap_wanted_dir}/scripts/${RELEASE}" ]]; then - display_alert "Symlinking" "debootstrap scripts/${RELEASE} to scripts/${debootstrap_default_script}" "info" - run_host_command_logged ln -sv "${debootstrap_wanted_dir}/scripts/${debootstrap_default_script}" "${debootstrap_wanted_dir}/scripts/${RELEASE}" + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "yes" ]]; then + # check if the debootstrap has the scripts/${RELEASE} script present, otherwise symlink it to debootstrap_default_script + if [[ ! -f "${debootstrap_wanted_dir}/scripts/${RELEASE}" ]]; then + display_alert "Symlinking" "debootstrap scripts/${RELEASE} to scripts/${debootstrap_default_script}" "info" + run_host_command_logged ln -sv "${debootstrap_wanted_dir}/scripts/${debootstrap_default_script}" "${debootstrap_wanted_dir}/scripts/${RELEASE}" + fi + display_alert "Installing base system with ${#AGGREGATED_PACKAGES_DEBOOTSTRAP[@]} packages" "Stage 1/2" "info" + else + display_alert "Installing base system with ${#AGGREGATED_PACKAGES_DEBOOTSTRAP[@]} packages" "Stage 1/1" "info" fi - - display_alert "Installing base system with ${#AGGREGATED_PACKAGES_DEBOOTSTRAP[@]} packages" "Stage 1/2" "info" cd "${SDCARD}" || exit_with_error "cray-cray about SDCARD" "${SDCARD}" # this will prevent error sh: 0: getcwd() failed - declare -a deboostrap_arguments=( + declare -ga debootstrap_arguments=( "--variant=minbase" # minimal base variant. go ask Debian about it. "--arch=${ARCH}" # the arch "'--include=${AGGREGATED_PACKAGES_DEBOOTSTRAP_COMMA}'" # from aggregation.py "'--components=${AGGREGATED_DEBOOTSTRAP_COMPONENTS_COMMA}'" # from aggregation.py ) - - # This is necessary to debootstrap from a non-official repo - [[ $ARCH == loong64 ]] && deboostrap_arguments+=("--keyring=/usr/share/keyrings/debian-ports-archive-keyring.gpg") - # Small detour for local apt caching option. - local_apt_deb_cache_prepare "before debootstrap" # sets LOCAL_APT_CACHE_INFO - if [[ "${LOCAL_APT_CACHE_INFO[USE]}" == "yes" ]]; then - deboostrap_arguments+=("--cache-dir=${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]}") # cache .deb's used + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "no" ]]; then + debootstrap_arguments+=("'--skip=check/empty'") # skips check if the rootfs dir is empty at start + fetch_distro_keyring "$RELEASE" fi - deboostrap_arguments+=("--foreign") # release name + # This is necessary to debootstrap from a non-official repo + [[ $ARCH == loong64 ]] && debootstrap_arguments+=("--keyring=/usr/share/keyrings/debian-ports-archive-keyring.gpg") + # Small detour for local apt caching option. + local_apt_deb_cache_prepare "before ${LOG_NAME}" # sets LOCAL_APT_CACHE_INFO + if [[ "${LOCAL_APT_CACHE_INFO[USE]}" == "yes" ]]; then + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "no" ]]; then + debootstrap_arguments+=("--setup-hook='mkdir -p ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]} \"\$1\"/var/cache/apt/archives/'") + debootstrap_arguments+=("--setup-hook='sync-in ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]} /var/cache/apt/archives/'") + debootstrap_arguments+=("--customize-hook='sync-out /var/cache/apt/archives/ ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]}'") + else + debootstrap_arguments+=("--cache-dir=${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]}") # cache .deb's used + debootstrap_arguments+=("--foreign") # prefixed before release name + fi + fi - deboostrap_arguments+=("${RELEASE}" "${SDCARD}/" "${debootstrap_apt_mirror}") # release, path and mirror; always last, positional arguments. + debootstrap_arguments+=("${RELEASE}" "${SDCARD}/" "${debootstrap_apt_mirror}") # release, path and mirror; always last, positional arguments. - # Set DEBOOTSTRAP_DIR only for this invocation; if we instead export it, the second stage will fail - run_host_command_logged "DEBOOTSTRAP_DIR='${debootstrap_wanted_dir}'" "${debootstrap_bin}" "${deboostrap_arguments[@]}" || { - exit_with_error "Debootstrap first stage failed" "${debootstrap_bin} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL}" - } - [[ ! -f ${SDCARD}/debootstrap/debootstrap ]] && exit_with_error "Debootstrap first stage did not produce marker file" + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "no" ]]; then + run_host_command_logged "${debootstrap_bin}" "${debootstrap_arguments[@]}" || { + exit_with_error "${LOG_NAME} failed" "${debootstrap_bin} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL}" + } + else + # Set DEBOOTSTRAP_DIR only for this invocation + export DEBOOTSTRAP_DIR="${debootstrap_wanted_dir}" + run_host_command_logged "${debootstrap_bin}" "${debootstrap_arguments[@]}" || { + exit_with_error "Debootstrap first stage failed" "${debootstrap_bin} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL}" + } + export -n DEBOOTSTRAP_DIR + [[ ! -f ${SDCARD}/debootstrap/debootstrap ]] && exit_with_error "Debootstrap first stage did not produce marker file" + fi - skip_target_check="yes" local_apt_deb_cache_prepare "after debootstrap first stage" # just for size reference in logs; skip the target check: debootstrap uses it for second stage. + skip_target_check="yes" local_apt_deb_cache_prepare "for ${LOG_NAME}" # just for size reference in logs deploy_qemu_binary_to_chroot "${SDCARD}" "rootfs" # undeployed near the end of this function - display_alert "Installing base system" "Stage 2/2" "info" - declare -g -a if_error_find_files_sdcard=("debootstrap.log") # if command fails, go look for this file and show it's contents during error processing - declare -g if_error_detail_message="Debootstrap second stage failed ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL}" - chroot_sdcard LC_ALL=C LANG=C /debootstrap/debootstrap --second-stage - [[ ! -f "${SDCARD}/bin/bash" ]] && exit_with_error "Debootstrap first stage did not produce /bin/bash" + if [[ "${LEGACY_DEBOOTSTRAP,,}" == "yes" ]]; then + display_alert "Installing base system" "Stage 2/2" "info" + declare -g -a if_error_find_files_sdcard=("debootstrap.log") # if command fails, go look for this file and show it's contents during error processing + declare -g if_error_detail_message="Debootstrap second stage failed ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL}" + chroot_sdcard LC_ALL=C LANG=C /debootstrap/debootstrap --second-stage + fi + [[ ! -f "${SDCARD}/bin/bash" ]] && exit_with_error "${LOG_NAME} did not produce /bin/bash" - # Done with debootstrap. Clean-up it's litterbox. - display_alert "Cleaning up after debootstrap" "debootstrap cleanup" "info" + # Done with mmdebstrap. Clean-up its litterbox. + display_alert "Cleaning up after ${LOG_NAME}" "${LOG_NAME} cleanup" "info" run_host_command_logged rm -rf "${SDCARD}/var/cache/apt" "${SDCARD}/var/lib/apt/lists" - local_apt_deb_cache_prepare "after debootstrap second stage" # just for size reference in logs + local_apt_deb_cache_prepare "after ${LOG_NAME} cleanup" # just for size reference in logs mount_chroot "${SDCARD}" # we mount the chroot here... it's un-mounted below when all is done, or by cleanup handler '' @TODO @@ -257,9 +338,9 @@ function create_new_rootfs_cache_via_debootstrap() { # Remove `machine-id` (https://www.freedesktop.org/software/systemd/man/machine-id.html) # Note: As we don't use systemd-firstboot.service functionality, we make it empty to prevent services - # from starting up automatically on first boot on system version 2.50+. If someone is using the same, + # from starting up automatically on first boot on systemd version 2.50+. If someone is using the same, # please reinitialize this to uninitialized. Do note that systemd will start all services then by - # default and that has to be handled in by setting system presets. + # default and that has to be handled by setting system presets. run_host_command_logged echo -n ">" "${SDCARD}/etc/machine-id" run_host_command_logged rm -v "${SDCARD}/var/lib/dbus/machine-id" @@ -271,7 +352,7 @@ function create_new_rootfs_cache_via_debootstrap() { undeploy_qemu_binary_from_chroot "${SDCARD}" "rootfs" # stage: make rootfs cache archive - display_alert "Ending debootstrap process and preparing cache" "$RELEASE" "info" + display_alert "Ending ${LOG_NAME} process and preparing cache" "$RELEASE" "info" wait_for_disk_sync "before tar rootfs" # we're done with using the chroot which we mounted above. diff --git a/lib/tools/shellcheck.sh b/lib/tools/shellcheck.sh index d988b7201..0bf78d987 100755 --- a/lib/tools/shellcheck.sh +++ b/lib/tools/shellcheck.sh @@ -51,7 +51,11 @@ if [[ ! -f "${SHELLCHECK_BIN}" ]]; then echo "MACHINE: ${MACHINE}" echo "Down URL: ${DOWN_URL}" echo "SHELLCHECK_BIN: ${SHELLCHECK_BIN}" - wget -O "${SHELLCHECK_BIN}.tar.xz" "${DOWN_URL}" + curl -fLo "${SHELLCHECK_BIN}.tar.xz" "${DOWN_URL}" || { + echo "download of shellcheck failed from ${DOWN_URL}"; + rm -f "${SHELLCHECK_BIN}.tar.xz" + exit 1; + } tar -xf "${SHELLCHECK_BIN}.tar.xz" -C "${DIR_SHELLCHECK}" "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" mv -v "${DIR_SHELLCHECK}/shellcheck-v${SHELLCHECK_VERSION}/shellcheck" "${SHELLCHECK_BIN}" rm -rf "${DIR_SHELLCHECK}/shellcheck-v${SHELLCHECK_VERSION}" "${SHELLCHECK_BIN}.tar.xz" diff --git a/lib/tools/shellfmt.sh b/lib/tools/shellfmt.sh index 71908ec33..98841721e 100755 --- a/lib/tools/shellfmt.sh +++ b/lib/tools/shellfmt.sh @@ -47,7 +47,11 @@ echo "SHELLFMT_BIN: ${SHELLFMT_BIN}" if [[ ! -f "${SHELLFMT_BIN}" ]]; then echo "Cache miss, downloading..." - wget -O "${SHELLFMT_BIN}" "${DOWN_URL}" + curl -fLo "${SHELLFMT_BIN}" "${DOWN_URL}" || { + echo "shellfmt download failed from ${DOWN_URL}" + rm -f "${SHELLFMT_BIN}" + exit 1; + } chmod +x "${SHELLFMT_BIN}" fi diff --git a/packages/blobs/asound.state/asound.state.youyeetoo-r1 b/packages/blobs/asound.state/asound.state.youyeetoo-r1 new file mode 100644 index 000000000..b771a6e89 --- /dev/null +++ b/packages/blobs/asound.state/asound.state.youyeetoo-r1 @@ -0,0 +1,428 @@ +state.rockchipes8323 { + control.1 { + iface CARD + name 'Headphones Jack' + value false + comment { + access read + type BOOLEAN + count 1 + } + } + control.2 { + iface MIXER + name '3D Mode' + value 'No 3D ' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No 3D ' + item.1 'Level 1' + item.2 'Level 2' + item.3 'Level 3' + item.4 'Level 4' + item.5 'Level 5' + item.6 'Level 6' + item.7 'Level 7' + } + } + control.3 { + iface MIXER + name 'ALC Capture Function' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 Right + item.2 Left + item.3 Stereo + } + } + control.4 { + iface MIXER + name 'ALC Capture NG Type' + value 'Constant PGA Gain' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Constant PGA Gain' + item.1 'Mute ADC Output' + } + } + control.5 { + iface MIXER + name 'Playback De-emphasis' + value None + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 None + item.1 '32Khz' + item.2 '44.1Khz' + item.3 '48Khz' + } + } + control.6 { + iface MIXER + name 'Capture Polarity' + value Normal + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Normal + item.1 'L Invert' + item.2 'R Invert' + item.3 'L + R Invert' + } + } + control.7 { + iface MIXER + name 'ALC Capture ZC Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.8 { + iface MIXER + name 'ALC Capture Decay Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.9 { + iface MIXER + name 'ALC Capture Attack Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.10 { + iface MIXER + name 'ALC Capture NG Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.11 { + iface MIXER + name 'ALC Capture NG Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.12 { + iface MIXER + name 'ZC Timeout Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.13 { + iface MIXER + name 'Capture Mute Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.14 { + iface MIXER + name 'Left Channel Capture Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 8' + dbmin 0 + dbmax 2400 + dbvalue.0 0 + } + } + control.15 { + iface MIXER + name 'Right Channel Capture Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 8' + dbmin 0 + dbmax 2400 + dbvalue.0 0 + } + } + control.16 { + iface MIXER + name 'Left Mixer Left Bypass Volume' + value 7 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -15 + dbmax 2085 + dbvalue.0 2085 + } + } + control.17 { + iface MIXER + name 'Right Mixer Right Bypass Volume' + value 7 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -15 + dbmax 2085 + dbvalue.0 2085 + } + } + control.18 { + iface MIXER + name 'PCM Volume' + value.0 167 + value.1 167 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 192' + dbmin -9999999 + dbmax 0 + dbvalue.0 -1250 + dbvalue.1 -1250 + } + } + control.19 { + iface MIXER + name 'Capture Digital Volume' + value.0 0 + value.1 0 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 192' + dbmin -9999999 + dbmax 0 + dbvalue.0 -9999999 + dbvalue.1 -9999999 + } + } + control.20 { + iface MIXER + name 'Output 1 Playback Volume' + value.0 33 + value.1 33 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 33' + dbmin -4500 + dbmax 450 + dbvalue.0 450 + dbvalue.1 450 + } + } + control.21 { + iface MIXER + name 'Output 2 Playback Volume' + value.0 33 + value.1 33 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 33' + dbmin -4500 + dbmax 450 + dbvalue.0 450 + dbvalue.1 450 + } + } + control.22 { + iface MIXER + name 'Headphones Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.23 { + iface MIXER + name 'Left PGA Mux' + value 'Line 1L' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Line 1L' + item.1 'Line 2L' + item.2 NC + item.3 DifferentialL + } + } + control.24 { + iface MIXER + name 'Right PGA Mux' + value 'Line 2R' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Line 1R' + item.1 'Line 2R' + item.2 NC + item.3 DifferentialR + } + } + control.25 { + iface MIXER + name 'Differential Mux' + value 'Line 1' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Line 1' + item.1 'Line 2' + } + } + control.26 { + iface MIXER + name 'Mono Mux' + value Stereo + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Stereo + item.1 'Mono (Left)' + item.2 'Mono (Right)' + } + } + control.27 { + iface MIXER + name 'Left Line Mux' + value 'Line 1L' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Line 1L' + item.1 'Line 2L' + item.2 NC + item.3 MicL + } + } + control.28 { + iface MIXER + name 'Right Line Mux' + value 'Line 1R' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Line 1R' + item.1 'Line 2R' + item.2 NC + item.3 MicR + } + } + control.29 { + iface MIXER + name 'Left Mixer Left Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.30 { + iface MIXER + name 'Left Mixer Left Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.31 { + iface MIXER + name 'Right Mixer Right Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.32 { + iface MIXER + name 'Right Mixer Right Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.33 { + iface MIXER + name 'OUT1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.34 { + iface MIXER + name 'OUT2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +} diff --git a/packages/bsp/S905X-P212/S905X-P212-HiFi.conf b/packages/bsp/S905X-P212/S905X-P212-HiFi.conf new file mode 100644 index 000000000..ca4326a3b --- /dev/null +++ b/packages/bsp/S905X-P212/S905X-P212-HiFi.conf @@ -0,0 +1,42 @@ +SectionVerb { + Value { + TQ "HiFi" + } +} + +SectionDevice."HDMI" { + Comment "HDMI" + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},0" + } + + EnableSequence [ + cset "name='AIU HDMI CTRL SRC' 'I2S'" + ] + + DisableSequence [ + cset "name='AIU HDMI CTRL SRC' 'DISABLED'" + ] +} + +SectionDevice."Lineout" { + Comment "Lineout" + + Value { + PlaybackPriority 100 + PlaybackPCM "hw:${CardId},0" + PlaybackMixerElem "ACODEC" + } + + EnableSequence [ + cset "name='AIU ACODEC SRC' 'I2S'" + cset "name='AIU ACODEC OUT EN Switch' on" + ] + + DisableSequence [ + cset "name='AIU ACODEC SRC' 'DISABLED'" + cset "name='AIU ACODEC OUT EN Switch' off" + ] +} diff --git a/packages/bsp/S905X-P212/S905X-P212.conf b/packages/bsp/S905X-P212/S905X-P212.conf new file mode 100644 index 000000000..1637a8526 --- /dev/null +++ b/packages/bsp/S905X-P212/S905X-P212.conf @@ -0,0 +1,25 @@ +Syntax 4 + +Comment "S905X P212 Sound" + +SectionUseCase."HiFi" { + File "/Amlogic/gx-sound-card/S905X-P212-HiFi.conf" + Comment "Play HiFi quality music" +} + +BootSequence [ + # Reset to default + cset "name='ACODEC Playback Volume' 255" + cset "name='ACODEC Left DAC Sel' 'Left'" + cset "name='ACODEC Mute Ramp Switch' off" + cset "name='ACODEC Playback Channel Mode' 'Stereo'" + cset "name='ACODEC Ramp Rate' 'Fast'" + cset "name='ACODEC Right DAC Sel' 'Right'" + cset "name='ACODEC Unmute Ramp Switch' off" + cset "name='ACODEC Volume Ramp Switch' off" + cset "name='AIU ACODEC I2S Lane Select' 0" + cset "name='AIU ACODEC OUT EN Switch' off" + cset "name='AIU ACODEC SRC' 'DISABLED'" + cset "name='AIU HDMI CTRL SRC' 'DISABLED'" + cset "name='AIU SPDIF SRC SEL' 'SPDIF'" +] diff --git a/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist b/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist new file mode 100644 index 000000000..1303736df --- /dev/null +++ b/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist @@ -0,0 +1,8 @@ +# configuration values for the armbian-lowmem extension +# intended for use by boards with <256MB RAM +# +# swapfile path +SWAPFILE_PATH=/swapfile +# +# size of swapfile to create in MiB +SWAPFILE_SIZE_MB=256 diff --git a/packages/bsp/armbian-lowmem/lowmem-mkswap.service b/packages/bsp/armbian-lowmem/lowmem-mkswap.service new file mode 100644 index 000000000..58796bc6b --- /dev/null +++ b/packages/bsp/armbian-lowmem/lowmem-mkswap.service @@ -0,0 +1,14 @@ +[Unit] +Description=Armbian lowmem: Create a swapfile +DefaultDependencies=no +Wants=armbian-resize-filesystem.service +After=armbian-resize-filesystem.service +Before=basic.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/lowmem-mkswap.sh +RemainAfterExit=yes + +[Install] +WantedBy=basic.target diff --git a/packages/bsp/armbian-lowmem/lowmem-mkswap.sh b/packages/bsp/armbian-lowmem/lowmem-mkswap.sh new file mode 100755 index 000000000..845a072b5 --- /dev/null +++ b/packages/bsp/armbian-lowmem/lowmem-mkswap.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +SWAPFILE_PATH="/swapfile" +SWAPFILE_SIZE_MB=256 + +[[ -f /etc/default/armbian-lowmem ]] && . /etc/default/armbian-lowmem + +echo "Creating swapfile of size ${SWAPFILE_SIZE_MB}MiB at ${SWAPFILE_PATH}" + +# Safety: do not overwrite existing swapfile +if [[ -f "${SWAPFILE_PATH}" ]]; then + echo "Swapfile ${SWAPFILE_PATH} already exists, not overwriting." >&2 + exit 0 +fi + +# Safety: ensure we have enough free space for the swapfile + headroom +SWAPFILE_BASE=$(dirname "${SWAPFILE_PATH}") +FREE_MB=$(df -Pm "${SWAPFILE_BASE}" | awk 'NR==2{print $4}') +NEEDED_MB=$(( SWAPFILE_SIZE_MB + 64 )) # 64MiB headroom +if (( FREE_MB < NEEDED_MB )); then + echo "Not enough free space in ${SWAPFILE_BASE} to create ${SWAPFILE_SIZE_MB}MiB swapfile." >&2 + exit 1 +fi + +# Create swapfile, set permissions, and enable it +fallocate -l "${SWAPFILE_SIZE_MB}M" "${SWAPFILE_PATH}" +chmod 600 "${SWAPFILE_PATH}" +mkswap "${SWAPFILE_PATH}" +# Add to fstab if not present +if ! grep -qE "^[[:space:]]+${SWAPFILE_PATH}[[:space:]]+swap[[:space:]]" /etc/fstab; then + echo "${SWAPFILE_PATH} swap swap defaults,nofail,discard=once,pri=0 0 0" >> /etc/fstab +fi + +swapon -p 0 "${SWAPFILE_PATH}" diff --git a/packages/bsp/common/etc/cron.daily/armbian-quotes b/packages/bsp/common/etc/cron.daily/armbian-quotes index f7958c558..18d185903 100755 --- a/packages/bsp/common/etc/cron.daily/armbian-quotes +++ b/packages/bsp/common/etc/cron.daily/armbian-quotes @@ -1,3 +1,3 @@ #!/bin/bash -curl --max-time 2 -L -s -o "/tmp/quotes.txt" "https://github.armbian.com/quotes.txt" +curl --max-time 2 -L -s -o "/etc/update-motd.d/quotes.txt" "https://github.armbian.com/quotes.txt" diff --git a/packages/bsp/common/etc/default/armbian-ramlog.dpkg-dist b/packages/bsp/common/etc/default/armbian-ramlog.dpkg-dist index 2a20bc58f..627dc12da 100644 --- a/packages/bsp/common/etc/default/armbian-ramlog.dpkg-dist +++ b/packages/bsp/common/etc/default/armbian-ramlog.dpkg-dist @@ -22,4 +22,7 @@ USE_RSYNC=true # likely a good idea. #XTRA_RSYNC_TO=(--delete) XTRA_RSYNC_FROM=() -XTRA_RSYNC_FROM=() + +# uncomment/change this if you want to move the long-term log storage +# e.g. to use NVMe. +#HDD_LOG=/mnt/nvme/log diff --git a/packages/bsp/common/etc/update-motd.d/00-clear b/packages/bsp/common/etc/update-motd.d/00-clear index e20783b23..9c978b5ce 100755 --- a/packages/bsp/common/etc/update-motd.d/00-clear +++ b/packages/bsp/common/etc/update-motd.d/00-clear @@ -12,10 +12,20 @@ THIS_SCRIPT="clear" MOTD_DISABLE="" -[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd +# Clear runtime MOTD state +MOTD_RUN_DIR="/run/armbian-motd" +if [[ -d "$MOTD_RUN_DIR" ]]; then + rm -f "${MOTD_RUN_DIR}/".*.printed 2>/dev/null +else + mkdir -p "$MOTD_RUN_DIR" 2>/dev/null +fi -for f in $MOTD_DISABLE; do - [[ $f == $THIS_SCRIPT ]] && exit 0 +safe_source() { [[ -f "$1" ]] && . "$1"; } + +# Optional overrides +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 done # Clear screen diff --git a/packages/bsp/common/etc/update-motd.d/10-armbian-header b/packages/bsp/common/etc/update-motd.d/10-armbian-header index 5dc1178f8..dd59d67cd 100755 --- a/packages/bsp/common/etc/update-motd.d/10-armbian-header +++ b/packages/bsp/common/etc/update-motd.d/10-armbian-header @@ -2,237 +2,166 @@ # # Copyright (c) Authors: https://www.armbian.com/authors # -# This file is licensed under the terms of the GNU General Public -# License version 2. This program is licensed "as is" without any -# warranty of any kind, whether express or implied. +# Licensed under the GNU General Public License, version 2. +# Distributed “as is” without any warranty of any kind. -# DO NOT EDIT THIS FILE but add config options to /etc/default/armbian-motd -# any changes will be lost on board support package update +# DO NOT EDIT THIS FILE. +# To customize behavior, override options in /etc/default/armbian-motd. +# Any local edits here will be lost during board support package updates. + +set -o pipefail THIS_SCRIPT="header" MOTD_DISABLE="" -HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth|^vnet|^virbr" -HIDE_LOCAL_IPV6="true" -# Read image configuration -[[ -f /etc/armbian-image-release ]] && . /etc/armbian-image-release -VENDORTEMP="${VENDOR}" +_motd_mark_after_header() { + local base="/run/armbian-motd" + mkdir -p "$base" 2>/dev/null || base="${XDG_RUNTIME_DIR:-/tmp}/armbian-motd" + mkdir -p "$base" 2>/dev/null || return 0 + local stamp="${base}/.after_header.printed" + [[ -e "$stamp" ]] || { echo ""; : >"$stamp"; } +} -# Read update configuration -[[ -f /etc/armbian-release ]] && . /etc/armbian-release +safe_source() { [[ -f "$1" ]] && . "$1"; } -# Keep the VENDOR from image if its defined there -[[ -n "${VENDORTEMP}" && "${VENDORTEMP}" != "${VENDOR}" ]] && VENDOR="${VENDORTEMP}" +# --- Load metadata from image and release files --- +safe_source /etc/armbian-image-release +VENDORTEMP="${VENDOR:-}" +safe_source /etc/armbian-release +[[ -n "${VENDORTEMP}" && "${VENDORTEMP}" != "${VENDOR:-}" ]] && VENDOR="${VENDORTEMP}" +[[ -n "${VENDORPRETTYNAME:-}" ]] && VENDOR="${VENDORPRETTYNAME}" -# If VENDORPRETTYNAME is defined, used that -[[ -n ${VENDORPRETTYNAME} ]] && VENDOR="${VENDORPRETTYNAME}" +# --- Distribution and upgrade information --- +DISTRIBUTION_CODENAME="" +DISTRIBUTION_ID="" +upgrade="" if [[ -f /etc/armbian-distribution-status ]]; then - . /etc/armbian-distribution-status - # Find a way that works - [[ -f /etc/lsb-release ]] && DISTRIBUTION_CODENAME=$(grep CODENAME /etc/lsb-release | cut -d"=" -f2) - [[ -f /etc/lsb-release ]] && DISTRIBUTION_ID=$(grep DISTRIB_ID /etc/lsb-release | cut -d"=" -f2) - [[ -z "${DISTRIBUTION_CODENAME}" && -f /etc/os-release ]] && DISTRIBUTION_CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d"=" -f2) - [[ -z "${DISTRIBUTION_ID}" && -f /etc/os-release ]] && DISTRIBUTION_ID=$(grep "^ID" /etc/os-release | cut -d"=" -f2) - [[ -z "${DISTRIBUTION_CODENAME}" && -x /usr/bin/lsb_release ]] && DISTRIBUTION_CODENAME=$(/usr/bin/lsb_release -c | cut -d":" -f2 | tr -d "\t") - [[ -z "${DISTRIBUTION_ID}" && -x /usr/bin/lsb_release ]] && DISTRIBUTION_ID=$(/usr/bin/lsb_release -i | cut -d":" -f2 | tr -d "\t") - # Read Armbian distribution status - DISTRIBUTION_STATUS=$(grep "^${DISTRIBUTION_CODENAME}" /etc/armbian-distribution-status | cut -d"=" -f2 | cut -d";" -f1) + # Prefer lsb-release (safe to source; no VERSION conflict) + if [[ -f /etc/lsb-release ]]; then + # shellcheck disable=SC1091 + . /etc/lsb-release + DISTRIBUTION_CODENAME="${DISTRIB_CODENAME:-${DISTRIBUTION_CODENAME}}" + DISTRIBUTION_ID="${DISTRIB_ID:-${DISTRIBUTION_ID}}" + fi - # Read upgrade possibilities on stable channel - filter=$(grep "supported" /etc/armbian-distribution-status | cut -d"=" -f1) - upgrade=$(for j in ${filter}; do - for i in $(grep "^${DISTRIBUTION_CODENAME}" /etc/armbian-distribution-status | cut -d";" -f2 | cut -d"=" -f2 | sed "s/,/ /g"); do - if [[ "${i}" == "${j}" ]]; then - echo "${i}" - fi + # If still missing, read only the keys we need from os-release (do NOT source it) + if [[ -z "${DISTRIBUTION_CODENAME}" || -z "${DISTRIBUTION_ID}" ]]; then + if [[ -f /etc/os-release ]]; then + DISTRIBUTION_CODENAME="$(awk -F= '/^VERSION_CODENAME=/{sub(/^"/,"",$2); sub(/"$/,"",$2); print $2}' /etc/os-release)" + DISTRIBUTION_ID="$(awk -F= '/^ID=/{sub(/^"/,"",$2); sub(/"$/,"",$2); print $2}' /etc/os-release)" + fi + fi + + # If still missing, fallback to lsb_release command + if [[ -z "${DISTRIBUTION_CODENAME}" || -z "${DISTRIBUTION_ID}" ]]; then + if command -v lsb_release >/dev/null 2>&1; then + DISTRIBUTION_CODENAME="$(lsb_release -c | awk -F: '{gsub(/\t/,"",$2); print $2}')" + DISTRIBUTION_ID="$(lsb_release -i | awk -F: '{gsub(/\t/,"",$2); print $2}')" + fi + fi + + DISTRIBUTION_STATUS="$(awk -F'[=;]' -v c="${DISTRIBUTION_CODENAME}" '$1==c{print $2; exit}' /etc/armbian-distribution-status)" + filter=$(awk -F= '/supported/{print $1}' /etc/armbian-distribution-status) + current_line="$(awk -F';' -v c="${DISTRIBUTION_CODENAME}" '$1==c{print $2; exit}' /etc/armbian-distribution-status)" + candidates="$(printf '%s\n' "${current_line#*=}" | tr ',' ' ')" + for j in $filter; do + for i in $candidates; do + if [[ "$i" == "$j" ]]; then upgrade="$i"; fi done - done | tail -1) + done fi -[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd +safe_source /etc/default/armbian-motd for f in ${MOTD_DISABLE}; do [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 done -function get_wan_address() { - curl -4 --max-time 2 -s https://ipv4.whatismyip.akamai.com/ -} # get wan ip address +# --- Kernel and system info --- +KERNELID="$(uname -r)" -function get_wan6_address() { - curl -6 --max-time 2 -s https://ipv6.whatismyip.akamai.com/ -} # get wan ip6 address +_motd_mark_after_header -function get_ip_addresses() { - local ipv4s=() - local ipv4 - local address4 - local ipv6s=() - local ipv6 - local address6 - local intf - local f - - for f in /sys/class/net/*; do - intf=$(basename "${f}") - # match only interface names - if [[ ${intf} =~ ${HIDE_IP_PATTERN} ]]; then - continue - else - # List all IP addresses without reordering or duplicates - ipv4=$(ip -4 addr show dev "${intf}") - ipv4=$(echo "${ipv4}" | grep -v "${intf}:avahi") - ipv4=$(echo "${ipv4}" | awk '/inet/ {print $2}') - ipv4=$(echo "${ipv4}" | cut -d'/' -f1) - ipv4=$(echo "${ipv4}" | awk '!x[$0]++') - ipv6=$(ip -6 addr show dev "${intf}") - if [[ "${HIDE_LOCAL_IPV6}" == true ]]; then - ipv6=$(ip -6 addr show dev "${intf}" | grep -v fe80) - fi - ipv6=$(echo "${ipv6}" | grep -v "${intf}:avahi") - ipv6=$(echo "${ipv6}" | awk '/inet6/ {print $2}') - ipv6=$(echo "${ipv6}" | cut -d'/' -f1) - ipv6=$(echo "${ipv6}" | awk '!x[$0]++') - - for address4 in ${ipv4}; do - ipv4s+=("${address4}") - done - for address6 in ${ipv6}; do - ipv6s+=("${address6}") - done - fi - done - - echo "${ipv4s[*]}|${ipv6s[*]}" -} # get_ip_addresses - -# Read Armbian kernel version -KERNELID=$(uname -r) -# Get other variables -ip_address=$(get_ip_addresses &) -wan_ip_address=$(get_wan_address &) -wan_ip6_address=$(get_wan6_address &) - -# Get access point info -if systemctl is-active --quiet service hostapd && [[ -f /etc/hostapd/hostapd.conf ]]; then - . /etc/hostapd/hostapd.conf -fi - -# Display software vendor logo -if [[ -n "${VENDORCOLOR}" ]]; then - echo -e "\e[38;2;${VENDORCOLOR}m$(figlet -f small " ${VENDOR}")\e[0m" +# --- Vendor banner --- +if [[ -n "${VENDORCOLOR:-}" ]]; then + if command -v figlet >/dev/null 2>&1; then + printf '\e[38;2;%sm%s\e[0m\n' "${VENDORCOLOR}" "$(figlet -f small " ${VENDOR}")" + else + printf '\e[38;2;%sm### %s ###\e[0m\n' "${VENDORCOLOR}" "${VENDOR}" + fi else - echo -e "\e[1;91m$(figlet -f small " ${VENDOR}")\e[0m" + if command -v figlet >/dev/null 2>&1; then + printf '\e[1;91m%s\e[0m\n' "$(figlet -f small " ${VENDOR}")" + else + printf '\e[1;91m### %s ###\e[0m\n' "${VENDOR}" + fi fi -# Read RPI model from cpuinfo -if [[ ${BOARD:-} == rpi4b ]]; then - BOARD_NAME=$(tr '\0' '\n' < /proc/device-tree/model | sed -E 's/ Rev [0-9.]+$//') +# --- Board name and version line --- +# Keep BOARD_NAME from Armbian files; only special-case RPi4 model tweak. +if [[ "${BOARD:-}" == "rpi4b" ]]; then + BOARD_NAME="$(tr '\0' '\n' < /proc/device-tree/model | sed -E 's/ Rev [0-9.]+$//')" fi -# Display version, board, and kernel version -[[ ${VERSION} == *trunk* ]] && VERSION=$(echo -e ${VERSION} | cut -d"." -f1-2 | sed "s/\$/ rolling/") -echo -e " \e[0;92mv${VERSION}\x1B[0m for ${BOARD_NAME} running Armbian Linux \e[0;92m${KERNELID^}\x1B[0m" +# Preserve Armbian VERSION; if it ends with "trunk", show "rolling" +if [[ "${VERSION:-}" == *trunk* ]]; then + VERSION="$(printf '%s' "${VERSION}" | cut -d'.' -f1-2)" + VERSION="${VERSION} rolling" +fi -# render image and board type +printf ' \e[0;92mv%s\x1B[0m for %s running Armbian Linux \e[0;92m%s\x1B[0m\n' \ + "${VERSION}" "${BOARD_NAME}" "${KERNELID}" + +# --- Hardware support status --- +HARDWARE_STATUS="" if [[ "${IMAGE_TYPE:-}" != "stable" ]]; then - [[ "${IMAGE_TYPE}" == "user-built" ]] && HARDWARE_STATUS="\e[0;91mDIY\x1B[0m (custom image)\x1B[0m" - [[ "${IMAGE_TYPE}" == "nightly" ]] && HARDWARE_STATUS="\e[0;91mfor advanced users\x1B[0m (rolling release)\x1B[0m" + case "${IMAGE_TYPE:-}" in + "user-built") HARDWARE_STATUS=$'\e[0;91mDIY\x1B[0m (custom image)\x1B[0m' ;; + "nightly") HARDWARE_STATUS=$'\e[0;91mfor advanced users\x1B[0m (rolling release)\x1B[0m' ;; + esac else - [[ "${BOARD_TYPE:-}" == "csc" || "${BOARD_TYPE}" == "tvb" ]] && HARDWARE_STATUS="\e[0;91mDIY (community maintained)\x1B[0m" - [[ "${BOARD_TYPE}" == "wip" ]] && HARDWARE_STATUS="\e[0;91mfor advanced users\x1B[0m (work in progress)\x1B[0m" - [[ "${BOARD_TYPE}" == "eos" ]] && HARDWARE_STATUS="\e[0;91mend of life\x1B[0m" + case "${BOARD_TYPE:-}" in + "csc"|"tvb") HARDWARE_STATUS=$'\e[0;91mDIY (community maintained)\x1B[0m' ;; + "wip") HARDWARE_STATUS=$'\e[0;91mfor advanced users\x1B[0m (work in progress)\x1B[0m' ;; + "eos") HARDWARE_STATUS=$'\e[0;91mend of life\x1B[0m' ;; + esac fi -# render distribution status -if [[ ${DISTRIBUTION_STATUS} == supported ]]; then - DISTRO_STATUS="\e[0;92mstable\e[0m (${DISTRIBUTION_CODENAME})" -elif [[ ${DISTRIBUTION_STATUS} == eos ]]; then - DISTRO_STATUS="\e[0;91mend of life\e[0m (${DISTRIBUTION_CODENAME})" -else - DISTRO_STATUS="\e[0;93mrolling\e[0m (${DISTRIBUTION_CODENAME})" -fi +# --- Distribution status line --- +case "${DISTRIBUTION_STATUS:-}" in + supported) DISTRO_STATUS=$'\e[0;92mstable\e[0m' ;; + eos) DISTRO_STATUS=$'\e[0;91mend of life\e[0m' ;; + *) DISTRO_STATUS=$'\e[0;93mrolling\e[0m' ;; +esac +[[ -n "${DISTRIBUTION_CODENAME}" ]] && DISTRO_STATUS+=" (${DISTRIBUTION_CODENAME})" -# read packages update status -[[ -f /var/cache/apt/archives/updates.number ]] && . /var/cache/apt/archives/updates.number -if [[ ${NUM_UPDATES:-} -gt 0 ]]; then - if apt-mark showhold | grep -q linux-image 2> /dev/null; then +# --- Updates status --- +if [[ -f /var/cache/apt/archives/updates.number ]]; then + # shellcheck disable=SC1091 + . /var/cache/apt/archives/updates.number +fi +UPDATE_STATUS="" +if [[ "${NUM_UPDATES:-0}" -gt 0 ]]; then + if apt-mark showhold 2>/dev/null | grep -q '^linux-image'; then UPDATE_STATUS="Kernel upgrade \e[0;91mdisabled\e[0m" else UPDATE_STATUS="Kernel upgrade \e[0;92menabled\e[0m" fi UPDATE_STATUS+=" and \e[1;92m${NUM_UPDATES}\e[0m package" - # Cosmetic is important - [[ ${NUM_UPDATES} -gt 1 ]] && UPDATE_STATUS+="s" + [[ "${NUM_UPDATES}" -gt 1 ]] && UPDATE_STATUS+="s" UPDATE_STATUS+=" available for upgrade\e[0m " fi -# read running Docker containers if any -if systemctl is-active docker > /dev/null; then - CONTAINERS_STATUS=$(docker ps --format "{{.Names}}" | tr '\n' ',' | sed 's/,/, /g' | sed 's/, $//') +printf '\n' + +# --- Display summary --- +if [[ -n "${DISTRO_STATUS:-}" ]]; then + [[ -n "${upgrade}" ]] && DISTRO_STATUS+=", possible distro upgrade (${upgrade})" + printf ' Packages: %s %b\n' "${DISTRIBUTION_ID^}" "${DISTRO_STATUS}" fi -echo "" +[[ -n "${UPDATE_STATUS}" ]] && printf ' Updates: %b\n' "${UPDATE_STATUS}" +[[ -n "${HARDWARE_STATUS}" ]] && printf ' Support: %b\n' "${HARDWARE_STATUS}" -# Display packages status -if [[ -n ${DISTRO_STATUS} ]]; then - if [[ -n "${upgrade}" ]]; then - DISTRO_STATUS+=", possible distro upgrade (${upgrade})" - fi - echo -e " Packages: ${DISTRIBUTION_ID^} ${DISTRO_STATUS}" -fi - -# Display available updates -if [[ -n ${UPDATE_STATUS} ]]; then - echo -e " Updates: ${UPDATE_STATUS}" -fi - -# Display hardware support status -if [[ -n ${HARDWARE_STATUS} ]]; then - echo -e " Support: ${HARDWARE_STATUS}" -fi - -# Display IP addresses -IFS='|' read -r ipv4s ipv6s <<< "${ip_address}" -# remove WAN IPv4 from the list of all IPv4 -if [[ "${ipv4s}" == *${wan_ip_address}* ]]; then - ipv4s=$(echo $ipv4s | sed "s/"${wan_ip_address}"//g" | xargs ) -fi -if [[ -n ${ipv4s} || -n ${wan_ip_address} ]]; then - all_ip_address=" IPv4: " - if [[ -n ${ipv4s} ]]; then - all_ip_address+=" \x1B[93m(LAN)\x1B[0m " - fi - all_ip_address+="\x1B[92m${ipv4s// /, }\x1B[0m " - if [[ -n ${wan_ip_address} ]]; then - all_ip_address+="\x1B[93m(WAN)\x1B[0m \x1B[95m${wan_ip_address}\x1B[0m " - fi - echo -e "${all_ip_address}" -fi -# remove WAN IPv6 from the list of all IPv6 -if [[ -n "${wan_ip6_address}" && "${ipv6s}" == *${wan_ip6_address}* ]]; then - ipv6s=$(echo $ipv6s | sed "s/"${wan_ip6_address}"//g" | xargs ) -fi - -if [[ -n ${ipv6s} || -n ${wan_ip6_address} ]]; then - all_ip6_address=" IPv6: " - if [[ -n ${ipv6s} ]]; then - all_ip6_address+="\x1B[96m${ipv6s// /, }\x1B[0m " - fi - if [[ -n ${wan_ip6_address} ]]; then - all_ip6_address+="\x1B[93m(WAN)\x1B[0m \x1B[95m${wan_ip6_address}\x1B[0m " - fi - echo -e "${all_ip6_address}" -fi - -# Display running docker containers -if [[ -n "${CONTAINERS_STATUS}" ]]; then - echo -e " Containers: \x1B[92m${CONTAINERS_STATUS}\x1B[0m" -fi - -# Display hostapd -if [[ -n ${ssid} ]]; then - echo -e " WiFi AP: SSID: (\x1B[91m${ssid}\x1B[0m), $(iw dev "${interface:-}" info | grep channel | xargs)" -fi - -echo "" +# ensure zero exit when executed directly +(return 0 2>/dev/null) || exit 0 \ No newline at end of file diff --git a/packages/bsp/common/etc/update-motd.d/15-ap-info b/packages/bsp/common/etc/update-motd.d/15-ap-info new file mode 100755 index 000000000..66e7328cf --- /dev/null +++ b/packages/bsp/common/etc/update-motd.d/15-ap-info @@ -0,0 +1,74 @@ +#!/bin/bash +# Print WiFi Access Point info for Armbian MOTD. +# Detects active hostapd instances, parses SSID + interface, shows channel via `iw`. + +set -o pipefail + +# one-time spacer after header (marks that something printed before Performance) +_motd_mark_after_header() { + # prefer /run, fallback to user runtime or /tmp (works when not root) + local base="/run/armbian-motd" + mkdir -p "$base" 2>/dev/null || base="${XDG_RUNTIME_DIR:-/tmp}/armbian-motd" + mkdir -p "$base" 2>/dev/null || return 0 + local stamp="${base}/.after_header.printed" + [[ -e "$stamp" ]] || { echo ""; : >"$stamp"; } +} + +safe_source() { [[ -f "$1" ]] && . "$1"; } + +THIS_SCRIPT="ap-info" +MOTD_DISABLE="" + +# Optional overrides +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 +done + +# helper: pretty-print one AP line +print_ap_line() { + local ssid="$1" iface="$2" + local chan + if command -v iw >/dev/null 2>&1; then + # Grab the whole "channel ..." line from iw and use it as-is + chan="$(iw dev "$iface" info 2>/dev/null \ + | sed -n 's/^[[:space:]]*channel[[:space:]]\+\(.*\)$/\1/p' \ + | head -1)" + fi + printf ' WiFi AP: SSID: (\x1B[91m%s\x1B[0m), channel %s\n' \ + "$ssid" "${chan:-n/a}" +} + +# detect active hostapd services +if systemctl is-active --quiet hostapd.service \ + || systemctl list-units 'hostapd@*.service' --state=active >/dev/null 2>&1; then + + # collect hostapd configs (classic and templated), skip non-existing + confs=() + for p in /etc/hostapd/hostapd.conf /etc/hostapd/hostapd-*.conf; do + [[ -f "$p" ]] && confs+=("$p") + done + + # print at most one line per iface+ssid combo + declare -A _ap_printed=() + first=1 + for cfg in "${confs[@]}"; do + ssid="$(grep -E '^[[:space:]]*ssid[[:space:]]*=' "$cfg" | sed -E 's/.*=//;s/^[[:space:]]+|[[:space:]]+$//')" + iface="$(grep -E '^[[:space:]]*interface[[:space:]]*=' "$cfg" | sed -E 's/.*=//;s/^[[:space:]]+|[[:space:]]+$//')" + + # fall back to iw to discover iface if config lacks it + [[ -z "$iface" ]] && iface="$(iw dev 2>/dev/null | awk '/Interface/ {print $2; exit}')" + + key="${iface}|${ssid}" + [[ -z "$ssid" || -z "$iface" || -n "${_ap_printed[$key]+x}" ]] && continue + + # print exactly one spacer before the first AP line + if (( first )); then _motd_mark_after_header; first=0; fi + + print_ap_line "$ssid" "$iface" + _ap_printed[$key]=1 + done +fi + +# ensure zero exit when executed directly +(return 0 2>/dev/null) || exit 0 diff --git a/packages/bsp/common/etc/update-motd.d/20-ip-info b/packages/bsp/common/etc/update-motd.d/20-ip-info new file mode 100755 index 000000000..cc140b641 --- /dev/null +++ b/packages/bsp/common/etc/update-motd.d/20-ip-info @@ -0,0 +1,112 @@ +#!/bin/bash +# Print LAN/WAN IPv4 and IPv6 lines for Armbian MOTD. +# Standalone: discovers addresses itself and prints formatted output. + +set -o pipefail + +safe_source() { [[ -f "$1" ]] && . "$1"; } + +THIS_SCRIPT="ip-info" +MOTD_DISABLE="" + +# Defaults (can be overridden by /etc/default/armbian-motd if present) +HIDE_IP_PATTERN='^dummy0|^lo|^docker|^hassio|^br-|^veth|^vnet|^virbr' +HIDE_LOCAL_IPV6="true" + +# Optional overrides +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 +done + +# one-time spacer after header (marks that something printed before Performance) +_motd_mark_after_header() { + local base="/run/armbian-motd" + mkdir -p "$base" 2>/dev/null || base="${XDG_RUNTIME_DIR:-/tmp}/armbian-motd" + mkdir -p "$base" 2>/dev/null || return 0 + local stamp="${base}/.after_header.printed" + [[ -e "$stamp" ]] || { echo ""; : >"$stamp"; } +} + +get_wan_address() { curl -4 -fsS --max-time 2 https://ipv4.whatismyip.akamai.com/ 2>/dev/null || true; } +get_wan6_address() { curl -6 -fsS --max-time 2 https://ipv6.whatismyip.akamai.com/ 2>/dev/null || true; } + +get_lan_ips() { + # echo "|" + local ipv4s=() ipv6s=() intf + + for p in /sys/class/net/*; do + intf="${p##*/}" + [[ "$intf" =~ $HIDE_IP_PATTERN ]] && continue + + # IPv4 (order preserved, unique) + mapfile -t add4 < <(ip -4 -o addr show dev "$intf" 2>/dev/null \ + | awk '$3=="inet"{print $4}' | cut -d/ -f1 || true) + for a in "${add4[@]}"; do + [[ " ${ipv4s[*]} " == *" $a "* ]] || ipv4s+=("$a") + done + + # IPv6 (prefer scope global when hiding link-local) + if [[ "${HIDE_LOCAL_IPV6}" == "true" ]]; then + mapfile -t add6 < <(ip -6 -o addr show dev "$intf" scope global 2>/dev/null \ + | awk '$3=="inet6"{print $4}' | cut -d/ -f1 || true) + else + mapfile -t add6 < <(ip -6 -o addr show dev "$intf" 2>/dev/null \ + | awk '$3=="inet6"{print $4}' | cut -d/ -f1 || true) + fi + for a in "${add6[@]}"; do + [[ " ${ipv6s[*]} " == *" $a "* ]] || ipv6s+=("$a") + done + done + + printf '%s|%s\n' "${ipv4s[*]}" "${ipv6s[*]}" +} + +print_ip_lines() { + local ipv4s="$1" ipv6s="$2" wan4="$3" wan6="$4" + # print a single blank line before the first post-header section + _motd_spacer() { + local tag="${1:-after-header}" + local dir="/run/armbian-motd"; local stamp="$dir/.${tag}.printed" + mkdir -p "$dir" 2>/dev/null + [[ -e "$stamp" ]] || { echo ""; : > "$stamp"; } + } + + # Drop WAN duplicates from LAN lists + if [[ -n "$wan4" && " $ipv4s " == *" $wan4 "* ]]; then + ipv4s="$(printf '%s\n' $ipv4s | awk -v w="$wan4" '$0!=w' | paste -sd' ' -)" + fi + if [[ -n "$wan6" && " $ipv6s " == *" $wan6 "* ]]; then + ipv6s="$(printf '%s\n' $ipv6s | awk -v w="$wan6" '$0!=w' | paste -sd' ' -)" + fi + + # IPv4 line + if [[ -n "$ipv4s" || -n "$wan4" ]]; then + _motd_mark_after_header + local line=" IPv4: " + [[ -n "$ipv4s" ]] && line+=" \x1B[93m(LAN)\x1B[0m \x1B[92m${ipv4s// /, }\x1B[0m " + [[ -n "$wan4" ]] && line+="\x1B[93m(WAN)\x1B[0m \x1B[95m${wan4}\x1B[0m " + printf '%b\n' "$line" + fi + + # IPv6 line + if [[ -n "$ipv6s" || -n "$wan6" ]]; then + _motd_mark_after_header + local line=" IPv6: " + [[ -n "$ipv6s" ]] && line+="\x1B[96m${ipv6s// /, }\x1B[0m " + [[ -n "$wan6" ]] && line+="\x1B[93m(WAN)\x1B[0m \x1B[95m${wan6}\x1B[0m " + printf '%b\n' "$line" + fi +} + +main() { + local combo ipv4s ipv6s wan4 wan6 + combo="$(get_lan_ips)" + IFS='|' read -r ipv4s ipv6s <<< "$combo" + wan4="$(get_wan_address)" + wan6="$(get_wan6_address)" + print_ip_lines "$ipv4s" "$ipv6s" "$wan4" "$wan6" +} + +# If sourced, don't run main; if executed, run. +(return 0 2>/dev/null) || main diff --git a/packages/bsp/common/etc/update-motd.d/25-containers-info b/packages/bsp/common/etc/update-motd.d/25-containers-info new file mode 100755 index 000000000..0de12993c --- /dev/null +++ b/packages/bsp/common/etc/update-motd.d/25-containers-info @@ -0,0 +1,53 @@ +#!/bin/bash +# Print running container names for Armbian MOTD (Docker). +# Standalone: discovers containers itself and prints a formatted line, +# identical to the original header behavior. + +set -o pipefail + +safe_source() { [[ -f "$1" ]] && . "$1"; } + +THIS_SCRIPT="containers-info" +MOTD_DISABLE="" + +# Optional overrides +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 +done + +_motd_spacer() { + local tag="${1:-after-header}" + local dir="/run/armbian-motd"; local stamp="$dir/.${tag}.printed" + mkdir -p "$dir" 2>/dev/null + [[ -e "$stamp" ]] || { echo ""; : > "$stamp"; } +} + +# one-time spacer after header (marks that something printed before Performance) +_motd_mark_after_header() { + local base="/run/armbian-motd" + mkdir -p "$base" 2>/dev/null || base="${XDG_RUNTIME_DIR:-/tmp}/armbian-motd" + mkdir -p "$base" 2>/dev/null || return 0 + local stamp="${base}/.after_header.printed" + [[ -e "$stamp" ]] || { echo ""; : >"$stamp"; } +} + + +list_docker_names() { + # Only show names if Docker is active and CLI is present + if systemctl is-active --quiet docker && command -v docker >/dev/null 2>&1; then + docker ps --format '{{.Names}}' 2>/dev/null | paste -sd', ' - + fi +} + +main() { + local names + names="$(list_docker_names)" + if [[ -n "$names" ]]; then + _motd_mark_after_header + printf ' Containers: \x1B[92m%s\x1B[0m\n' "$names" + fi +} + +# If sourced, don't run main; if executed, run. +(return 0 2>/dev/null) || { main; exit 0; } diff --git a/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo b/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo index 7707b1820..b513a3017 100755 --- a/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo +++ b/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo @@ -7,186 +7,236 @@ # warranty of any kind, whether express or implied. # -# DO NOT EDIT THIS FILE but add config options to /etc/default/armbian-motd -# generate system information +# DO NOT EDIT THIS FILE — use /etc/default/armbian-motd for overrides. + +set -o pipefail export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin THIS_SCRIPT="sysinfo" -# don't change default values - they are lost on upgrades. Use /etc/default/armbian-motd for your values - +# Defaults (override in /etc/default/armbian-motd) MOTD_DISABLE="" PRIMARY_INTERFACE="eth0" -PRIMARY_DIRECTION="rx" -STORAGE=/dev/sda1 +PRIMARY_DIRECTION="rx" # rx | tx | both | (anything else to disable) +STORAGE="/dev/sda1" CPU_TEMP_LIMIT=60 -# Temperature offset in Celcius degrees -CPU_TEMP_OFFSET=0 +CPU_TEMP_OFFSET=0 # °C offset HDD_TEMP_LIMIT=60 AMB_TEMP_LIMIT=40 [[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd -for f in $MOTD_DISABLE; do - [[ $f == $THIS_SCRIPT ]] && exit 0 +for f in ${MOTD_DISABLE}; do + [[ "$f" == "$THIS_SCRIPT" ]] && exit 0 done -# don't edit below here +# Optional vendor helpers (ambienttemp, batteryinfo, getboardtemp) +if [[ -r /usr/lib/armbian/armbian-allwinner-battery ]]; then + # shellcheck disable=SC1091 + . /usr/lib/armbian/armbian-allwinner-battery +fi +# Provide safe no-op stubs if functions are missing +command -v ambienttemp >/dev/null 2>&1 || ambienttemp() { echo ""; } +command -v batteryinfo >/dev/null 2>&1 || batteryinfo() { :; } +command -v getboardtemp >/dev/null 2>&1 || getboardtemp() { board_temp=""; } -# Include functions: -# getboardtemp() -# batteryinfo() -# ambienttemp() -source /usr/lib/armbian/armbian-allwinner-battery - -function display() { - # $1=name $2=value $3=red_limit $4=minimal_show_limit $5=unit $6=after $7=acs/desc{ - # battery red color is opposite, lower number - if [[ "$1" == "Battery" ]]; then local great="<"; else local great=">"; fi - if [[ -n "$2" && "$2" -gt "0" && (( "${2%.*}" -ge "$4" )) ]]; then - printf "%-14s" "$1:" - if awk "BEGIN{exit ! ($2 $great $3)}"; then echo -ne "\e[0;91m $2"; else echo -ne "\e[0;92m $2"; fi - printf "%-1s\x1B[0m" "$5" - printf "%-11s\t" "$6" +display() { + # $1=name $2=value $3=red_limit $4=min_show_limit $5=unit $6=after + # Battery uses inverse threshold (lower is worse) + local name="$1" val="$2" red="$3" min="$4" unit="$5" after="$6" + [[ -z "$val" ]] && return 0 + if awk -v v="$val" -v m="$min" -v inv="$name" 'BEGIN{ + if (v+0 <= 0) exit 1; + if (inv=="Battery") exit !(v+0 >= m+0); else exit !(v+0 >= m+0) + }'; then + printf "%-14s" "${name}:" + if awk -v v="$val" -v r="$red" -v inv="$name" 'BEGIN{ + if (inv=="Battery") exit !(v+0 < r+0); else exit !(v+0 > r+0) + }'; then + printf "\e[0;91m %s" "$val" + else + printf "\e[0;92m %s" "$val" + fi + printf "%s\x1B[0m" "$unit" + printf "%-11s\t" "$after" return 1 fi -} # display + return 0 +} -function storage_info() { - # storage info - RootInfo=$(df -h /) - root_usage=$(awk '/\// {print $(NF-1)}' <<<${RootInfo} | sed 's/%//g') - root_total=$(awk '/\// {print $(NF-4)}' <<<${RootInfo}) - StorageInfo=$(df -h $STORAGE 2>/dev/null | grep $STORAGE) - if [[ -n "${StorageInfo}" && ${RootInfo} != *$STORAGE* ]]; then - storage_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g') - storage_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo}) - if [[ -n "$(command -v smartctl)" ]]; then - DISK="${STORAGE::-1}" - storage_temp+=$(smartctl -l scttempsts $DISK 2> /dev/null | grep -i 'Current Temperature:' | awk '{print $(NF-1)}') +storage_info() { + # Root filesystem + local rootInfo storageInfo + rootInfo="$(df -hP /)" + root_usage="$(awk 'NR==2{gsub(/%/,"",$5); print $5}' <<<"$rootInfo")" + root_total="$(awk 'NR==2{print $2}' <<<"$rootInfo")" + + # Optional extra storage (only if it exists and is not the root FS) + if df -hP "$STORAGE" &>/dev/null; then + storageInfo="$(df -hP "$STORAGE" | awk 'NR==2')" + if [[ -n "$storageInfo" ]] && ! grep -q " $STORAGE " <<<"$rootInfo"; then + storage_usage="$(awk '{gsub(/%/,"",$5); print $5}' <<<"$storageInfo")" + storage_total="$(awk '{print $2}' <<<"$storageInfo")" + if command -v smartctl >/dev/null 2>&1; then + local disk="${STORAGE%[0-9]}" + storage_temp="$(smartctl -l scttempsts "$disk" 2>/dev/null \ + | awk -F': *' '/Current Temperature:/ {print $(NF-1)}')" + fi fi fi -} # storage_info +} -# query various systems and send some stuff to the background for overall faster execution. -# Works only with ambienttemp and batteryinfo since A20 is slow enough :) -amb_temp=$(ambienttemp &) +# Collect sensor and storage data +amb_temp="$(ambienttemp)" batteryinfo storage_info getboardtemp critical_load=80 -# get uptime, logged in users and load in one take -UPTIME=$(LC_ALL=C uptime) -UPT1=${UPTIME#*'up '} -UPT2=${UPT1%'user'*} -users=${UPT2//*','} -users=${users//' '} -time=${UPT2%','*} -time=${time//','} -time=$(echo $time | xargs) -load=${UPTIME#*'load average: '} -load=${load//','} -load=$(echo $load | cut -d" " -f1) -[[ $load == 0.0* ]] && load=0.10 -cpucount=$(grep -c processor /proc/cpuinfo) +# Uptime, users, and load +users="$(who 2>/dev/null | wc -l | tr -d ' ')" +time="$(uptime -p 2>/dev/null | sed -e 's/^up //')" +[[ -z "$time" ]] && time="$(LC_ALL=C uptime | sed -E 's/.*up ([^,]+), .*/\1/')" -load=$(awk '{printf("%.0f",($1/$2) * 100)}' <<< "$load $cpucount") +cpucount="$(grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)" +read -r load1 _ < /proc/loadavg +[[ "$load1" == 0.0* ]] && load1="0.10" +load="$(awk -v l="$load1" -v c="$cpucount" 'BEGIN{printf("%.0f",(l/c)*100)}')" -# memory and swap -mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem") -memory_usage=$(awk '{printf("%.0f",(($2-($4+$6+$7))/$2) * 100)}' <<<${mem_info}) -mem_info=$(echo $mem_info | awk '{print $2}') -memory_total=$(( mem_info / 1024 )) -swap_info=$(LC_ALL=C free -m | grep "^Swap") -swap_usage=$( (awk '/Swap/ { printf("%3.0f", $3/$2*100) }' <<<${swap_info} 2>/dev/null || echo 0) | tr -c -d '[:digit:]') -swap_total=$(awk '{print $(2)}' <<<${swap_info}) +# Memory / swap +read -r mem_total_kb _ < <(awk '/MemTotal:/ {print $2" "$3; exit}' /proc/meminfo) +mem_total_mb="$(( mem_total_kb / 1024 ))" +mem_used_kb="$(awk ' + /MemTotal:/ {t=$2} + /MemFree:/ {f=$2} + /Buffers:/ {b=$2} + /^Cached:/ {c=$2} + END{printf("%d", t-f-b-c)} +' /proc/meminfo)" +memory_usage="$(awk -v u="$mem_used_kb" -v t="$mem_total_kb" 'BEGIN{printf("%.0f", (u/t)*100)}')" -# display info +swap_total_mb="$(awk '/SwapTotal:/ {print int($2/1024)}' /proc/meminfo)" +swap_used_mb="$(awk '/SwapFree:/ {sf=$2} /SwapTotal:/ {st=$2} END{print int((st-sf)/1024)}' /proc/meminfo)" +if [[ "${swap_total_mb:-0}" -gt 0 ]]; then + swap_usage="$(awk -v u="$swap_used_mb" -v t="$swap_total_mb" 'BEGIN{printf("%3.0f", (u/t)*100)}')" +else + swap_total_mb=0 + swap_usage=0 +fi -# draw a line to start this section +# --- spacing before Performance --- +# Add a blank line only if something printed before (e.g., IP, containers, AP) +if [[ -e /run/armbian-motd/.after_header.printed ]] \ + || [[ -e "${XDG_RUNTIME_DIR:-/tmp}/armbian-motd/.after_header.printed" ]]; then + echo "" +fi +printf "\e[0;90m Performance: \x1B[0m\n\n" -#echo "" -printf "\e[0;90m Performance: \x1B[0m" -echo "" # fixed newline +display " Load" "${load%% *}" "$critical_load" "0" "%" "" +printf " Uptime: \x1B[92m%s\x1B[0m\t" "${time:-unknown}" +display " Local users" "${users:-0}" "3" "2" "" "" echo "" -display " Load" "${load%% *}" "${critical_load}" "0" "%" "" -printf " Uptime: \x1B[92m%s\x1B[0m\t" "$time" -display " Local users" "${users##* }" "3" "2" "" -echo "" # fixed newline -if [[ ${memory_total} -gt 1000 ]]; then - memory_total=$(awk '{printf("%.2f",$1/1024)}' <<<${memory_total})"G" +# Humanize totals +if (( mem_total_mb > 1000 )); then + memory_total="$(awk -v m="$mem_total_mb" 'BEGIN{printf("%.2fG", m/1024)}')" else - memory_total+="M" + memory_total="${mem_total_mb}M" fi -if [[ ${swap_total} -gt 500 ]]; then - swap_total=$(awk '{printf("%.2f",$1/1024)}' <<<${swap_total})"G" +if (( swap_total_mb > 500 )); then + swap_total_disp="$(awk -v s="$swap_total_mb" 'BEGIN{printf("%.2fG", s/1024)}')" else - swap_total+="M" + swap_total_disp="${swap_total_mb}M" fi -display " Memory usage" "$memory_usage" "70" "0" "%" " of ${memory_total}" -display " Zram usage" "$swap_usage" "75" "0" "%" " of ${swap_total}" -echo "" # fixed newline -display " CPU temp" "$board_temp" $CPU_TEMP_LIMIT "0" "°C" "" -display " Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" -display " Usage of /" "$root_usage" "90" "1" "%" " of $root_total $overlay_root" -if command -v overlayroot-chroot > /dev/null 2>&1 && findmnt -k /media/root-ro | tail -1 | grep -w /media/root-ro > /dev/null 2>&1; then -echo -ne "\x1B[91m(read only rootfs)\x1B[0m" +display " Memory usage" "$memory_usage" "70" "0" "%" " of ${memory_total}" +display " Zram usage" "$swap_usage" "75" "0" "%" " of ${swap_total_disp}" +echo "" + +# Temperatures & root usage +# Apply optional CPU temp offset if both numeric +if [[ -n "${board_temp:-}" ]] && awk -v t="$board_temp" -v o="$CPU_TEMP_OFFSET" 'BEGIN{exit !(t ~ /^-?[0-9.]+$/ && o ~ /^-?[0-9.]+$/)}'; then + board_temp="$(awk -v t="$board_temp" -v o="$CPU_TEMP_OFFSET" 'BEGIN{printf("%.1f", t+o)}')" fi -echo "" # fixed newline + +# Truncate temperature decimals (e.g. 37.6 → 37) +cpu_temp_int=$(printf '%.0f\n' "${board_temp%%.*}") +amb_temp_int=$(printf '%.0f\n' "${amb_temp%%.*}") + +display " CPU temp" "$cpu_temp_int" "$CPU_TEMP_LIMIT" "0" "°C" "" +display " Ambient temp" "$amb_temp_int" "$AMB_TEMP_LIMIT" "0" "°C" "" +display " Usage of /" "${root_usage:-0}" "90" "1" "%" " of ${root_total} ${overlay_root}" + +if command -v overlayroot-chroot >/dev/null 2>&1 && findmnt -k /media/root-ro | tail -1 | grep -qw /media/root-ro; then + echo -ne "\x1B[91m(read only rootfs)\x1B[0m" +fi +echo "" + +# Optional secondary storage / disk temp / battery a=0 -display " storage /" "$storage_usage" "90" "1" "%" " of $storage_total" ; a=$((a+$?)) -display " storage temp" "$storage_temp" $HDD_TEMP_LIMIT "0" "°C" "" ; a=$((a+$?)) -display " Battery" "$battery_percent" "20" "1" "%" "$status_battery_text" ; a=$((a+$?)) -(( $a > 0 )) && echo "" # new line only if some value is displayed +display " storage /" "${storage_usage:-0}" "90" "1" "%" " of ${storage_total:-}" ; a=$((a+$?)) +display " storage temp" "${storage_temp:-0}" "$HDD_TEMP_LIMIT" "0" "°C" "" ; a=$((a+$?)) +display " Battery" "${battery_percent:-0}" "20" "1" "%" "${status_battery_text:-}" ; a=$((a+$?)) +(( a > 0 )) && echo "" -line=0 -if [[ -n "$PRIMARY_INTERFACE" ]] && vnstat -i "$PRIMARY_INTERFACE" &> /dev/null; then - traffic=$(LC_ALL=C vnstat -i $PRIMARY_INTERFACE --oneline | cut -d";" -f4,5) - traffic_rx=$(echo $traffic | cut -d";" -f1,1 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/' | cut -d" " -f1 | cut -d"." -f1) - traffic_rx_unit=$(echo $traffic | cut -d";" -f1,1 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/' | cut -d" " -f2) - traffic_tx=$(echo $traffic | cut -d";" -f2,2 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/' | cut -d" " -f1 | cut -d"." -f1) - traffic_tx_unit=$(echo $traffic | cut -d";" -f2,2 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/' | cut -d" " -f2) - [[ "$traffic" == *"Not enough"* ]] && { traffic_tx="n/a "; traffic_rx="n/a "; } - case $PRIMARY_DIRECTION in - tx) - display " TX today" "$traffic_tx" 500 0 "" "$traffic_tx_unit" "" - line=$((line+1)) - ;; - rx) - display " RX today" "$traffic_rx" 500 0 "" "$traffic_rx_unit" "" - line=$((line+1)) - ;; - both) - display " TX today" "$traffic_tx" 500 0 "" "$traffic_tx_unit" "" - display " RX today" "$traffic_rx" 500 0 "" "$traffic_rx_unit" "" - line=$((line+1)) - ;; - *) #off or whatever - ;; - esac +# vnStat daily traffic (if available) +if [[ -n "$PRIMARY_INTERFACE" ]] && command -v vnstat >/dev/null 2>&1; then + if vnstat -i "$PRIMARY_INTERFACE" &>/dev/null; then + # Use C locale so decimals are '.' and units are ASCII. + line="$(LC_ALL=C vnstat -i "$PRIMARY_INTERFACE" --oneline 2>/dev/null)" + # Fields 4 and 5 are today's RX;TX totals. They may be like "205.88KiB" or "205.88 KiB". + rx_raw="$(cut -d';' -f4 <<<"$line")" + tx_raw="$(cut -d';' -f5 <<<"$line")" + + # Normalize: extract integer value (truncate decimals) and unit; ensure exactly one space. + norm_val() { sed -E 's/^([0-9]+)(\.[0-9]+)?([[:space:]]*)([A-Za-z]+).*/\1/'; } + norm_unit() { sed -E 's/^([0-9]+)(\.[0-9]+)?([[:space:]]*)([A-Za-z]+).*/\4/'; } + + traffic_rx_value="$(printf '%s' "$rx_raw" | norm_val)" + traffic_rx_unit="$( printf '%s' "$rx_raw" | norm_unit)" + traffic_tx_value="$(printf '%s' "$tx_raw" | norm_val)" + traffic_tx_unit="$( printf '%s' "$tx_raw" | norm_unit)" + + # Handle "Not enough" (no data yet) + if [[ "$rx_raw$tx_raw" == *"Not enough"* ]]; then + traffic_rx_value="n/a"; traffic_rx_unit="" + traffic_tx_value="n/a"; traffic_tx_unit="" + fi + + case "$PRIMARY_DIRECTION" in + tx) + display " TX today" "$traffic_tx_value" 500 0 " ${traffic_tx_unit}" "" ;; + rx) + display " RX today" "$traffic_rx_value" 500 0 " ${traffic_rx_unit}" "" ;; + both) + display " TX today" "$traffic_tx_value" 500 0 " ${traffic_tx_unit}" "" + display " RX today" "$traffic_rx_value" 500 0 " ${traffic_rx_unit}" "" ;; + *) : ;; + esac + echo "" # force newline after vnStat output + fi fi -if [[ $(command -v zpool) ]]; then - zpoolstatus="$(zpool status &1 )" - if [[ -n $(echo $zpoolstatus | grep 'not loaded') ]]; then - : - elif [[ -n $(echo $zpoolstatus | grep 'degraded\|OFFLINE') ]]; then +# ZFS pool summary +if command -v zpool >/dev/null 2>&1; then + zpoolstatus="$(zpool status 2>&1 || true)" + if grep -q 'not loaded' <<<"$zpoolstatus"; then + : # no line + elif grep -Eq 'degraded|OFFLINE' <<<"$zpoolstatus"; then printf " ZFS pool: " echo -ne "\e[0;91mDegraded\x1B[0m" - line=$((line+1)) - elif [[ -n $(echo $zpoolstatus | grep 'no pools available') ]]; then + echo "" + elif grep -q 'no pools available' <<<"$zpoolstatus"; then printf " ZFS pool: " echo -ne "n/a" - line=$((line+1)) + echo "" else printf " ZFS pool: " echo -ne "\e[0;92mOnline\x1B[0m" - line=$((line+1)) + echo "" fi fi -echo "" + +exit 0 diff --git a/packages/bsp/common/etc/update-motd.d/35-armbian-tips b/packages/bsp/common/etc/update-motd.d/35-armbian-tips index c1b6067ab..643b65d15 100755 --- a/packages/bsp/common/etc/update-motd.d/35-armbian-tips +++ b/packages/bsp/common/etc/update-motd.d/35-armbian-tips @@ -1,32 +1,82 @@ #!/bin/bash # -# Copyright (c) Authors: https://www.armbian.com/authors +# Armbian MOTD: Tips (compact + robust) # -# This file is licensed under the terms of the GNU General Public -# License version 2. This program is licensed "as is" without any -# warranty of any kind, whether express or implied. - -# DO NOT EDIT THIS FILE but add config options to /etc/default/armbian-motd -# any changes will be lost on board support package update THIS_SCRIPT="tips" MOTD_DISABLE="" -[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd +safe_source() { [[ -f "$1" ]] && . "$1"; } -for f in $MOTD_DISABLE; do - [[ $f == $THIS_SCRIPT ]] && exit 0 +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 done +# --- helpers --- +_has_prev_output() { + [[ -e /run/armbian-motd/.after_header.printed ]] \ + || [[ -e "${XDG_RUNTIME_DIR:-/tmp}/armbian-motd/.after_header.printed" ]] +} + +# extract field from a tiny JSON object; prefer jq, fallback to sed +_json_get() { + local key="$1" json="$2" + if command -v jq >/dev/null 2>&1; then + jq -r --arg k "$key" '.[$k] // empty' <<<"$json" 2>/dev/null + else + printf '%s\n' "$json" | sed -n -E "s/.*\"$key\":\"([^\"]*)\".*/\1/p" + fi +} + +# --- collect content --- + +lines=() + +# 1) Optional quote: /etc/update-motd.d/quotes.txt lines like: YYYY-MM-DD|Some text... quotes="/etc/update-motd.d/quotes.txt" -if [[ -f $quotes && $(( $RANDOM % 1 )) == 0 ]]; then - random_line=$(shuf -i 1-$(wc -l < $quotes) -n 1) - quote=$(sed -n -e "$random_line"p $quotes) - DUE_DATE=$(echo $quote | cut -d"|" -f1) - SELECTED_QUOTE=$(echo $quote | cut -d"|" -f2) - if [[ -n $SELECTED_QUOTE && $(date +'%Y-%m-%d') < $(date -d $DUE_DATE +"%Y-%m-%d") ]]; then - printf "\e[0;90m Tips:\x1B[0m\n " #; printf '%.s─' $(seq 1 5); echo -e " \x1B[0m" - echo -e "\n$SELECTED_QUOTE" | fold -w 79 -s | sed 's/^/ /' - echo "" - fi +if [[ -f "$quotes" ]]; then + total=$(wc -l < "$quotes") + if [[ "$total" -gt 0 ]]; then + rline=$(( RANDOM % total + 1 )) + raw=$(sed -n "${rline}p" "$quotes") + due="${raw%%|*}" + qtext="${raw#*|}" + # show only if not expired or due is empty + today=$(date +%Y-%m-%d) + if [[ -z "$due" || "$today" < "$(date -d "$due" +%Y-%m-%d 2>/dev/null || echo 9999-12-31)" ]]; then + [[ -n "$qtext" ]] && lines+=("$qtext") + fi + fi fi + +# 2) One non-expired recommend_message (if defined) +if [[ "$(declare -p recommend_messages 2>/dev/null)" == "declare -a"* ]]; then + today=$(date +%Y-%m-%d) + valid=() + for item in "${recommend_messages[@]}"; do + exp=$(_json_get expiration "$item") + [[ -z "$exp" || "$today" < "$exp" ]] && valid+=("$item") + done + if ((${#valid[@]})); then + pick=${valid[$RANDOM % ${#valid[@]}]} + msg=$(_json_get message "$pick") + url=$(_json_get url "$pick") + [[ -n "$msg" ]] && lines+=("$msg") + [[ -n "$url" ]] && lines+=("$url") + fi +fi + +# --- print (only if we actually have something to say) --- + +if ((${#lines[@]})); then + # One blank line ONLY if something printed earlier + _has_prev_output && echo "" + + printf "\e[0;90m Tips:\x1B[0m\n\n" + for l in "${lines[@]}"; do + printf "%s\n" " $l" + done +fi + +exit 0 diff --git a/packages/bsp/common/etc/update-motd.d/41-commands b/packages/bsp/common/etc/update-motd.d/41-commands index 70db18667..86e17bfa6 100755 --- a/packages/bsp/common/etc/update-motd.d/41-commands +++ b/packages/bsp/common/etc/update-motd.d/41-commands @@ -12,15 +12,24 @@ THIS_SCRIPT="commands" MOTD_DISABLE="" -[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd +safe_source() { [[ -f "$1" ]] && . "$1"; } + +# Optional overrides +safe_source /etc/default/armbian-motd +for f in ${MOTD_DISABLE}; do + [[ "${f}" == "${THIS_SCRIPT}" ]] && exit 0 +done + +_motd_spacer() { + local tag="${1:-after-header}" + local dir="/run/armbian-motd"; local stamp="$dir/.${tag}.printed" + mkdir -p "$dir" 2>/dev/null + [[ -e "$stamp" ]] || { echo ""; : > "$stamp"; } +} # read upgrade count to show upgrade command [[ -f /var/cache/apt/archives/updates.number ]] && . /var/cache/apt/archives/updates.number -for f in $MOTD_DISABLE; do - [[ $f == $THIS_SCRIPT ]] && exit 0 -done - # text, sudo / without, command, condition # condition can be fairly complex list=( @@ -52,6 +61,7 @@ done # show list for existing command only if [[ "${cmd_count}" -gt 0 ]]; then + echo "" # ensure we start on a fresh line printf "\e[0;90m Commands: \x1B[0m\n" #; printf '%.s─' $(seq 1 39); echo -e "\x1B[0m" echo "" for l in "${output[@]}" @@ -61,7 +71,7 @@ if [[ "${cmd_count}" -gt 0 ]]; then command=$(echo $l | cut -d"," -f3) printf " \e[1;33m%-${name_len}s\e[0m %-0s: $sudo$command\n" "$name" done - echo -e "\033[0m" + echo -en "\033[0m" fi exit 0 diff --git a/packages/bsp/common/etc/update-motd.d/99-blank b/packages/bsp/common/etc/update-motd.d/99-blank new file mode 100755 index 000000000..e94a68c02 --- /dev/null +++ b/packages/bsp/common/etc/update-motd.d/99-blank @@ -0,0 +1,3 @@ +#!/bin/bash +echo "" +exit 0 diff --git a/packages/bsp/common/usr/bin/armbian-install b/packages/bsp/common/usr/bin/armbian-install index b3b94336a..b197fcd5f 100755 --- a/packages/bsp/common/usr/bin/armbian-install +++ b/packages/bsp/common/usr/bin/armbian-install @@ -181,7 +181,7 @@ create_armbian() # count files is needed for progress bar dialog --title " $title " --backtitle "$backtitle" --infobox "\n Counting files ... few seconds." 5 60 - TODO=$(rsync -avx --delete --stats --exclude-from=$EX_LIST / "${TempDir}"/rootfs | grep "Number of files:"|awk '{print $4}' | tr -d '.,') + TODO=$(rsync -anvx --delete --stats --exclude-from=$EX_LIST / "${TempDir}"/rootfs | grep "Number of files:"|awk '{print $4}' | tr -d '.,') echo -e "\nCopying ${TODO} files to $2. \c" >> $logfile # creating rootfs @@ -194,15 +194,21 @@ create_armbian() echo 0 >"${nsi_conn_progress}" echo no >"${nsi_conn_done}" - # Launch rsync in background - { \ - rsync -avx --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs | \ - nl | awk '{ printf "%.0f\n", 100*$1/"'"$TODO"'" }' \ - > "${nsi_conn_progress}" ; - # create empty persistent journal directory if it exists before install - [ -d /var/log.hdd/journal ] && mkdir "${TempDir}"/rootfs/var/log/journal - # save exit code from rsync - echo ${PIPESTATUS[0]} >"${nsi_conn_done}" + # Launch rsync in background and stream progress percentages + { + rsync -avx --delete --exclude-from="$EX_LIST" / "${TempDir}/rootfs" \ + | stdbuf -oL awk -v todo="${TODO:-1}" '{ + pct = int((100 * NR) / (todo == 0 ? 1 : todo)); + if (pct > 100) pct = 100; + print pct; + fflush(); # ensure the progress file gets new lines promptly + }' > "${nsi_conn_progress}" + + # create empty persistent journal dir if it existed before install + [ -d /var/log.hdd/journal ] && mkdir -p "${TempDir}/rootfs/var/log/journal" + + # save rsync exit code (first cmd in the pipe) + echo ${PIPESTATUS[0]} > "${nsi_conn_done}" } & # while variables @@ -241,7 +247,7 @@ create_armbian() This will take approximately $(( $((USAGE/300)) * 1 )) minutes to finish. Please wait!\n\n" 11 80 # run rsync again to silently catch outstanding changes between / and "${TempDir}"/rootfs/ - dialog --title "$title" --backtitle "$backtitle" --infobox "\n Cleaning up ... Almost done." 5 60 + dialog --title "$title" --backtitle "$backtitle" --infobox "\n Finalizing file sync ... Please wait." 5 60 rsync -avx --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs >/dev/null 2>&1 # mark OS as transferred @@ -465,6 +471,8 @@ create_armbian() if [[ $1 == *mtd* ]]; then if [[ -f "${TempDir}"/rootfs/boot/armbianEnv.txt ]]; then sed -e 's,rootdev=.*,rootdev='"$satauuid"',g' -i "${TempDir}"/rootfs/boot/armbianEnv.txt + sed -e 's,rootfstype=.*,rootfstype='$FilesystemChoosen',g' -i "${TempDir}"/rootfs/boot/armbianEnv.txt + grep -qE '^rootfstype=' "${TempDir}/rootfs/boot/armbianEnv.txt" || echo "rootfstype=$FilesystemChoosen" >> "${TempDir}/rootfs/boot/armbianEnv.txt" fi if [[ -f "${TempDir}"/rootfs/boot/extlinux/extlinux.conf ]]; then sed -e 's,root='"$root_uuid"',root='"$satauuid"',g' -i "${TempDir}"/rootfs/boot/extlinux/extlinux.conf @@ -668,6 +676,26 @@ format_disk() [[ $? -ne 0 ]] && exit 10 FilesystemChoosen=${FilesystemOptions[(2*$FilesystemChoices)-1]} + if [[ $FilesystemChoosen == *btrfs* ]] && ! command -v mkfs.btrfs; then + dialog --yes-label "Install" --no-label 'Deny' --title "$title" --backtitle "$backtitle" --yesno "\nThe btrfs-progs package is not installed.\n\nIt is required to format the root partition as btrfs. Install it now?" 10 75 + if [[ $? -eq 0 ]]; then + dialog --title "$title" --backtitle "$backtitle" --infobox "\nInstalling btrfs-progs ... please wait." 5 60 + DEBIAN_FRONTEND=noninteractive apt-get update -o 'Dpkg::Use-pTy=0' >> $logfile 2>&1 &&\ + DEBIAN_FRONTEND=noninteractive apt-get install -y -o 'Dpkg::Use-pTy=0' btrfs-progs >> $logfile 2>&1 + if [[ ! $? -eq 0 ]]; then + dialog --title "$title" --backtitle "$backtitle" --colors --infobox\ + "\nFailed to install btrfs-progs\n\nThe log file has been written to $logfile" 5 60 + exit 15 + fi + fi + + if ! command -v mkfs.btrfs; then + dialog --title "$title" --backtitle "$backtitle" --colors\ + --infobox "\nmkfs.btrfs not found, cannot proceed" 5 60 + exit 12 + fi + fi + dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1 to $FilesystemChoosen ... please wait." 5 60 mkfs.${FilesystemChoosen} ${mkopts[$FilesystemChoosen]} "$1" >> $logfile 2>&1 } diff --git a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin index 262331085..1613cc462 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin +++ b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin @@ -51,8 +51,6 @@ createYAML() { local YAML="network:\n" YAML+=" $DEVTYPE:\n" YAML+=" $DEVICE_NAME:\n" - if [[ "${PRESET_NET_USE_STATIC}" == 0 ]]; then YAML+=" dhcp4: yes\n";fi - if [[ "${PRESET_NET_USE_STATIC}" == 0 ]]; then YAML+=" dhcp6: yes\n";fi if [[ "${PRESET_NET_USE_STATIC}" == 1 ]]; then YAML+=" addresses:\n" YAML+=" - $PRESET_NET_STATIC_IP/$PRESET_NET_STATIC_MASK\n" @@ -61,6 +59,9 @@ createYAML() { if [[ -n "${PRESET_NET_STATIC_GATEWAY}" ]]; then YAML+=" via: ${PRESET_NET_STATIC_GATEWAY}\n";fi if [[ -n "${PRESET_NET_STATIC_DNS}" ]]; then YAML+=" nameservers:\n"; fi if [[ -n "${PRESET_NET_STATIC_DNS}" ]]; then YAML+=" addresses: [$PRESET_NET_STATIC_DNS]\n"; fi + else + YAML+=" dhcp4: yes\n" + YAML+=" dhcp6: yes\n" fi if [[ "${PRESET_NET_WIFI_ENABLED}" == 1 ]]; then if [[ -n "${PRESET_NET_WIFI_COUNTRYCODE}" ]]; then YAML+=" regulatory-domain: $PRESET_NET_WIFI_COUNTRYCODE\n"; fi @@ -599,7 +600,16 @@ add_user() { else passwd -d "$RealUserName" > /dev/null 2>&1 fi - for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh render; do + + # Pre-create docker group to ensure user membership is set up before Docker installation. + # (docker-ce package creates this group automatically during postinst, but we create it early + # to guarantee group membership is ready immediately after user creation.) + if ! getent group docker >/dev/null; then + if ! addgroup --system docker 2>/dev/null; then + echo "Warning: Failed to create docker group" >&2 + fi + fi + for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh render docker; do usermod -aG "${additionalgroup}" "${RealUserName}" 2> /dev/null done @@ -803,12 +813,11 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then fi else - echo -e "\e[0;31m\nWARNING!\x1B[0m\n\nYou are using an \e[0;31mautomated build\x1B[0m meant only for developers to provide" - echo -e "constructive feedback to improve build system, OS settings or UX.\n" - - echo -e "If this does not apply to you, \e[0;31mSTOP NOW!\x1B[0m Especially don't use this " - echo -e "image for production since things might not work as expected or at " - echo -e "all. They may break anytime with next update." + echo -e "\e[0;31m\nDeveloper Preview Build\x1B[0m\n" + echo -e "This Armbian image was generated automatically for development and testing purpose." + echo -e "It may include unfinished features or unstable components.\n" + echo -e "If you are not here to report issues or just test it, \e[0;31mplease do not use this image in production.\x1B[0m" + echo -e "Expect things to change — or even break — as improvements are made." fi @@ -954,12 +963,15 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then # create default sddm config mkdir -p /etc/sddm.conf.d - cat <<- EOF > /etc/sddm.conf.d/armbian.conf - [Theme] - Current=breeze - [General] - InputMethod=none - EOF + + if [ ! -e "/etc/sddm.conf.d/armbian.conf" ]; then + cat <<- EOF > /etc/sddm.conf.d/armbian.conf + [Theme] + Current=breeze + [General] + InputMethod=none + EOF + fi # 1st run goes without login cat <<- EOF > /etc/sddm.conf.d/autologin.conf @@ -980,6 +992,7 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then else # no display manager detected -> clear screen and show motd clear + run-parts --lsbsysinit /etc/cron.daily run-parts --lsbsysinit /etc/update-motd.d # Display reboot recommendation if necessary diff --git a/packages/bsp/common/usr/lib/armbian/armbian-ramlog b/packages/bsp/common/usr/lib/armbian/armbian-ramlog index d7d8f5f63..794c90882 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-ramlog +++ b/packages/bsp/common/usr/lib/armbian/armbian-ramlog @@ -9,6 +9,7 @@ SIZE=50M USE_RSYNC=true ENABLED=false +HDD_LOG=/var/log.hdd [ -f /etc/default/armbian-ramlog ] && . /etc/default/armbian-ramlog @@ -16,7 +17,6 @@ ENABLED=false # Never touch anything below here. Only edit /etc/default/armbian-ramlog -HDD_LOG=/var/log.hdd RAM_LOG=/var/log LOG2RAM_LOG="${HDD_LOG}/armbian-ramlog.log" LOG_OUTPUT="tee -a $LOG2RAM_LOG" @@ -111,9 +111,11 @@ check_if_installed () { case "$1" in start) [ -d $HDD_LOG ] || mkdir -p $HDD_LOG - mount --bind $RAM_LOG $HDD_LOG - mount --make-private $HDD_LOG - + if [ "$HDD_LOG" == "/var/log.hdd" ]; then + mount --bind $RAM_LOG $HDD_LOG + mount --make-private $HDD_LOG + fi + # Check whether zram device is available or we need to use tmpfs LOG_TYPE="tmpfs" for rd in /dev/zram*; do @@ -139,17 +141,20 @@ case "$1" in stop) syncToDisk umount -l $RAM_LOG - umount -l $HDD_LOG + if [ "$HDD_LOG" == "/var/log.hdd" ]; then + umount -l $HDD_LOG + fi ;; write) syncToDisk ;; postrotate) - cd /var/log.hdd/ + cd $HDD_LOG find . -type f -print | grep -E -v "(\.gz|\.xz|\.[0-9]|armbian-ramlog)|\.journal" | while IFS= read -r file do - dest="/var/log/$file" - cat $file > $dest + dest="/var/log/$file" + cat $file > $dest + touch -r $file $dest done ;; *) diff --git a/packages/bsp/common/usr/lib/armbian/armbian-resize-filesystem b/packages/bsp/common/usr/lib/armbian/armbian-resize-filesystem index 88b2ca12b..eb490c41d 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-resize-filesystem +++ b/packages/bsp/common/usr/lib/armbian/armbian-resize-filesystem @@ -17,13 +17,13 @@ do_expand_partition() echo -e "\n### [resize2fs] Trying to resize partition $partdev:\n" # make sure the target is a partition - local parttype=$(lsblk -n -o TYPE $partdev | head -1) + local parttype=$(lsblk -n -d -o TYPE $partdev) if [[ "$parttype" != "part" ]]; then echo -e "\n$partdev isn't a partition: $parttype" >&2 return 1 fi - local diskdevname=$(lsblk -n -o PKNAME $partdev | head -1) # i.e. mmcblk0 or sda + local diskdevname=$(lsblk -n -d -o PKNAME $partdev) # i.e. mmcblk0 or sda # due to the bug in util-linux 2.34 which fails to show device, let's use this failover: [[ -z $diskdevname ]] && diskdevname=$(echo $partdev | sed -e "s/^\/dev\///" | sed "s/p.*//") local diskdev="/dev/$diskdevname" # i.e. /dev/mmcblk0, /dev/sda @@ -166,7 +166,7 @@ do_expand_partition() touch /var/run/resize2fs-reboot fi - local partsize=$(lsblk -n -b -o SIZE $partdev | head -1) + local partsize=$(lsblk -n -d -b -o SIZE $partdev) local actualsize=$(( $sectorsize * ($lastsector - $partstart + 1) )) if [[ $actualsize -ne $partsize ]]; then echo -e "\n### [resize2fs] Automated reboot needed to finish the resize procedure" @@ -183,15 +183,20 @@ do_resize_crypt() { local dev=$1 local parentdev=$2 - local name=$(lsblk -n -o NAME $dev | head -1) # i.e. armbian-root + local name=$(lsblk -n -d -o NAME $dev) # i.e. armbian-root echo -e "\n### [resize2fs] Start resizing LUKS container now\n" # It's probably no need to run 'cryptsetup resize'. # After reboot, it will auto resize to adapte the partition # 'cryptsetup resize' requires passphrase, so it will fail. - cryptsetup resize $name + # if /etc/rootfs.key is present - it can be done unattended + if [ -f /etc/rootfs.key ]; then + cryptsetup resize --key-file /etc/rootfs.key "$name" + else + cryptsetup resize "$name" + fi - local parentsize=$(lsblk -n -b -o SIZE $parentdev | head -1) + local parentsize=$(lsblk -n -d -b -o SIZE $parentdev) local sectorsize=$(cryptsetup status $name | awk -F':' '/^ *sector size/ {print $2}' | tr -c -d '[:digit:]') local offset=$(cryptsetup status $name | awk -F':' '/^ *offset/ {print $2}' | tr -c -d '[:digit:]') @@ -238,7 +243,7 @@ do_expand_filesystem() esac # check whether reboot is necessary for resize2fs to take effect - local devsize=$(lsblk -n -b -o SIZE $partdev | head -1) + local devsize=$(lsblk -n -d -b -o SIZE $partdev) local fssize=$(findmnt -n -b -o SIZE --target $mountpoint) if [[ $(( 100 * $fssize / $devsize )) -lt 90 ]]; then echo -e "\n### [resize2fs] Automated reboot needed to finish the resize procedure" @@ -267,8 +272,8 @@ main() # check for crypt local cryptname="" - if [[ "$(lsblk -n -o TYPE $rootdev | head -1)" == "crypt" ]]; then - local cryptname=$(lsblk -n -o NAME $rootdev | head -1) # i.e. armbian-root + if [[ "$(lsblk -n -d -o TYPE $rootdev)" == "crypt" ]]; then + local cryptname=$(lsblk -n -d -o NAME $rootdev) # i.e. armbian-root local parent_uuid=$(cat /etc/crypttab | awk "{if(\$1 == \"$cryptname\"){print \$2}}" | sed 's/UUID=//') local parentdev=$(blkid -U $parent_uuid) # i.e. /dev/mmcblk0p1 or /dev/sda1 diff --git a/packages/bsp/helios64/fancontrol.service.privatedevices-override b/packages/bsp/helios64/fancontrol.service.privatedevices-override new file mode 100644 index 000000000..8b0aa68aa --- /dev/null +++ b/packages/bsp/helios64/fancontrol.service.privatedevices-override @@ -0,0 +1,2 @@ +[Service] +PrivateDevices=no diff --git a/packages/bsp/rk3318/rk3318-config b/packages/bsp/rk3318/rk3318-config index cdf8a01f4..57d77694d 100755 --- a/packages/bsp/rk3318/rk3318-config +++ b/packages/bsp/rk3318/rk3318-config @@ -75,8 +75,10 @@ DT_LED_OVERLAYS+=(["rk3318-box-led-conf4"]="Generic + wifi on sdmmc-ext") DT_LED_OVERLAYS+=(["rk3318-box-led-conf2"]="X88_PRO_B boards") DT_LED_OVERLAYS+=(["rk3318-box-led-conf3"]="MXQ-RK3328-D4 boards (w/ RK805)") DT_LED_OVERLAYS+=(["rk3318-box-led-conf5"]="YX_RK3318 boards") +DT_LED_OVERLAYS+=(["rk3318-box-led-conf6"]="T98_RK3318 boards") +DT_LED_OVERLAYS+=(["rk3318-box-led-conf7"]="T9_RK3318 boards") -DT_LED_OVERLAYS_ORDER=("rk3318-box-led-conf1" "rk3318-box-led-conf4" "rk3318-box-led-conf2" "rk3318-box-led-conf3" "rk3318-box-led-conf5") +DT_LED_OVERLAYS_ORDER=("rk3318-box-led-conf1" "rk3318-box-led-conf4" "rk3318-box-led-conf2" "rk3318-box-led-conf3" "rk3318-box-led-conf5" "rk3318-box-led-conf6" "rk3318-box-led-conf7") DT_CPU_OVERLAYS+=(["rk3318-box-cpu-hs"]="RK3318 or RK3328") diff --git a/patch/atf/atf-imx8/0001-fix-needed-by-armbian-build-system.patch b/patch/atf/atf-imx8/0001-fix-needed-by-armbian-build-system.patch index 9d1f16f1c..bd0c6d6d5 100644 --- a/patch/atf/atf-imx8/0001-fix-needed-by-armbian-build-system.patch +++ b/patch/atf/atf-imx8/0001-fix-needed-by-armbian-build-system.patch @@ -1,4 +1,4 @@ -From 230e25fbcd0a36dfaaa8f3b9f0ad7d9cd0500736 Mon Sep 17 00:00:00 2001 +From 5b8d60b91f18b31343ee26f25d1ec7c70ce9187e Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Wed, 28 May 2025 14:02:39 +0200 Subject: [PATCH] fix needed by armbian build system @@ -11,7 +11,7 @@ Signed-off-by: Martin Schmiedel 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile -index ea5701347..7a4ff1244 100644 +index ea5701347..5213a1199 100644 --- a/Makefile +++ b/Makefile @@ -343,6 +343,10 @@ GCC_V_OUTPUT := $(shell $(CC) -v 2>&1) @@ -19,7 +19,7 @@ index ea5701347..7a4ff1244 100644 TF_LDFLAGS += -z noexecstack +# remove possibly contained gcc linker flags we use the linker directly -+gcc_linker_flags = -Wl,--no-warn-rwx-segment ++gcc_linker_flags = -Wl,--no-warn-rwx-segments -Wl,--no-warn-rwx-segment +TF_LDFLAGS := $(filter-out $(gcc_linker_flags), $(TF_LDFLAGS)) + # LD = armlink diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0001-v6-coverletter-net-next-rework-IRQ-handling-in-mtk_e.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0001-v6-coverletter-net-next-rework-IRQ-handling-in-mtk_e.patch new file mode 100644 index 000000000..e69de29bb diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0002-net-ethernet-mtk_eth_soc-support-named-IRQs.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0002-net-ethernet-mtk_eth_soc-support-named-IRQs.patch new file mode 100644 index 000000000..542dc4ee7 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0002-net-ethernet-mtk_eth_soc-support-named-IRQs.patch @@ -0,0 +1,99 @@ +From ad319b24f3eae33c753c406611d49032333b25da Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 13 Jun 2025 16:06:37 +0200 +Subject: [PATCH 02/84] net: ethernet: mtk_eth_soc: support named IRQs + +Add named interrupts and keep index based fallback for existing +devicetrees. + +Currently only rx and tx IRQs are defined to be used with mt7988, but +later extended with RSS/LRO support. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Simon Horman +--- +v6: +- change irq names from tx/rx to fe1/fe2 because reserved irqs + are usable and not bound to specific function +- dropped Simons RB because of this +v5: +- fix typo in description +- add comments from previous patch #3 with changes suggested by simon + +v2: +- move irqs loading part into own helper function +- reduce indentation +- place mtk_get_irqs helper before the irq_handler (note for simon) + +net: mtk_eth_soc: change irq name back to fe1 + fe2 +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 46 ++++++++++++++++----- + 1 file changed, 35 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 880f27ca84d4..1de594a93146 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3344,6 +3344,37 @@ static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) + schedule_work(ð->pending_work); + } + ++static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) ++{ ++ int i; ++ ++ /* future SoCs beginning with MT7988 should use named IRQs in dts */ ++ eth->irq[1] = platform_get_irq_byname(pdev, "fe1"); ++ eth->irq[2] = platform_get_irq_byname(pdev, "fe2"); ++ if (eth->irq[1] >= 0 && eth->irq[2] >= 0) ++ return 0; ++ ++ /* legacy way: ++ * On MTK_SHARED_INT SoCs (MT7621 + MT7628) the first IRQ is taken ++ * from devicetree and used for both RX and TX - it is shared. ++ * On SoCs with non-shared IRQs the first entry is not used, ++ * the second is for TX, and the third is for RX. ++ */ ++ for (i = 0; i < 3; i++) { ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0) ++ eth->irq[i] = eth->irq[0]; ++ else ++ eth->irq[i] = platform_get_irq(pdev, i); ++ ++ if (eth->irq[i] < 0) { ++ dev_err(&pdev->dev, "no IRQ%d resource found\n", i); ++ return -ENXIO; ++ } ++ } ++ ++ return 0; ++} ++ + static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) + { + struct mtk_eth *eth = _eth; +@@ -5113,17 +5144,10 @@ static int mtk_probe(struct platform_device *pdev) + } + } + +- for (i = 0; i < 3; i++) { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0) +- eth->irq[i] = eth->irq[0]; +- else +- eth->irq[i] = platform_get_irq(pdev, i); +- if (eth->irq[i] < 0) { +- dev_err(&pdev->dev, "no IRQ%d resource found\n", i); +- err = -ENXIO; +- goto err_wed_exit; +- } +- } ++ err = mtk_get_irqs(pdev, eth); ++ if (err) ++ goto err_wed_exit; ++ + for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { + eth->clks[i] = devm_clk_get(eth->dev, + mtk_clks_source_name[i]); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0003-net-ethernet-mtk_eth_soc-add-consts-for-irq-index.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0003-net-ethernet-mtk_eth_soc-add-consts-for-irq-index.patch new file mode 100644 index 000000000..96ca3c59a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0003-net-ethernet-mtk_eth_soc-add-consts-for-irq-index.patch @@ -0,0 +1,129 @@ +From d32c956e9f42925aa91839d127ee2f2c04bf6f7f Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 15 Jun 2025 12:10:44 +0200 +Subject: [PATCH 03/84] net: ethernet: mtk_eth_soc: add consts for irq index + +Use consts instead of fixed integers for accessing IRQ array. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Simon Horman +Reviewed-by: Daniel Golle +--- +v5: +- rename consts to be compatible with upcoming RSS/LRO changes + MTK_ETH_IRQ_SHARED => MTK_FE_IRQ_SHARED + MTK_ETH_IRQ_TX => MTK_FE_IRQ_TX + MTK_ETH_IRQ_RX => MTK_FE_IRQ_RX + MTK_ETH_IRQ_MAX => MTK_FE_IRQ_NUM +v4: +- calculate max from last (rx) irq index and use it for array size too +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++----------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 ++++++- + 2 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 1de594a93146..2b9c24bbe7c3 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3349,9 +3349,9 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + int i; + + /* future SoCs beginning with MT7988 should use named IRQs in dts */ +- eth->irq[1] = platform_get_irq_byname(pdev, "fe1"); +- eth->irq[2] = platform_get_irq_byname(pdev, "fe2"); +- if (eth->irq[1] >= 0 && eth->irq[2] >= 0) ++ eth->irq[MTK_FE_IRQ_TX] = platform_get_irq_byname(pdev, "fe1"); ++ eth->irq[MTK_FE_IRQ_RX] = platform_get_irq_byname(pdev, "fe2"); ++ if (eth->irq[MTK_FE_IRQ_TX] >= 0 && eth->irq[MTK_FE_IRQ_RX] >= 0) + return 0; + + /* legacy way: +@@ -3360,9 +3360,9 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + * On SoCs with non-shared IRQs the first entry is not used, + * the second is for TX, and the third is for RX. + */ +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < MTK_FE_IRQ_NUM; i++) { + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0) +- eth->irq[i] = eth->irq[0]; ++ eth->irq[i] = eth->irq[MTK_FE_IRQ_SHARED]; + else + eth->irq[i] = platform_get_irq(pdev, i); + +@@ -3428,7 +3428,7 @@ static void mtk_poll_controller(struct net_device *dev) + + mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); + mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask); +- mtk_handle_irq_rx(eth->irq[2], dev); ++ mtk_handle_irq_rx(eth->irq[MTK_FE_IRQ_RX], dev); + mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); + mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask); + } +@@ -4914,7 +4914,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + eth->netdev[id]->features |= eth->soc->hw_features; + eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; + +- eth->netdev[id]->irq = eth->irq[0]; ++ eth->netdev[id]->irq = eth->irq[MTK_FE_IRQ_SHARED]; + eth->netdev[id]->dev.of_node = np; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) +@@ -5191,17 +5191,17 @@ static int mtk_probe(struct platform_device *pdev) + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { +- err = devm_request_irq(eth->dev, eth->irq[0], ++ err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_SHARED], + mtk_handle_irq, 0, + dev_name(eth->dev), eth); + } else { +- err = devm_request_irq(eth->dev, eth->irq[1], ++ err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_TX], + mtk_handle_irq_tx, 0, + dev_name(eth->dev), eth); + if (err) + goto err_free_dev; + +- err = devm_request_irq(eth->dev, eth->irq[2], ++ err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_RX], + mtk_handle_irq_rx, 0, + dev_name(eth->dev), eth); + } +@@ -5247,7 +5247,7 @@ static int mtk_probe(struct platform_device *pdev) + } else + netif_info(eth, probe, eth->netdev[i], + "mediatek frame engine at 0x%08lx, irq %d\n", +- eth->netdev[i]->base_addr, eth->irq[0]); ++ eth->netdev[i]->base_addr, eth->irq[MTK_FE_IRQ_SHARED]); + } + + /* we run 2 devices on the same DMA ring so we need a dummy device +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 6f72a8c8ae1e..8cdf1317dff5 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -642,6 +642,11 @@ + + #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + ++#define MTK_FE_IRQ_SHARED 0 ++#define MTK_FE_IRQ_TX 1 ++#define MTK_FE_IRQ_RX 2 ++#define MTK_FE_IRQ_NUM (MTK_FE_IRQ_RX + 1) ++ + struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; +@@ -1292,7 +1297,7 @@ struct mtk_eth { + struct net_device *dummy_dev; + struct net_device *netdev[MTK_MAX_DEVS]; + struct mtk_mac *mac[MTK_MAX_DEVS]; +- int irq[3]; ++ int irq[MTK_FE_IRQ_NUM]; + u32 msg_enable; + unsigned long sysclk; + struct regmap *ethsys; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0004-net-ethernet-mtk_eth_soc-skip-first-IRQ-if-not-used.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0004-net-ethernet-mtk_eth_soc-skip-first-IRQ-if-not-used.patch new file mode 100644 index 000000000..99f2431f0 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0004-net-ethernet-mtk_eth_soc-skip-first-IRQ-if-not-used.patch @@ -0,0 +1,68 @@ +From 6345b3efe38255c3c0b500c0fbf6b7dcf9055663 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 15 Jun 2025 12:39:14 +0200 +Subject: [PATCH 04/84] net: ethernet: mtk_eth_soc: skip first IRQ if not used + +On SoCs with dedicated RX and TX interrupts (all except MT7621 and +MT7628) platform_get_irq() is called for the first IRQ (eth->irq[0]) +but it is never used. +Skip the first IRQ and reduce the IRQ-count to 2. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Daniel Golle +Reviewed-by: Simon Horman +--- +v6: +- changed commit description a bit +- use MTK_FE_IRQ_SHARED instead of 0 +v5: +- change commit title and description +v4: +- drop >2 condition as max is already 2 and drop the else continue +- update comment to explain which IRQs are taken in legacy way +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 12 ++++++++---- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 2b9c24bbe7c3..0068a983fcd0 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3361,10 +3361,14 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + * the second is for TX, and the third is for RX. + */ + for (i = 0; i < MTK_FE_IRQ_NUM; i++) { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0) +- eth->irq[i] = eth->irq[MTK_FE_IRQ_SHARED]; +- else +- eth->irq[i] = platform_get_irq(pdev, i); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { ++ if (i == MTK_FE_IRQ_SHARED) ++ eth->irq[MTK_FE_IRQ_SHARED] = platform_get_irq(pdev, i); ++ else ++ eth->irq[i] = eth->irq[MTK_FE_IRQ_SHARED]; ++ } else { ++ eth->irq[i] = platform_get_irq(pdev, i + 1); ++ } + + if (eth->irq[i] < 0) { + dev_err(&pdev->dev, "no IRQ%d resource found\n", i); +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 8cdf1317dff5..9261c0e13b59 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -643,8 +643,8 @@ + #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + + #define MTK_FE_IRQ_SHARED 0 +-#define MTK_FE_IRQ_TX 1 +-#define MTK_FE_IRQ_RX 2 ++#define MTK_FE_IRQ_TX 0 ++#define MTK_FE_IRQ_RX 1 + #define MTK_FE_IRQ_NUM (MTK_FE_IRQ_RX + 1) + + struct mtk_rx_dma { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0005-net-ethernet-mtk_eth_soc-only-use-legacy-mode-on-mis.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0005-net-ethernet-mtk_eth_soc-only-use-legacy-mode-on-mis.patch new file mode 100644 index 000000000..b0f5e489d --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0005-net-ethernet-mtk_eth_soc-only-use-legacy-mode-on-mis.patch @@ -0,0 +1,37 @@ +From d9c6fd5ac513e0268cffd88d651d14181724c367 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 18 Jun 2025 19:03:10 +0200 +Subject: [PATCH 05/84] net: ethernet: mtk_eth_soc: only use legacy mode on + missing IRQ name + +If platform_get_irq_byname returns -ENXIO fall back to legacy (index +based) mode, but on other errors function should return this error. + +Suggested-by: Daniel Golle +Signed-off-by: Frank Wunderlich +Reviewed-by: Simon Horman +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 0068a983fcd0..9333f2b8e1d6 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3354,6 +3354,13 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + if (eth->irq[MTK_FE_IRQ_TX] >= 0 && eth->irq[MTK_FE_IRQ_RX] >= 0) + return 0; + ++ /* only use legacy mode if platform_get_irq_byname returned -ENXIO */ ++ if (eth->irq[MTK_FE_IRQ_TX] != -ENXIO) ++ return eth->irq[MTK_FE_IRQ_TX]; ++ ++ if (eth->irq[MTK_FE_IRQ_RX] != -ENXIO) ++ return eth->irq[MTK_FE_IRQ_RX]; ++ + /* legacy way: + * On MTK_SHARED_INT SoCs (MT7621 + MT7628) the first IRQ is taken + * from devicetree and used for both RX and TX - it is shared. +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0006-build.sh-add-build-script-config-defconfig-and-fit-s.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0006-build.sh-add-build-script-config-defconfig-and-fit-s.patch new file mode 100644 index 000000000..8961329bf --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0006-build.sh-add-build-script-config-defconfig-and-fit-s.patch @@ -0,0 +1,2766 @@ +From aff3d69278291f4138605fd0c62ca7b085e6326e Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 7 May 2025 19:23:05 +0200 +Subject: [PATCH 06/84] build.sh: add build script,config,defconfig and fit + source + +--- + arch/arm64/configs/mt7988a_bpi-r4_defconfig | 1310 +++++++++++++++++++ + bpi-r4.its | 112 ++ + build.conf | 27 + + build.sh | 1273 ++++++++++++++++++ + 4 files changed, 2722 insertions(+) + create mode 100644 arch/arm64/configs/mt7988a_bpi-r4_defconfig + create mode 100644 bpi-r4.its + create mode 100644 build.conf + create mode 100755 build.sh + +diff --git a/arch/arm64/configs/mt7988a_bpi-r4_defconfig b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +new file mode 100644 +index 000000000000..69de56a20462 +--- /dev/null ++++ b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +@@ -0,0 +1,1310 @@ ++CONFIG_LOCALVERSION="-bpi-r4" ++CONFIG_LOCALVERSION_AUTO=n ++ ++CONFIG_32BIT=y ++CONFIG_64BIT_TIME=y ++CONFIG_ADVISE_SYSCALLS=y ++CONFIG_AEABI=y ++CONFIG_AF_UNIX_OOB=y ++CONFIG_AIO=y ++CONFIG_ALLOW_DEV_COREDUMP=y ++CONFIG_ANON_INODES=y ++CONFIG_ARCH_BINFMT_ELF_STATE=y ++CONFIG_ARCH_FLATMEM_ENABLE=y ++CONFIG_ARM64_SW_TTBR0_PAN=y ++CONFIG_ARM_CPU_TOPOLOGY=y ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++CONFIG_ARM_GIC_MAX_NR=1 ++CONFIG_ATAGS_PROC=y ++CONFIG_ATA_BMDMA=y ++CONFIG_ATA_SFF=y ++CONFIG_ATM_BR2684_IPFILTER=y ++CONFIG_ATM_CLIP_NO_ICMP=y ++CONFIG_BASE_FULL=y ++CONFIG_BASE_SMALL=n ++CONFIG_BCMA_POSSIBLE=y ++CONFIG_BINARY_PRINTF=y ++CONFIG_BINFMT_ELF=y ++CONFIG_BINFMT_SCRIPT=y ++CONFIG_BITREVERSE=y ++CONFIG_BLK_DEV=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 ++CONFIG_BLOCK=y ++CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 ++CONFIG_BOOT_RAW=y ++CONFIG_BPF=y ++CONFIG_BPF_JIT=y ++CONFIG_BPF_JIT_DEFAULT_ON=y ++CONFIG_BPF_SYSCALL=y ++CONFIG_BPF_UNPRIV_DEFAULT_OFF=y ++CONFIG_BQL=y ++CONFIG_BRANCH_PROFILE_NONE=y ++CONFIG_BRIDGE=y ++CONFIG_BRIDGE_IGMP_SNOOPING=y ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HCIUART_BCSP=y ++CONFIG_BT_HCIUART_H4=y ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BUG=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++CONFIG_BUILDTIME_TABLE_SORT=y ++CONFIG_BUILD_SALT="" ++CONFIG_CACHE_L2X0_PMU=y ++CONFIG_CARDBUS=y ++CONFIG_CC_CAN_LINK=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_CLS_U32_MARK=y ++CONFIG_CMDLINE="" ++CONFIG_COMPACTION=y ++#CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 ++CONFIG_CONSOLE_LOGLEVEL_QUIET=4 ++CONFIG_CONSTRUCTORS=y ++CONFIG_CPU_LITTLE_ENDIAN=y ++CONFIG_CPU_SW_DOMAIN_PAN=y ++CONFIG_CRAMFS_BLOCKDEV=y ++CONFIG_CRC32=y ++CONFIG_CRC32_SARWATE=y ++CONFIG_CROSS_COMPILE="" ++CONFIG_CRYPTO=y ++CONFIG_CRYPTO_ACOMP2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AES=y ++CONFIG_CRYPTO_AKCIPHER=y ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_CCM=y ++CONFIG_CRYPTO_CTR=y ++CONFIG_CRYPTO_GCM=y ++CONFIG_CRYPTO_GF128MUL=y ++CONFIG_CRYPTO_GHASH=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_KPP=y ++CONFIG_CRYPTO_KPP2=y ++CONFIG_CRYPTO_LIB_AES=y ++CONFIG_CRYPTO_LIB_ARC4=y ++CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_NULL=y ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_PCRYPT=y ++CONFIG_CRYPTO_SKCIPHER=y ++CONFIG_CRYPTO_SKCIPHER2=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_FS_ALLOW_ALL=y ++CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y ++CONFIG_DEBUG_KERNEL=y ++CONFIG_DEFAULT_CUBIC=y ++CONFIG_DEFAULT_DEADLINE=y ++CONFIG_DEFAULT_FQ_CODEL=y ++CONFIG_DEFAULT_HOSTNAME="(none)" ++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 ++CONFIG_DEFAULT_INIT="" ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_DEFAULT_NET_SCH="fq_codel" ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_DEVPORT=y ++CONFIG_DMA_COHERENT_POOL=y ++CONFIG_DMA_DECLARE_COHERENT=y ++CONFIG_DMA_NONCOHERENT_MMAP=y ++CONFIG_DOUBLEFAULT=y ++CONFIG_DQL=y ++CONFIG_DUMMY_CONSOLE_COLUMNS=80 ++CONFIG_DUMMY_CONSOLE_ROWS=25 ++CONFIG_DVB_MAX_ADAPTERS=16 ++CONFIG_DYNAMIC_DEBUG_CORE=y ++CONFIG_EFI_PARTITION=y ++CONFIG_ELFCORE=y ++CONFIG_EMBEDDED=y ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_EPOLL=y ++CONFIG_ETHERNET=y ++CONFIG_ETHTOOL_NETLINK=y ++CONFIG_EVENTFD=y ++CONFIG_EXPERT=y ++CONFIG_EXPORTFS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++CONFIG_EXTRA_FIRMWARE="" ++CONFIG_EXTRA_TARGETS="" ++CONFIG_F2FS_FS_XATTR=y ++CONFIG_F2FS_STAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++CONFIG_FB_NOTIFY=y ++CONFIG_FIB_RULES=y ++CONFIG_FILE_LOCKING=y ++CONFIG_FLATMEM=y ++CONFIG_FLATMEM_MANUAL=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_FORTIFY_SOURCE=y ++CONFIG_FRAME_WARN=1024 ++CONFIG_FSNOTIFY=y ++CONFIG_FUTEX=y ++CONFIG_FUTEX_PI=y ++CONFIG_FW_LOADER=y ++CONFIG_FW_LOADER_USER_HELPER=y ++CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++CONFIG_GACT_PROB=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_IRQ_IPI=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PTDUMP=y ++CONFIG_GENERIC_VDSO_TIME_NS=y ++CONFIG_GPIOLIB_FASTPATH_LIMIT=512 ++CONFIG_GPIO_SYSFS=y ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_HARDEN_BRANCH_HISTORY=y ++CONFIG_HARDEN_EL2_VECTORS=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_HPET_MMAP_DEFAULT=y ++CONFIG_HW_PERF_EVENTS=y ++CONFIG_HW_RANDOM_TPM=y ++CONFIG_HZ=100 ++CONFIG_HZ_100=y ++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 ++CONFIG_INET=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_INIT_STACK_NONE=y ++CONFIG_INOTIFY_USER=y ++CONFIG_INPUT_MISC=y ++CONFIG_IO_STRICT_DEVMEM=y ++CONFIG_IO_WQ=y ++CONFIG_IPV6_NDISC_NODETYPE=y ++CONFIG_IPW2100_MONITOR=y ++CONFIG_IPW2200_MONITOR=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_VS_MH_TAB_INDEX=10 ++CONFIG_ISDN=y ++CONFIG_JFFS2_CMODE_PRIORITY=y ++CONFIG_JFFS2_COMPRESSION_OPTIONS=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++CONFIG_JFFS2_FS_XATTR=y ++CONFIG_JFFS2_LZMA=y ++CONFIG_JFFS2_RTIME=y ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_JOLIET=y ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_KASAN_STACK=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_KERNEL_XZ=y ++CONFIG_KERNFS=y ++CONFIG_KUSER_HELPERS=y ++CONFIG_LBDAF=y ++CONFIG_LDISC_AUTOLOAD=y ++CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y ++CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_CLASS_MULTICOLOR=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_NETDEV=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LINEAR_RANGES=y ++CONFIG_LLC=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_LOCKD_V4=y ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 ++CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" ++CONFIG_LSM_MMAP_MIN_ADDR=65536 ++CONFIG_LTO_NONE=y ++CONFIG_LZMA_COMPRESS=y ++CONFIG_LZMA_DECOMPRESS=y ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 ++CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_MEMBARRIER=y ++#CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++CONFIG_MII=y ++CONFIG_MISC_FILESYSTEMS=y ++CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y ++CONFIG_MMC_BLOCK_BOUNCE=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMU=y ++CONFIG_MMU_GATHER_RCU_TABLE_FREE=y ++CONFIG_MMU_GATHER_TABLE_FREE=y ++CONFIG_MODPROBE_PATH="/sbin/modprobe" ++CONFIG_MODULES=y ++CONFIG_MODULE_COMPRESS_NONE=y ++CONFIG_MODULE_STRIPPED=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MSDOS_PARTITION=y ++CONFIG_MTD=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_NOSWAP=y ++CONFIG_MTD_CFI_UTIL=y ++CONFIG_MTD_COMPLEX_MAPPINGS=y ++CONFIG_MTD_GEN_PROBE=y ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 ++CONFIG_MTD_NAND_IDS=y ++CONFIG_MTD_OF_PARTS=y ++CONFIG_MTD_PHYSMAP_OF=y ++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 ++CONFIG_MTD_ROOTFS_ROOT_DEV=y ++CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y ++CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 ++CONFIG_MTD_SPLIT=y ++CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" ++CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y ++CONFIG_MTD_SPLIT_SUPPORT=y ++CONFIG_MULTIUSER=y ++CONFIG_NET=y ++CONFIG_NETDEVICES=y ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NET_CADENCE=y ++CONFIG_NET_CLS=y ++CONFIG_NET_CLS_IND=y ++CONFIG_NET_CORE=y ++CONFIG_NET_EMATCH_STACK=32 ++CONFIG_NET_IPGRE_BROADCAST=y ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_DEFAULT=y ++CONFIG_NET_SCH_FIFO=y ++CONFIG_NET_SCH_FQ_CODEL=y ++CONFIG_NET_SCH_CAKE=m ++CONFIG_NET_SOCK_MSG=y ++CONFIG_NET_VENDOR_3COM=y ++CONFIG_NET_VENDOR_8390=y ++CONFIG_NET_VENDOR_ADAPTEC=y ++CONFIG_NET_VENDOR_AGERE=y ++CONFIG_NET_VENDOR_ALACRITECH=y ++CONFIG_NET_VENDOR_ALTEON=y ++CONFIG_NET_VENDOR_AMAZON=y ++CONFIG_NET_VENDOR_AMD=y ++CONFIG_NET_VENDOR_AQUANTIA=y ++CONFIG_NET_VENDOR_ARC=y ++CONFIG_NET_VENDOR_ATHEROS=y ++CONFIG_NET_VENDOR_AURORA=y ++CONFIG_NET_VENDOR_BROADCOM=y ++CONFIG_NET_VENDOR_BROCADE=y ++CONFIG_NET_VENDOR_CADENCE=y ++CONFIG_NET_VENDOR_CAVIUM=y ++CONFIG_NET_VENDOR_CHELSIO=y ++CONFIG_NET_VENDOR_CIRRUS=y ++CONFIG_NET_VENDOR_CISCO=y ++CONFIG_NET_VENDOR_CORTINA=y ++CONFIG_NET_VENDOR_DEC=y ++CONFIG_NET_VENDOR_DLINK=y ++CONFIG_NET_VENDOR_EMULEX=y ++CONFIG_NET_VENDOR_EXAR=y ++CONFIG_NET_VENDOR_EZCHIP=y ++CONFIG_NET_VENDOR_FARADAY=y ++CONFIG_NET_VENDOR_FREESCALE=y ++CONFIG_NET_VENDOR_FUJITSU=y ++CONFIG_NET_VENDOR_GOOGLE=y ++CONFIG_NET_VENDOR_HISILICON=y ++CONFIG_NET_VENDOR_HP=y ++CONFIG_NET_VENDOR_HUAWEI=y ++CONFIG_NET_VENDOR_I825XX=y ++CONFIG_NET_VENDOR_IBM=y ++CONFIG_NET_VENDOR_INTEL=y ++CONFIG_NET_VENDOR_MARVELL=y ++CONFIG_NET_VENDOR_MELLANOX=y ++CONFIG_NET_VENDOR_MICREL=y ++CONFIG_NET_VENDOR_MICROCHIP=y ++CONFIG_NET_VENDOR_MICROSEMI=y ++CONFIG_NET_VENDOR_MYRI=y ++CONFIG_NET_VENDOR_NATSEMI=y ++CONFIG_NET_VENDOR_NETERION=y ++CONFIG_NET_VENDOR_NETRONOME=y ++CONFIG_NET_VENDOR_NI=y ++CONFIG_NET_VENDOR_NVIDIA=y ++CONFIG_NET_VENDOR_OKI=y ++CONFIG_NET_VENDOR_PACKET_ENGINES=y ++CONFIG_NET_VENDOR_PENSANDO=y ++CONFIG_NET_VENDOR_QLOGIC=y ++CONFIG_NET_VENDOR_QUALCOMM=y ++CONFIG_NET_VENDOR_RDC=y ++CONFIG_NET_VENDOR_REALTEK=y ++CONFIG_NET_VENDOR_RENESAS=y ++CONFIG_NET_VENDOR_ROCKER=y ++CONFIG_NET_VENDOR_SAMSUNG=y ++CONFIG_NET_VENDOR_SEEQ=y ++CONFIG_NET_VENDOR_SILAN=y ++CONFIG_NET_VENDOR_SIS=y ++CONFIG_NET_VENDOR_SMSC=y ++CONFIG_NET_VENDOR_SOCIONEXT=y ++CONFIG_NET_VENDOR_SOLARFLARE=y ++CONFIG_NET_VENDOR_STMICRO=y ++CONFIG_NET_VENDOR_SUN=y ++CONFIG_NET_VENDOR_SYNOPSYS=y ++CONFIG_NET_VENDOR_TEHUTI=y ++CONFIG_NET_VENDOR_TI=y ++CONFIG_NET_VENDOR_TOSHIBA=y ++CONFIG_NET_VENDOR_VIA=y ++CONFIG_NET_VENDOR_WIZNET=y ++CONFIG_NET_VENDOR_XILINX=y ++CONFIG_NET_VENDOR_XIRCOM=y ++CONFIG_NEW_LEDS=y ++CONFIG_NFSD_V3=y ++CONFIG_NFS_COMMON=y ++CONFIG_NFS_V3=y ++CONFIG_NF_CONNTRACK_PROCFS=y ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NLATTR=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_OF_RESERVED_MEM=y ++CONFIG_OPTIMIZE_INLINING=y ++CONFIG_OVERLAY_FS=y ++CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y ++CONFIG_OVERLAY_FS_XINO_AUTO=y ++CONFIG_PACKET=y ++CONFIG_PAGE_SIZE_4KB=y ++CONFIG_PANIC_ON_OOPS=y ++CONFIG_PANIC_ON_OOPS_VALUE=1 ++CONFIG_PANIC_TIMEOUT=10 ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_PCIE_BUS_DEFAULT=y ++CONFIG_PCI_QUIRKS=y ++CONFIG_PCI_SYSCALL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_PINMUX=y ++CONFIG_POSIX_TIMERS=y ++CONFIG_PPC_4K_PAGES=y ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MULTILINK=y ++CONFIG_PREEMPT_NONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 ++CONFIG_PRINT_STACK_DEPTH=64 ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++CONFIG_RCU_KTHREAD_PRIO=0 ++CONFIG_RCU_NEED_SEGCBLIST=y ++CONFIG_RCU_STALL_COMMON=y ++CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_RFKILL=y ++CONFIG_RTC_DRV_CMOS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_INTF_DEV=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_LIB=y ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++CONFIG_RT_MUTEXES=y ++CONFIG_RUNTIME_TESTING_MENU=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_RXKAD=y ++CONFIG_SATA_MOBILE_LPM_POLICY=0 ++CONFIG_SBITMAP=y ++CONFIG_SCHED_HRTICK=y ++CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_LOWLEVEL=y ++CONFIG_SCSI_MOD=y ++CONFIG_SCSI_PROC_FS=y ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_SECURITY_DMESG_RESTRICT=y ++CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_16550A_VARIANTS=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_DMA=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_SERIAL_EARLYCON=y ++CONFIG_SHMEM=y ++CONFIG_SIGNALFD=y ++CONFIG_SLABINFO=y ++CONFIG_SLAB_MERGE_DEFAULT=y ++CONFIG_SLUB=y ++CONFIG_SLUB_CPU_PARTIAL=y ++CONFIG_SND_DRIVERS=y ++CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 ++CONFIG_SND_HDA_PREALLOC_SIZE=64 ++CONFIG_SND_MAX_CARDS=16 ++CONFIG_SND_OSSEMUL=y ++CONFIG_SND_PCI=y ++CONFIG_SND_PCM_OSS_PLUGINS=y ++CONFIG_SND_PROC_FS=y ++CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y ++CONFIG_SND_USB=y ++CONFIG_SND_VERBOSE_PROCFS=y ++CONFIG_SND_X86=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_SQUASHFS=y ++CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y ++CONFIG_SQUASHFS_EMBEDDED=y ++CONFIG_SQUASHFS_FILE_DIRECT=y ++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 ++CONFIG_SQUASHFS_XZ=y ++CONFIG_SSB_POSSIBLE=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_STAGING=y ++CONFIG_STANDALONE=y ++CONFIG_STDBINUTILS=y ++CONFIG_STP=y ++CONFIG_STRICT_KERNEL_RWX=y ++CONFIG_STRICT_MODULE_RWX=y ++CONFIG_STRIP_ASM_SYMS=y ++CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y ++CONFIG_SWAP=y ++CONFIG_SYMBOLIC_ERRNAME=y ++CONFIG_SYN_COOKIES=y ++CONFIG_SYSCTL=y ++CONFIG_SYSFS=y ++CONFIG_SYSTEM_TRUSTED_KEYS="" ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TEXTSEARCH=y ++CONFIG_THIN_ARCHIVES=y ++CONFIG_TICK_ONESHOT=y ++CONFIG_TIMERFD=y ++CONFIG_TINY_RCU=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_XATTR=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_TRACING_SUPPORT=y ++CONFIG_TRAD_SIGNALS=y ++CONFIG_TTY=y ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_XATTR=y ++CONFIG_UBIFS_FS_ZLIB=y ++CONFIG_UBIFS_FS_ZSTD=y ++CONFIG_UBSAN_ALIGNMENT=y ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_UID16=y ++CONFIG_UNIX=y ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX_SCM=y ++CONFIG_USBIP_VHCI_HC_PORTS=8 ++CONFIG_USBIP_VHCI_NR_HCS=1 ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB_ARMLINUX=y ++CONFIG_USB_AUTOSUSPEND_DELAY=2 ++CONFIG_USB_BELKIN=y ++CONFIG_USB_DEFAULT_PERSIST=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_TT_NEWSCHED=y ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_KEYSPAN_MPR=y ++CONFIG_USB_SERIAL_KEYSPAN_USA18X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y ++CONFIG_USB_SERIAL_SAFE_PADDED=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_VDSO=y ++CONFIG_VHOST_MENU=y ++CONFIG_VIRTIO_MENU=y ++CONFIG_VIRT_TO_BUS=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VMSPLIT_3G=y ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y ++CONFIG_WATCHDOG_OPEN_TIMEOUT=0 ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PRIV=y ++CONFIG_WEXT_PROC=y ++CONFIG_WEXT_SPY=y ++CONFIG_WILINK_PLATFORM_DATA=y ++CONFIG_WIRELESS=y ++CONFIG_WIRELESS_EXT=y ++CONFIG_WLAN=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_X86_SYSFB=y ++CONFIG_XEN_SCRUB_PAGES_DEFAULT=y ++CONFIG_XFRM=y ++CONFIG_XZ_DEC=y ++CONFIG_ZONE_DMA=y ++CONFIG_64BIT=y ++CONFIG_AQUANTIA_PHY=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_ARCH_KEEP_MEMBLOCK=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_STACKWALK=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARCH_WANTS_NO_INSTR=y ++CONFIG_ARM64=y ++CONFIG_ARM64_4K_PAGES=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_ARM64_ERRATUM_843419=y ++CONFIG_ARM64_ERRATUM_845719=y ++CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y ++CONFIG_ARM64_MODULE_PLTS=y ++CONFIG_ARM64_PAGE_SHIFT=12 ++CONFIG_ARM64_PA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++CONFIG_ARM64_TAGGED_ADDR_ABI=y ++CONFIG_ARM64_VA_BITS=39 ++CONFIG_ARM64_VA_BITS_39=y ++CONFIG_ARM_AMBA=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++CONFIG_ARM_MEDIATEK_CPUFREQ_HW=y ++CONFIG_PM_DEVFREQ=y ++CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=y ++CONFIG_ARM_PMU=y ++CONFIG_ARM_PSCI_FW=y ++CONFIG_ATA=y ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_MQ_PCI=y ++CONFIG_BLK_PM=y ++CONFIG_BLOCK_COMPAT=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_COMMON_CLK=y ++CONFIG_COMMON_CLK_MEDIATEK=y ++CONFIG_COMMON_CLK_MT2712=y ++CONFIG_COMMON_CLK_MT7622=y ++CONFIG_COMMON_CLK_MT7622_AUDSYS=y ++CONFIG_COMMON_CLK_MT7622_ETHSYS=y ++CONFIG_COMMON_CLK_MT7622_HIFSYS=y ++CONFIG_COMMON_CLK_MT7988=y ++CONFIG_COMMON_CLK_MT8183=y ++CONFIG_COMMON_CLK_MT8516=y ++CONFIG_COMPAT=y ++CONFIG_COMPAT_32BIT_TIME=y ++CONFIG_COMPAT_BINFMT_ELF=y ++CONFIG_COMPAT_NETLINK_MESSAGES=y ++CONFIG_COMPAT_OLD_SIGACTION=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ATTR_SET=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_RMAP=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CRC16=y ++CONFIG_CRYPTO_AES_ARM64=y ++CONFIG_CRYPTO_AES_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_CMAC=y ++CONFIG_CRYPTO_CRC32=y ++CONFIG_CRYPTO_CRC32C=y ++CONFIG_CRYPTO_CRYPTD=y ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_DRBG=y ++CONFIG_CRYPTO_DRBG_HMAC=y ++CONFIG_CRYPTO_DRBG_MENU=y ++CONFIG_CRYPTO_ECB=y ++CONFIG_CRYPTO_ECC=y ++CONFIG_CRYPTO_ECDH=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_HASH_INFO=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_JITTERENTROPY=y ++CONFIG_CRYPTO_LIB_SHA256=y ++CONFIG_CRYPTO_LZO=y ++CONFIG_CRYPTO_RNG=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=y ++CONFIG_CRYPTO_SHA256=y ++CONFIG_CRYPTO_SHA256_ARM64=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_SIMD=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_DCACHE_WORD_ACCESS=y ++CONFIG_DEBUG_MISC=y ++CONFIG_DIMLIB=y ++CONFIG_DMADEVICES=y ++CONFIG_DMATEST=y ++CONFIG_DMA_DIRECT_REMAP=y ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_ENGINE_RAID=y ++CONFIG_DMA_OF=y ++CONFIG_DMA_REMAP=y ++CONFIG_DMA_VIRTUAL_CHANNELS=y ++CONFIG_DTC=y ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_EDAC_SUPPORT=y ++CONFIG_EINT_MTK=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_F2FS_FS=y ++CONFIG_FIT_PARTITION=y ++CONFIG_FIXED_PHY=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_FRAME_POINTER=y ++CONFIG_FS_IOMAP=y ++CONFIG_FS_MBCACHE=y ++CONFIG_FWNODE_MDIO=y ++CONFIG_FW_LOADER_PAGED_BUF=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_GENERIC_ARCH_TOPOLOGY=y ++CONFIG_GENERIC_BUG=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_GENERIC_CPU_VULNERABILITIES=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_EARLY_IOREMAP=y ++CONFIG_GENERIC_FIND_FIRST_BIT=y ++CONFIG_GENERIC_GETTIMEOFDAY=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y ++CONFIG_GENERIC_MSI_IRQ=y ++CONFIG_GENERIC_MSI_IRQ_DOMAIN=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_PHY=y ++CONFIG_GENERIC_PINCONF=y ++CONFIG_GENERIC_PINCTRL_GROUPS=y ++CONFIG_GENERIC_PINMUX_FUNCTIONS=y ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GLOB=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_CDEV=y ++CONFIG_GRO_CELLS=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_HAS_DMA=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_MTK=y ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MT65XX=y ++CONFIG_ICPLUS_PHY=y ++CONFIG_IIO=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_IO_URING=y ++CONFIG_IRQCHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_IRQ_WORK=y ++CONFIG_JBD2=y ++CONFIG_JUMP_LABEL=y ++CONFIG_LIBFDT=y ++CONFIG_LOCK_DEBUGGING_SUPPORT=y ++CONFIG_LOCK_SPIN_ON_OWNER=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MAXLINEAR_GPHY=y ++CONFIG_MDIO_BUS=y ++CONFIG_MDIO_DEVICE=y ++CONFIG_MDIO_DEVRES=y ++CONFIG_MEDIATEK_GE_PHY=y ++#CONFIG_MEDIATEK_MT6577_AUXADC=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_MEMFD_CREATE=y ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 ++CONFIG_MFD_SYSCON=y ++CONFIG_MIGRATION=y ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_CQHCI=y ++CONFIG_MMC_MTK=y ++CONFIG_MODULES_TREE_LOOKUP=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_MTD_NAND_CORE=y ++CONFIG_MTD_NAND_ECC=y ++CONFIG_MTD_NAND_ECC_MEDIATEK=y ++CONFIG_MTD_NAND_ECC_SW_HAMMING=y ++CONFIG_MTD_NAND_MTK=y ++CONFIG_MTD_NAND_MTK_BMT=y ++CONFIG_MTD_PARSER_TRX=y ++CONFIG_MTD_RAW_NAND=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_SPLIT_FIRMWARE=y ++CONFIG_MTD_SPLIT_FIT_FW=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++CONFIG_MTD_UBI_BLOCK=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTK_EFUSE=y ++CONFIG_MTK_HSDMA=y ++CONFIG_MTK_INFRACFG=y ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_MTK_SCPSYS=y ++CONFIG_MTK_SCPSYS_PM_DOMAINS=y ++CONFIG_MTK_THERMAL=y ++CONFIG_MTK_SOC_THERMAL=y ++CONFIG_MTK_TIMER=y ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++CONFIG_NET_DEVLINK=y ++CONFIG_NET_DSA=y ++CONFIG_NET_DSA_MT7530=y ++CONFIG_NET_DSA_TAG_MTK=y ++CONFIG_LED_TRIGGER_PHY=y ++CONFIG_NET_FLOW_LIMIT=y ++CONFIG_NET_MEDIATEK_SOC=y ++CONFIG_NET_MEDIATEK_SOC_WED=y ++CONFIG_NET_SELFTESTS=y ++CONFIG_NET_SWITCHDEV=y ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NLS=y ++CONFIG_NO_HZ_COMMON=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_NR_CPUS=4 ++CONFIG_NVMEM=y ++CONFIG_NVMEM_SYSFS=y ++CONFIG_OF=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_DYNAMIC=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_GPIO=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_KOBJ=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_OVERLAY=y ++CONFIG_OF_RESOLVE=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_PADATA=y ++CONFIG_PARTITION_PERCPU=y ++CONFIG_PCI=y ++CONFIG_PCIEAER=y ++CONFIG_PCIEASPM=y ++CONFIG_PCIEASPM_PERFORMANCE=y ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PCIE_MEDIATEK_GEN3=y ++CONFIG_PCIE_PME=y ++CONFIG_PCI_DEBUG=y ++CONFIG_PCI_DOMAINS=y ++CONFIG_PCI_DOMAINS_GENERIC=y ++CONFIG_PCI_MSI=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PERF_EVENTS=y ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_PHYLIB=y ++CONFIG_PHYLINK=y ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCTRL_MT7622=y ++CONFIG_PINCTRL_MT7988=y ++CONFIG_PINCTRL_MT8516=y ++CONFIG_PINCTRL_MTK=y ++CONFIG_PINCTRL_MTK_MOORE=y ++CONFIG_PINCTRL_MTK_V2=y ++CONFIG_PM=y ++CONFIG_PM_CLK=y ++CONFIG_PM_GENERIC_DOMAINS=y ++CONFIG_PM_GENERIC_DOMAINS_OF=y ++CONFIG_PM_OPP=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_POWER_SUPPLY=y ++CONFIG_PRINTK_TIME=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_COMPRESS=n ++#CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" ++CONFIG_PSTORE_CONSOLE=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y ++CONFIG_PSTORE_PMSG=y ++CONFIG_PSTORE_RAM=y ++CONFIG_PTP_1588_CLOCK_OPTIONAL=y ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=y ++CONFIG_PWM_SYSFS=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++CONFIG_RAS=y ++CONFIG_RATIONAL=y ++CONFIG_REALTEK_PHY=y ++CONFIG_REED_SOLOMON=y ++CONFIG_REED_SOLOMON_DEC8=y ++CONFIG_REED_SOLOMON_ENC8=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_MT6380=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_RFS_ACCEL=y ++CONFIG_RODATA_FULL_DEFAULT_ENABLED=y ++CONFIG_RPS=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_MT7622=y ++CONFIG_RTC_I2C_AND_SPI=y ++CONFIG_RTL8367S_GSW=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_SCHED_MC=y ++CONFIG_SCSI=y ++CONFIG_SCSI_COMMON=y ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_SERIAL_DEV_CTRL_TTYPORT=y ++CONFIG_SERIAL_MCTRL_GPIO=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SGL_ALLOC=y ++CONFIG_SG_POOL=y ++CONFIG_SMP=y ++CONFIG_SOCK_RX_QUEUE_MAPPING=y ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_SPI=y ++CONFIG_SPI_DYNAMIC=y ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_MEM=y ++CONFIG_SPI_MT65XX=y ++CONFIG_SPI_MTK_NOR=y ++CONFIG_SPI_MTK_SNFI=y ++CONFIG_SRCU=y ++CONFIG_SWCONFIG=y ++CONFIG_SWIOTLB=y ++CONFIG_SWPHY=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_SYSVIPC_COMPAT=y ++CONFIG_THERMAL=y ++CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y ++CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 ++CONFIG_THERMAL_EMULATION=y ++CONFIG_THERMAL_GOV_BANG_BANG=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_STEP_WISE=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_THERMAL_OF=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THREAD_INFO_IN_TASK=y ++CONFIG_TICK_CPU_ACCOUNTING=y ++CONFIG_TIMER_OF=y ++CONFIG_TIMER_PROBE=y ++CONFIG_TREE_RCU=y ++CONFIG_TREE_SRCU=y ++CONFIG_UBIFS_FS=y ++CONFIG_USB=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_VMAP_STACK=y ++CONFIG_WATCHDOG_CORE=y ++CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m ++CONFIG_WATCHDOG_SYSFS=y ++CONFIG_XPS=y ++CONFIG_XXHASH=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZONE_DMA32=y ++CONFIG_ZSTD_COMPRESS=y ++CONFIG_ZSTD_DECOMPRESS=y ++ ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DEVTMPFS_SAFE=y ++ ++CONFIG_REGULATOR_RT5190A=y ++CONFIG_RESET_TI_SYSCON=y ++CONFIG_REGMAP_I2C=y ++CONFIG_MTK_LVTS_THERMAL=y ++CONFIG_PHY_MTK_XSPHY=y ++CONFIG_NVMEM_MTK_EFUSE=y ++ ++ ++CONFIG_WLAN_VENDOR_MEDIATEK=y ++CONFIG_CFG80211=m ++CONFIG_CFG80211_WEXT=y ++CONFIG_MAC80211=y ++CONFIG_MAC80211_LEDS=y ++CONFIG_MT7996E=m ++ ++CONFIG_VFAT_FS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_852=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_15=y ++ ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_STORAGE=y ++CONFIG_I2C_GPIO=y ++CONFIG_SFP=y ++CONFIG_BLK_DEV_NVME=y ++CONFIG_NVME_HWMON=y ++ ++#CONFIG_USB_USBNET=m ++#CONFIG_USB_SERIAL=m ++#CONFIG_USB_SERIAL_OPTION=m ++#CONFIG_USB_SERIAL_QUALCOMM=m ++#CONFIG_USB_NET_CDC_MBIM=m ++#CONFIG_USB_NET_QMI_WWAN=m ++ ++#CONFIG_NVMEM_MTK_EFUSE=y ++#CONFIG_SENSORS_PWM_FAN=y ++ ++CONFIG_DUMMY=m ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_MIP6=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETLINK_DIAG=y ++CONFIG_INET_UDP_DIAG=m ++CONFIG_NET_IPIP=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_IPV6=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_NETFILTER_NETLINK=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV6=m ++CONFIG_NF_REJECT_IPV6=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP6_NF_TARGET_SYNPROXY=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_IP_VS=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++#CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TPROXY_IPV4=m ++CONFIG_NF_TPROXY_IPV6=m ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_XFRM=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_SYNPROXY=m ++CONFIG_NFTL=m ++CONFIG_NFTL_RW=y ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NF_FLOW_TABLE=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NF_FLOW_TABLE_IPV6=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_NAT_FTP=m ++CONFIG_PPP=m ++CONFIG_PPPOE=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_MPPE=m ++CONFIG_VETH=m ++CONFIG_TUN=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_NET_L3_MASTER_DEV=y ++CONFIG_IPVLAN=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_NET_CLS_ACT=y ++# QoS and/or fair queueing ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_CSZ=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_INGRESS=m ++#CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_QOS=y ++CONFIG_NET_ESTIMATOR=y ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_ROUTE=y ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_POLICE=y ++ ++CONFIG_NET_ACT_VLAN=m ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_SAMPLE=y ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++# CONFIG_NET_ACT_BPF is not set ++CONFIG_NET_ACT_CONNMARK=m ++CONFIG_NET_ACT_CTINFO=m ++CONFIG_NET_ACT_SKBMOD=m ++# CONFIG_NET_ACT_IFE is not set ++CONFIG_NET_ACT_TUNNEL_KEY=m ++CONFIG_NET_ACT_CT=m ++# CONFIG_NET_ACT_GATE is not set ++ ++#NFS Client ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_PNFS_FILE_LAYOUT=m ++CONFIG_PNFS_BLOCK=m ++CONFIG_PNFS_FLEXFILE_LAYOUT=m ++CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" ++CONFIG_NFS_V4_1_MIGRATION=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++CONFIG_ROOT_NFS=y ++ ++#NFS Server ++CONFIG_NFSD=m ++CONFIG_NFSD_V2_ACL=y ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_NFSD_PNFS=y ++CONFIG_NFSD_BLOCKLAYOUT=y ++CONFIG_NFSD_SCSILAYOUT=y ++CONFIG_NFSD_FLEXFILELAYOUT=y ++CONFIG_NFSD_FAULT_INJECTION=y ++CONFIG_NFS_ACL_SUPPORT=m ++ ++#usb-tethering ++CONFIG_USB_USBNET=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_RNDIS_HOST=m ++ ++#for lxc ++CONFIG_CGROUPS=y ++CONFIG_NAMESPACES=y ++CONFIG_USER_NS=y ++CONFIG_MEMCG=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CPUSETS=y ++CONFIG_UNIX_DIAG=m ++CONFIG_PACKET_DIAG=m ++CONFIG_FUSE_FS=m ++ ++#for docker ++CONFIG_CGROUP_FREEZER=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_MEMCG_SWAP_ENABLED=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CFS_BANDWIDTH=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CGROUP_BPF=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_SECCOMP=y ++ ++CONFIG_I2C_MUX=y ++CONFIG_I2C_MUX_PCA954x=y ++ ++CONFIG_PCS_MTK_USXGMII=y ++ ++CONFIG_MT7915E=m ++CONFIG_MT798X_WMAC=y ++CONFIG_PHY_MTK_XFI_TPHY=y ++CONFIG_RTC_DRV_PCF8563=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SENSORS_PWM_FAN=y ++ ++#add some 4G/5G modem options ++CONFIG_USB_ACM=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_CDNS_SUPPORT=m ++CONFIG_USB_CDNS3=m ++CONFIG_WWAN=m ++CONFIG_MHI_BUS=m ++CONFIG_MHI_NET=m ++CONFIG_MHI_WWAN_CTRL=m ++CONFIG_MHI_WWAN_MBIM=m ++CONFIG_MTK_T7XX=m ++ ++CONFIG_MARVELL_PHY=m ++CONFIG_MARVELL_10G_PHY=m ++CONFIG_MEDIATEK_2P5GE_PHY=m ++#spi display ++#CONFIG_DRM=m ++#CONFIG_FB=m ++#CONFIG_FB_MODE_HELPERS=y ++#CONFIG_DRM_PANEL_MIPI_DBI=m ++#CONFIG_BACKLIGHT_PWM=m +diff --git a/bpi-r4.its b/bpi-r4.its +new file mode 100644 +index 000000000000..4c10360895a7 +--- /dev/null ++++ b/bpi-r4.its +@@ -0,0 +1,112 @@ ++/dts-v1/; ++ ++/ { ++ description = "U-Boot fitImage for bpi-r4 aarch64 kernel"; ++ #address-cells = <1>; ++ ++ images { ++ kernel-1 { ++ description = "Linux Kernel %version%"; ++ data = /incbin/("./arch/arm64/boot/Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ load = <0x44000000>; ++ entry = <0x44000000>; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-base { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ load = <0x47000000>; ++ compression = "none"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-base-2g5 { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ load = <0x47000000>; ++ compression = "none"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-ov-sd { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtbo"); ++ type = "flat_dt"; ++ }; ++ fdt-ov-emmc { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtbo"); ++ type = "flat_dt"; ++ }; ++/* ramdisk-1 { ++ description = "ramdisk"; ++ data = /incbin/("./rootfs_arm64.cpio.gz"); ++ type = "ramdisk"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ };*/ ++ }; ++ configurations { ++ default = "conf-sd"; ++ conf-base { ++ description = "Boot Linux kernel with base FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-base-2g5 { ++ description = "Boot Linux kernel with base FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base-2g5"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-sd { ++ description = "Boot Linux kernel with SD FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-sd"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-emmc { ++ description = "Boot Linux kernel with EMMC FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-emmc"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ ov-sd { ++ description = "SD FDT overlay blob"; ++ fdt = "fdt-ov-sd"; ++ }; ++ ov-emmc { ++ description = "EMMC FDT overlay blob"; ++ fdt = "fdt-ov-emmc"; ++ }; ++ }; ++}; +diff --git a/build.conf b/build.conf +new file mode 100644 +index 000000000000..60d7ff7a4859 +--- /dev/null ++++ b/build.conf +@@ -0,0 +1,27 @@ ++uploaduser=$USER ++uploadserver=r2 ++uploaddir=/var/lib/tftp ++#uploaduser=root ++#uploadserver=192.168.0.11 ++#uploaddir=/boot/bananapi/bpi-r2/linux ++ ++builddir=../build ++ramdisksize=8G ++#numproc=8 ++ ++board=bpi-r2 ++#board=bpi-r64 ++#board=bpi-r2pro ++#board=bpi-r3 ++board=bpi-r4 ++ ++#r64 with rtl8367 ++#boardversion=v0.1 ++#r2pro with rtl8367 ++#boardversion=v00 ++ ++#mainline uboot for r64 (old ATF) needs 64bit uImage ++#uimagearch=arm64 ++ ++#grep whitelist filter for adding modules to initramfs ++ownmodules='mt76\|bluetooth' +diff --git a/build.sh b/build.sh +new file mode 100755 +index 000000000000..ee71e488bb7c +--- /dev/null ++++ b/build.sh +@@ -0,0 +1,1273 @@ ++#!/bin/bash ++if [[ $UID -eq 0 ]]; ++then ++ echo "do not run as root!" ++ exit 1; ++fi ++ ++numproc=$(grep ^processor /proc/cpuinfo | wc -l) ++ ++. build.conf ++ ++r64newswver=1.0 ++if [[ -z "$board" ]];then board="bpi-r2";fi ++ ++kernver=$(make kernelversion | grep -v 'make') ++#echo $kernver ++ ++DOTCONFIG=".config" ++ ++clr_red=$'\e[1;31m' ++clr_green=$'\e[1;32m' ++clr_yellow=$'\e[1;33m' ++clr_blue=$'\e[1;34m' ++clr_reset=$'\e[0m' ++ ++DEFCONFIG="" ++DTS="" ++DTSI="" ++ ++case $board in ++ "bpi-r2pro") ++ ARCH=arm64 ++ CONFIGPATH=arch/$ARCH/configs ++ DEFCONFIG=$CONFIGPATH/rk3568_bpi-r2p_defconfig ++ DEFCONFIG=$CONFIGPATH/quartz64_defconfig ++ if [[ "$boardversion" == "v00" ]];then ++ DTS=arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro-rtl8367.dts ++ else ++ DTS=arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts ++ fi ++ DTSI=arch/arm64/boot/dts/rockchip/rk356x.dtsi ++ ;; ++ "bpi-r64") ++ ARCH=arm64 ++ CONFIGPATH=arch/$ARCH/configs ++ DEFCONFIG=$CONFIGPATH/mt7622_bpi-r64_defconfig ++ if [[ "$boardversion" == "v0.1" ]];then ++ DTS=arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rtl8367.dts ++ else ++ DTS=arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++ fi ++ DTSI=arch/arm64/boot/dts/mediatek/mt7622.dtsi ++ ;; ++ "bpi-r3") ++ ARCH=arm64 ++ CONFIGPATH=arch/$ARCH/configs ++ DEFCONFIG=$CONFIGPATH/mt7986a_bpi-r3_defconfig ++ DTS=arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts ++ #DTS=arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dts ++ DTSI=arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++ ;; ++ "bpi-r4") ++ ARCH=arm64 ++ CONFIGPATH=arch/$ARCH/configs ++ DEFCONFIG=$CONFIGPATH/mt7988a_bpi-r4_defconfig ++ DTS=arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts ++ DTSI=arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++ ;; ++ *) #bpir2 ++ ARCH=arm ++ CONFIGPATH=arch/$ARCH/configs ++ DEFCONFIG=$CONFIGPATH/mt7623n_evb_fwu_defconfig ++ DTS=arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts ++ DTSI=arch/arm/boot/dts/mediatek/mt7623.dtsi ++ ;; ++esac ++#echo "DTB:${DTS%.*}.dtb" ++export ARCH=$ARCH; ++ ++#defconfig-override ++if [[ "$1" =~ ^(importconfig|defconfig)$ && -n "$2" ]]; ++then ++ if [[ -e "${CONFIGPATH}/${2}_defconfig" ]];then ++ echo "using defconfig ${2}_defconfig" ++ DEFCONFIG="${CONFIGPATH}/${2}_defconfig" ++ else ++ echo "defconfig ${2}_defconfig not found!" ++ fi ++fi ++ ++#Check Crosscompile ++crosscompile=0 ++hostarch=$(uname -m) #r64:aarch64 r2: armv7l ++ ++if [[ ! $hostarch =~ aarch64|armv ]];then ++ if [[ "$ARCH" == "arm64" ]]; then ++ if [[ -z "$(which aarch64-linux-gnu-gcc)" ]];then echo "please install gcc-aarch64-linux-gnu";exit 1;fi ++ export CROSS_COMPILE='ccache aarch64-linux-gnu-' ++ elif [[ "$ARCH" == "arm" ]]; then ++ if [[ -z "$(which arm-linux-gnueabihf-gcc)" ]];then echo "please install gcc-arm-linux-gnueabihf";exit 1;fi ++ export CROSS_COMPILE='ccache arm-linux-gnueabihf-' ++ fi ++ ++ crosscompile=1 ++fi; ++ ++#if [[ "$builddir" != "" && ! "$1" =~ ^(updatesrc|uenv|defconfig|dts.?|[u]?mount)$ ]]; ++if [[ "$builddir" != "" ]]; ++then ++ if [[ "$1" == "importconfig" ]]; ++ then ++ KBUILD_OUTPUT= make mrproper ++ fi ++ if [[ ! "$builddir" =~ ^/ ]] || [[ "$builddir" == "/" ]];then ++ #make it absolute ++ builddir=$(realpath $(pwd)"/"$builddir) ++# echo "absolute: $builddir" ++ fi ++ ++ mkdir -p $builddir ++ ++ if [[ "$ramdisksize" != "" ]]; ++ then ++ mount | grep '\s'$builddir'\s' &>/dev/null #$?=0 found;1 not found ++ if [[ $? -ne 0 ]];then ++ #make sure directory is clean for mounting ++ if [[ "$(ls -A $builddir)" ]];then ++ rm -rf $builddir/* ++ fi ++ if [[ "$1" == "importconfig" ]]; ++ then ++ echo "mounting tmpfs for building..." ++ sudo mount -t tmpfs -o size=$ramdisksize none $builddir ++ fi ++ fi ++ fi ++ ++ #if builddir is empty then run make mrproper to clean up sourcedir ++ if [[ ! "$(ls -A $builddir)" ]];then make mrproper;fi ++ ++ if ! [[ "$1" =~ "updatesrc" ]];then ++ DOTCONFIG="$builddir/$DOTCONFIG" ++ export KBUILD_OUTPUT=$builddir ++ fi ++fi ++ ++function edit() ++{ ++ file=$1 ++ if [[ -z "$EDITOR" ]];then EDITOR=/usr/bin/editor;fi #use alternatives setting ++ if [[ -e "$file" ]];then ++ if [[ -w "$file" ]];then ++ $EDITOR "$file" ++ else ++ echo "file $file not writable by user using sudo..." ++ sudo $EDITOR "$file" ++ fi ++ else ++ echo "file $file not found" ++ fi ++} ++ ++#Check Dependencies ++ ++function check_dep() ++{ ++ PACKAGE_Error=0 ++ ++ grep -i 'ubuntu\|debian' /etc/issue &>/dev/null ++ if [[ $? -ne 0 ]];then ++ echo "depency-check currently only on debian/ubuntu..." ++ return 0; ++ fi ++ PACKAGES=$(dpkg -l | awk '{print $2}') ++ ++ NEEDED_PKGS="make" ++ ++ #echo "needed: $NEEDED_PKGS" ++ ++ if [[ $# -ge 1 ]]; ++ then ++ if [[ $@ =~ "build" ]];then ++ NEEDED_PKGS+=" u-boot-tools bc gcc libc6-dev libncurses-dev ccache libssl-dev" ++ fi ++ if [[ $@ =~ "deb" ]];then ++ NEEDED_PKGS+=" fakeroot" ++ fi ++ fi ++ ++ echo "needed: $NEEDED_PKGS" ++ for package in $NEEDED_PKGS; do ++ #TESTPKG=$(dpkg -l |grep "\s${package}") ++ TESTPKG=$(echo "$PACKAGES" |grep "^${package}") ++ if [[ -z "${TESTPKG}" ]];then echo "please install ${package}";PACKAGE_Error=1;fi ++ done ++ if [ ${PACKAGE_Error} == 1 ]; then return 1; fi ++ return 0; ++} ++ ++function getuenvpath { ++ if [[ $crosscompile -ne 0 ]];then ++ uenv_base=/media/${USER}/BPI-BOOT/ ++ else ++ uenv_base=/boot/ ++ fi ++ if [[ -d $uenv_base ]];then ++ if [[ "$board" == "bpi-r2" || "$board" == "bpi-r64" ]];then ++ #r2/r64 uboot: ${bpi}/${board}/${service}/${bootenv} ++ uenv=${uenv_base}/bananapi/$board/linux/uEnv.txt ++ else ++ uenv=${uenv_base}/uEnv.txt ++ fi ++ if [[ ! -e $uenv ]];then ++ mkdir -p $(dirname ${uenv}) ++ fi ++ fi ++ echo $uenv ++} ++ ++function get_version() ++{ ++ echo "generate branch vars..." ++ #kernbranch=$(git rev-parse --abbrev-ref HEAD) ++ ++ echo "getting git branch: " ++ #find branches with actual commit and filter out detached head ++ commit=$(git log -n 1 --pretty='%h') ++ branches=$(git branch --contains $commit | grep -v '(HEAD') ++ echo "$branches" ++ ++ kernbranch=$(echo "$branches" | grep '^*') #look for marked branch (local) ++ if [[ "$kernbranch" == "" ]];then #no marked branch (travis) ++ kernbranch=$(echo "$branches" | head -1) #use first one ++ fi ++ #kernbranch=$(git branch --contains $(git log -n 1 --pretty='%h') | grep '^*' | grep -v '(HEAD' | head -1 | sed 's/^..//') ++ kernbranch=$(echo "$kernbranch" | sed 's/^..//') ++ kernbranch=${kernbranch//frank-w_/} ++ #if no branch is selected (e.g. bisect) ++ if [[ "${kernbranch}" =~ ^\(.* ]]; then ++ kernbranch="-$commit"; ++ fi ++ ++ gitbranch=$(echo $kernbranch|sed 's/^[456]\.[0-9]\+//'|sed 's/-rc$//') ++ ++ echo "kernbranch:$kernbranch,gitbranch:$gitbranch" ++} ++ ++function get_r64_switch ++{ ++ grep 'RTL8367S_GSW=y' $DOTCONFIG &>/dev/null ++ if [[ $? -eq 0 ]];then ++ echo "rtl8367" ++ else ++ grep 'MT753X_GSW=y' $DOTCONFIG &>/dev/null ++ if [[ $? -eq 0 ]];then ++ echo "mt7531" ++ else ++ echo "" ++ fi ++ fi ++} ++ ++function increase_kernel { ++ #echo $kernver ++ old_IFS=$IFS ++ IFS='.' ++ read -ra KV <<< "$kernver" ++ IFS=',' ++ newkernver=${KV[0]}"."${KV[1]}"."$(( ${KV[2]} +1 )) ++ echo $newkernver ++} ++ ++function disable_option() { ++ echo "disable $1" ++ if [[ "$1" == "" ]];then echo "option missing ($1)";return;fi ++ #CFG=RTL8367S_GSW; ++ CFG=${1^^}; ++ CFG=${CFG//CONFIG_/} ++ #echo "CFG:$CFG" ++ #grep -i 'mt753x\|rtl8367' .config ++ grep $CFG .config ++ if [[ $? -eq 0 ]]; then ++ sed -i 's:CONFIG_'$CFG'=y:# CONFIG_'$CFG' is not set:g' $DOTCONFIG ++ grep $CFG $DOTCONFIG ++ else ++ echo "option CONFIG_$CFG not found in .config" ++ fi ++} ++ ++function update_kernel_source { ++ changedfiles=$(git diff --name-only) ++ if [[ -z "$changedfiles" ]]; then ++ git fetch stable ++ ret=$? ++ if [[ $ret -eq 0 ]];then ++ newkernver=$(increase_kernel) ++ kernmajorver=$(make kernelversion | sed -e 's/\.[0-9]\+$//') ++ maxkernver=$(git for-each-ref --sort=-taggerdate --count=1 refs/tags/v${kernmajorver}.*| sed 's/^.*refs\/tags\/v//') ++ echo "newkernver:$newkernver (max:$maxkernver)" ++ git merge --no-edit v$newkernver ++ elif [[ $ret -eq 128 ]];then ++ #repo not found ++ git remote add stable https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git ++ fi ++ else ++ echo "please first commit/stash modified files: $changedfiles" ++ fi ++} ++ ++function changelog() { ++ get_version >/dev/null ++ lasttag=$(curl -s "https://api.github.com/repos/frank-w/BPI-R2-4.14/releases?per_page=100" | jq -r '[.[] | select(.tag_name|contains("'${kernbranch}'"))][0]' | grep "tag_name" | sed 's/.*: "\(.*\)",/\1/') ++ echo "changes since $lasttag:" ++ git log --pretty=format:"%h %ad %s %d" --date=short $lasttag..HEAD ++} ++ ++function pack { ++ get_version ++ #if [[ "$board" == "bpi-r64" ]];then ++ # switch=$(get_r64_switch)"_" ++ #fi ++ prepare_SD ++ echo "pack..." ++ olddir=$(pwd) ++ cd ../SD ++ fname=${board}_${switch}${kernver}${gitbranch}.tar.gz ++ tar -cz --owner=root --group=root -f $fname BPI-BOOT BPI-ROOT ++ md5sum $fname > $fname.md5 ++ ls -lh $(pwd)"/"$fname ++ cd $olddir ++} ++ ++function pack_debs { ++ get_version ++ echo "pack linux-headers, linux-image, linux-libc-dev debs..." ++ echo "LOCALVERSION=${gitbranch} board=$board ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE" ++ LOCALVERSION="${gitbranch}" board="$board" KDEB_COMPRESS=gzip make bindeb-pkg ++ if [[ $? -ne 0 ]];then exit 1;fi; ++ ls ../*.deb ++} ++ ++ ++function upload { ++ get_version ++ ++ DTBFILE=${DTS%.*}.dtb ++ echo "using ${DTBFILE}..." ++ bindir=""; ++ if [[ -n "$builddir" ]];then bindir="$builddir/"; fi ++ ++ b=${board//bpi/} ++ if [[ "${gitbranch}" =~ "${b}" ]]; then ++ b="" ++ fi ++ ++ imagename="${kernver}${gitbranch}${b}" ++ read -e -i $imagename -p "Kernel-filename: " input ++ imagename="${input:-$imagename}" ++ ++ echo "Name: $imagename" ++ ++ if [[ "$board" == "bpi-r2" ]];then ++ imagename="uImage_$imagename" ++ else ++ read -e -i y -p "upload fit? " fitupload ++ if [[ "$fitupload" == "y" ]]; ++ then ++ imagename="${imagename}.itb" ++ echo "uploading fit as $imagename" ++ else ++ dtbname="${kernver}${b}${gitbranch}.dtb" ++ read -e -i $dtbname -p "dtb-filename: " input ++ dtbname="${input:-$dtbname}" ++ echo "DTB Name: $dtbname" ++ fi ++ fi ++ ++ echo "DTB Name: $dtbname" ++ echo "uploading to ${uploadserver}:${uploaddir}..." ++ ++ if [[ "$board" == "bpi-r2" ]];then ++ scp uImage ${uploaduser}@${uploadserver}:${uploaddir}/${imagename} ++ else ++ if [[ "$fitupload" == "y" ]]; ++ then ++ scp ${board}.itb ${uploaduser}@${uploadserver}:${uploaddir}/${imagename} ++ else ++ scp uImage_nodt ${uploaduser}@${uploadserver}:${uploaddir}/${imagename} ++ scp ${bindir}${DTBFILE} ${uploaduser}@${uploadserver}:${uploaddir}/${dtbname} ++ fi ++ fi ++} ++ ++function install ++{ ++ get_version ++ ++ DTBFILE=${DTS%.*}.dtb ++ echo "using ${DTBFILE}..." ++ bindir=""; ++ if [[ -n "$builddir" ]];then bindir="$builddir/"; fi ++ ++ imagename="${kernver}${gitbranch}" ++ if [[ "$board" == "bpi-r2pro" ]];then ++ $0 mount ++ fi ++ read -e -i $imagename -p "Image-filename: " input ++ imagename="${input:-$imagename}" ++ ++ echo "Name: $imagename" ++ ++ if [[ $crosscompile -eq 0 ]]; then ++ kerneldir="/boot/bananapi/$board/linux" ++ kernelfile="$kerneldir/$imagename" ++ if [[ -d "$kerneldir" ]];then ++ if [[ -e "$kernelfile" ]];then ++ echo "backup of kernel: $kernelfile.bak" ++ sudo cp "$kernelfile" "$kernelfile.bak" ++ fi ++ echo "installing new kernel..." ++ sudo cp ./uImage "$kernelfile" ++ sudo make modules_install ++ else ++ echo "Kernel directory not found...is /boot mounted?" ++ fi ++ else ++ itbinput=n ++ imginput=n ++ read -p "Press [enter] to copy data to SD-Card..." ++ if [[ -d /media/$USER/BPI-BOOT ]]; then ++ ++ targetdir=/media/$USER/BPI-BOOT ++ if [[ "$board" == "bpi-r2" || "$board" == "bpi-r64" ]];then ++ targetdir=/media/$USER/BPI-BOOT/bananapi/$board/linux ++ fi ++ mkdir -p $targetdir ++ kernelfile=$targetdir/$imagename ++ ++ dtinput=n ++ ndtinput=y ++ imginput=y ++ if [[ -e ${board}.its ]];then ++ read -e -i "y" -p "install FIT kernel (itb) [yn]? " itbinput ++ if [[ "$itbinput" == "y" ]];then ++ itbname=${imagename}.itb ++ itbfile=$targetdir/$itbname ++ if [[ -e $itbfile ]];then ++ echo "backup of kernel: $itbfile.bak" ++ cp $itbfile $itbfile.bak ++ fi ++ echo "copy new kernel" ++ cp ./${board}.itb $itbfile ++ if [[ $? -ne 0 ]];then exit 1;fi ++ ndtinput=n ++ imginput=n ++ fi ++ else ++ read -e -i "y" -p "install kernel with DT [yn]? " dtinput ++ if [[ "$dtinput" == "y" ]];then ++ if [[ -e $kernelfile ]];then ++ echo "backup of kernel: $kernelfile.bak" ++ cp $kernelfile $kernelfile.bak ++ fi ++ echo "copy new kernel" ++ cp ./uImage $kernelfile ++ if [[ $? -ne 0 ]];then exit 1;fi ++ fi ++ ++ ndt="n" ++ if [ "$dtinput" != "y" ];then ndt="y"; fi ++ read -e -i "$ndt" -p "install kernel with separate DT [yn]? " ndtinput ++ ndtsuffix="_nodt" ++ fi ++ ++ if [[ "$board" == "bpi-r2pro" ]];then ++ targetdir=/media/$USER/BPI-BOOT/extlinux ++ read -e -i "$imginput" -p "install img kernel (img.gz) [yn]? " imginput ++ if [[ "$imginput" == "y" ]];then ++ dtbname=${imgname}.dtb ++ imgname=${imagename}.gz ++ imgfile=$targetdir/$imgname ++ if [[ -e ${imgfile} ]];then ++ echo "backup of kernel: $imgfile.bak" ++ cp ${imgfile} ${imgfile}.bak ++ fi ++ echo "copy new kernel" ++ set -x ++ cp ${bindir}arch/arm64/boot/Image.gz $imgfile ++ cp ${bindir}${DTBFILE} ${targetdir}/${dtbname} ++ set +x ++ if [[ $? -ne 0 ]];then exit 1;fi ++ ndtinput=n ++ fi ++ fi ++ if [[ "$ndtinput" == "y" ]];then ++ if [[ -e ${kernelfile}${ndtsuffix} ]];then ++ echo "backup of kernel: $kernelfile.bak" ++ cp ${kernelfile}${ndtsuffix} ${kernelfile}${ndtsuffix}.bak ++ fi ++ echo "copy new nodt kernel" ++ cp ./uImage_nodt ${kernelfile}${ndtsuffix} ++ if [[ $? -ne 0 ]];then exit 1;fi ++ mkdir -p $targetdir/dtb ++ dtbname=${kernver}${gitbranch}.dtb ++ read -e -i $dtbname -p "dtb-filename: " input ++ dtbname="${input:-$dtbname}" ++ echo "DTB Name: $dtbname" ++ ++ dtbfile=$targetdir/dtb/${dtbname} ++ if [[ -e $dtbfile ]];then ++ echo "backup of dtb: $dtbfile.bak" ++ cp $dtbfile $dtbfile.bak ++ fi ++ echo "copy new dtb" ++ cp ${bindir}${DTBFILE} $dtbfile ++ fi ++ ++ if [[ "$dtinput" == "y" ]] || [[ "$ndtinput" == "y" ]] || [[ "$itbinput" == "y" ]] || [[ "$imginput" == "y" ]];then ++ echo "copy modules (root needed because of ext-fs permission)" ++ export INSTALL_MOD_PATH=/media/$USER/BPI-ROOT/; ++ echo "INSTALL_MOD_PATH: $INSTALL_MOD_PATH" ++ sudo make ARCH=$ARCH INSTALL_MOD_PATH=$INSTALL_MOD_PATH KBUILD_OUTPUT=$KBUILD_OUTPUT modules_install ++ ++ echo "uImage:" ++ if [[ "$itbinput" == "y" ]];then ++ echo "${itbfile}" ++ fi ++ if [[ "$dtinput" == "y" ]];then ++ echo "${kernelfile}" ++ fi ++ if [[ "$ndtinput" == "y" ]];then ++ echo "${kernelfile}${ndtsuffix}" ++ echo "DTB: ${dtbfile}" ++ fi ++ ++ kernelname=$(ls -1t $INSTALL_MOD_PATH"/lib/modules" | head -n 1) ++ EXTRA_MODULE_PATH=$INSTALL_MOD_PATH"/lib/modules/"$kernelname"/kernel/extras" ++ #echo $kernelname" - "${EXTRA_MODULE_PATH} ++ CRYPTODEV="utils/cryptodev/cryptodev-linux/cryptodev.ko" ++ if [ -e "${CRYPTODEV}" ]; then ++ echo Copy CryptoDev ++ sudo mkdir -p "${EXTRA_MODULE_PATH}" ++ sudo cp "${CRYPTODEV}" "${EXTRA_MODULE_PATH}" ++ #Build Module Dependencies ++ sudo /sbin/depmod -b $INSTALL_MOD_PATH ${kernelname} ++ fi ++ ++ #sudo cp -r ../mod/lib/modules /media/$USER/BPI-ROOT/lib/ ++ if [[ -n "$(grep 'CONFIG_MT76=' $DOTCONFIG)" ]];then ++ echo "MT76 set,don't forget the firmware-files..."; ++ fi ++ else ++ echo "install of modules skipped because no kernel was installed"; ++ fi ++ ++ echo "syncing sd-card...this will take a while" ++ echo "run 'watch -n 1 grep -e Dirty: /proc/meminfo' to show progress" ++ sync ++ ++ uenv=$(getuenvpath) ++ echo "using bootfile $uenv" ++ openuenv=n ++ ++ if [[ -e "$uenv" ]];then ++ echo "by default this kernel-/dtb-file will be loaded (kernel-var in uEnv.txt):" ++ if [[ "$itbinput" == "y" ]];then ++ curkernel=$(grep '^fit=' $uenv|tail -1| sed 's/fit=//') ++ else ++ curkernel=$(grep '^kernel=' $uenv|tail -1| sed 's/kernel=//') ++ curfdt=$(grep '^fdt=' $uenv|tail -1| sed 's/fdt=//') ++ fi ++ echo "kernel: " $curkernel ++ echo "dtb: " $curfdt ++ if [[ "$curkernel" == "${imagename}" || "$curkernel" == "${imagename}${ndtsuffix}" || "$curkernel" == "${itbname}" ]];then ++ echo "no change needed!" ++ openuenv=n ++ else ++ echo "change needed to boot new kernel (kernel=${imagename}/fit=${itbname})!" ++ openuenv=y ++ fi ++ else ++ echo "no bootconfig...change needed to boot new kernel (kernel=${imagename}/fit=${itbname})!" ++ openuenv=y ++ fi ++ ++ read -e -i "$openuenv" -p "open boot config file (uEnv/extlinux.conf) [yn]? " input ++ if [[ "$input" == "y" ]];then ++ $0 uenv ++ fi ++ ++ read -e -i "y" -p "umount SD card [yn]? " input ++ if [[ "$input" == "y" ]];then ++ $0 umount ++ fi ++ else ++ echo "SD-Card not found!" ++ fi ++ fi ++} ++ ++function install_modules { ++ echo "cleaning up modules" ++ rm -r $(pwd)/mod/* 2> /dev/null ++ mkdir $(pwd)/mod ++ echo "building and installing modules" ++# export LOCALVERSION="${gitbranch}" ++# #MAKEFLAGS="V=1" ++# make ${MAKEFLAGS} ${CFLAGS} modules ++ build ++ INSTALL_MOD_PATH=$(pwd)/mod make modules_install ++} ++ ++function mod2initrd { ++ size=$(du -s mod | awk '{ print $1}') #65580 working ++ echo $size ++ if [[ $size -eq 0 ]]; ++ then ++ install_modules ++ fi ++ #first reset initrd ++ echo "reset initramfs..." ++ git checkout utils/buildroot/rootfs_${board}.cpio.gz ++ ls -lh utils/buildroot/rootfs_${board}.cpio.gz ++ ( ++ echo "adding modules to initramfs..." ++ cd mod ++ #need to create dirs and common files first ++ find . -not -iname '*.ko' > mod.lst ++ if [[ "$ownmodules" != "" ]];then ++ find . | grep $ownmodules >> mod.lst ++ fi ++ cat mod.lst | cpio -H newc -o | gzip >> ../utils/buildroot/rootfs_${board}.cpio.gz ++ #to show whats inside cpio: ++ #gunzip -c < ../utils/buildroot/rootfs_${board}.cpio.gz | while LANG=C cpio -itv 2>/dev/null; do :; done| grep lib/modules ++ ls -lh ../utils/buildroot/rootfs_${board}.cpio.gz ++ ) ++ initrdsize=$(ls -l --block-size=M utils/buildroot/rootfs_bpi-r2.cpio.gz | awk '{print $5}' | sed 's/M$//') ++ if [[ $initrdsize -lt 100 ]]; #lower than 40MB leaves 10MB for kernel uImage ++ then ++ echo "re-building kernel with initramfs... ($DOTCONFIG)" ++ OWNCONFIGS="CONFIG_INITRAMFS_SOURCE=\"utils/buildroot/rootfs_${board}.cpio.gz\" CONFIG_INITRAMFS_FORCE=y" ++ build ++ installchoice ++ else ++ echo "kernel with initrd may exceed uboot limit of ~100MB (Bad Data CRC)" ++ fi ++} ++ ++function deb { ++#set -x ++ check_dep "deb" ++ if [[ $? -ne 0 ]];then exit 1;fi ++ get_version ++ ver=${kernver}-${board}${gitbranch} ++ uimagename=uImage_${kernver}${gitbranch} ++ echo "deb package ${ver}" ++ prepare_SD ++ boardv=${board:4} ++ targetdir=debian/bananapi-$boardv-image ++ ++# cd ../SD ++# fname=bpi-r2_${kernver}_${gitbranch}.tar.gz ++# tar -cz --owner=root --group=root -f $fname BPI-BOOT BPI-ROOT ++ ++ rm -rf $targetdir/boot/bananapi/$board/linux/* ++ rm -rf $targetdir/lib/modules/* ++ mkdir -p $targetdir/boot/bananapi/$board/linux/dtb/ ++ mkdir -p $targetdir/lib/modules/ ++ mkdir -p $targetdir/DEBIAN/ ++ ++ #sudo mount --bind ../SD/BPI-ROOT/lib/modules debian/bananapi-r2-image/lib/modules/ ++ if [[ -e ./uImage || -e ./uImage_nodt ]] && [[ -d ../SD/BPI-ROOT/lib/modules/${ver} ]]; then ++ if [[ -e ./uImage ]];then ++ cp ./uImage $targetdir/boot/bananapi/$board/linux/${uimagename} ++ fi ++ if [[ -e ./uImage_nodt && -e ./$board.dtb ]];then ++ cp ./uImage_nodt $targetdir/boot/bananapi/$board/linux/${uimagename}_nodt ++ cp ./$board.dtb $targetdir/boot/bananapi/$board/linux/dtb/$board-${kernver}${gitbranch}.dtb ++ fi ++# pwd ++ cp -r ../SD/BPI-ROOT/lib/modules/${ver} $targetdir/lib/modules/ ++ #rm debian/bananapi-r2-image/lib/modules/${ver}/{build,source} ++ #mkdir debian/bananapi-r2-image/lib/modules/${ver}/kernel/extras ++ #cp cryptodev-linux/cryptodev.ko debian/bananapi-r2-image/lib/modules/${ver}/kernel/extra ++ cat > $targetdir/DEBIAN/preinst << EOF ++#!/bin/bash ++clr_red=\$'\e[1;31m' ++clr_green=\$'\e[1;32m' ++clr_yellow=\$'\e[1;33m' ++clr_blue=\$'\e[1;34m' ++clr_reset=\$'\e[0m' ++m=\$(mount | grep '/boot[^/]') ++if [[ -z "\$m" ]]; ++then ++ echo "\${clr_red}/boot needs to be mountpoint for /dev/mmcblk0p1\${clr_reset}"; ++ exit 1; ++fi ++kernelfile=/boot/bananapi/$board/linux/${uimagename} ++if [[ -e "\${kernelfile}" ]];then ++ echo "\${clr_red}\${kernelfile} already exists\${clr_reset}" ++ echo "\${clr_red}please remove/rename it or uninstall previous installed kernel-package\${clr_reset}" ++ exit 2; ++fi ++EOF ++ chmod +x $targetdir/DEBIAN/preinst ++ cat > $targetdir/DEBIAN/postinst << EOF ++#!/bin/bash ++clr_red=\$'\e[1;31m' ++clr_green=\$'\e[1;32m' ++clr_yellow=\$'\e[1;33m' ++clr_blue=\$'\e[1;34m' ++clr_reset=\$'\e[0m' ++case "\$1" in ++ configure) ++ #install|upgrade) ++ echo "kernel=${uimagename}">>/boot/bananapi/$board/linux/uEnv.txt ++ ++ #check for non-dsa-kernel (4.4.x) ++ kernver=\$(uname -r) ++ if [[ "\${kernver:0:3}" == "4.4" ]]; ++ then ++ echo "\${clr_yellow}you are upgrading from kernel 4.4.\${clr_reset}"; ++ echo "\${clr_yellow}Please make sure your network-config (/etc/network/interfaces) matches dsa-driver\${clr_reset}"; ++ echo "\${clr_yellow}(bring cpu-ports ethx up, ip-configuration to wan/lanx)\${clr_reset}"; ++ fi ++ ;; ++ *) echo "unhandled \$1 in postinst-script" ++esac ++EOF ++ chmod +x $targetdir/DEBIAN/postinst ++ cat > $targetdir/DEBIAN/postrm << EOF ++#!/bin/bash ++case "\$1" in ++ abort-install) ++ echo "installation aborted" ++ ;; ++ remove|purge) ++ if [[ -e /boot/bananapi/$board/linux/uEnv.txt ]];then ++ cp /boot/bananapi/$board/linux/uEnv.txt /boot/bananapi/$board/linux/uEnv.txt.bak ++ grep -v ${uimagename} /boot/bananapi/$board/linux/uEnv.txt.bak > /boot/bananapi/$board/linux/uEnv.txt ++ else ++ cp /boot/uEnv.txt /boot/uEnv.txt.bak ++ grep -v ${uimagename} /boot/uEnv.txt.bak > /boot/uEnv.txt ++ fi ++ ;; ++esac ++EOF ++ chmod +x $targetdir/DEBIAN/postrm ++ if [[ "$board" == "bpi-r2" ]];then ++ debarch=armhf ++ else ++ debarch=arm64 ++ fi ++ ++ cat > $targetdir/DEBIAN/control << EOF ++Package: bananapi-$boardv-image-${kernbranch} ++Version: ${kernver}-1 ++Section: custom ++Priority: optional ++Architecture: $debarch ++Multi-Arch: no ++Essential: no ++Maintainer: Frank Wunderlich ++Description: ${BOARD^^} linux image ${ver} ++EOF ++ cd debian ++ fakeroot dpkg-deb --build bananapi-$boardv-image ../debian ++ cd .. ++ ls -lh debian/*.deb ++ debfile=debian/bananapi-$boardv-image-${kernbranch,,}_${kernver}-1_$debarch.deb ++ dpkg -c $debfile ++ ++ dpkg -I $debfile ++ else ++ echo "First build kernel ${ver}" ++ echo "eg: ./build" ++ fi ++} ++ ++function build { ++ echo Cleanup Kernel Build ++ rm arch/arm/boot/zImage 2>/dev/null ++ rm arch/arm/boot/zImage-dtb 2>/dev/null ++ rm arch/arm64/boot/Image 2>/dev/null ++ rm ./uImage* 2>/dev/null ++ rm ${board}.dtb 2>/dev/null ++ ++ check_dep "build" ++ if [[ $? -ne 0 ]];then exit 1;fi ++ ++ get_version ++ ++ if [ -e $DOTCONFIG ]; then ++ exec 3> >(tee build.log) ++ export LOCALVERSION="${gitbranch}" ++ #MAKEFLAGS="V=1" ++ export DTC_FLAGS="-@" ++ make ${MAKEFLAGS} ${CFLAGS} ${OWNCONFIGS} 2>&3 ++ ret=$? ++ exec 3>&- ++ ++ if [[ $ret == 0 ]]; then ++ if [[ -z "${uimagearch}" ]];then uimagearch=arm;fi ++ ++ DTBFILE=${DTS%.*}.dtb ++ case "$board" in ++ "bpi-r2pro") ++ IMAGE=arch/arm64/boot/Image ++ LADDR=0x7f000001 ++ ENTRY=0x7f000001 ++ ;; ++ "bpi-r64") ++ IMAGE=arch/arm64/boot/Image ++ LADDR=40080000 ++ ENTRY=40080000 ++ ;; ++ "bpi-r3") ++ IMAGE=arch/arm64/boot/Image ++ LADDR=40080000 ++ ENTRY=40080000 ++ if [[ -e mt7986a-bananapi-bpi-r3-nor.dts ]];then ++ echo "compiling r3 dt overlays" ++ #dtc -O dtb -o bpi-r3-nor.dtbo mt7986a-bananapi-bpi-r3-nor.dts ++ #dtc -O dtb -o bpi-r3-nand.dtbo mt7986a-bananapi-bpi-r3-nand.dts ++ fi ++ ;; ++ "bpi-r4") ++ IMAGE=arch/arm64/boot/Image ++ LADDR=40080000 ++ ENTRY=40080000 ++ ;; ++ "bpi-r2") ++ IMAGE=arch/arm/boot/zImage ++ LADDR=80008000 ++ ENTRY=80008000 ++ ;; ++ esac ++ ++ if [[ "$builddir" != "" ]]; ++ then ++ cp $builddir/${IMAGE%.*}* ${IMAGE%/*} ++ DTBBASE=${DTBFILE%.*} ++ if [[ -e $builddir/${DTBBASE}.dtb ]];then ++ cp $builddir/${DTBBASE}*.dtb ${DTBFILE%/*} ++ cp $builddir/$DTBFILE $board.dtb ++ fi ++ if [[ -e $builddir/${DTBBASE}-sd.dtbo ]];then ++ cp $builddir/${DTBBASE}-*.dtbo ${DTBFILE%/*} ++ fi ++ elif [[ -e $DTBFILE ]];then ++ cp $DTBFILE $board.dtb ++ fi ++ ++ #if [[ "$board" == "bpi-r2pro" ]];then ++ # #skipping mkimage causes no choice, but uImage is not bootable on r2pro ++ # mkimage -A ${uimagearch} -O linux -T kernel -C none -a $LADDR -e $ENTRY -n "Linux Kernel $kernver$gitbranch" -d $IMAGE ./uImage_nodt ++ if [[ -e ${board}.its ]];then #"$board" == "bpi-r64" || "$board" == "bpi-r3" ]];then ++ mkimage -A ${uimagearch} -O linux -T kernel -C none -a $LADDR -e $ENTRY -n "Linux Kernel $kernver$gitbranch" -d $IMAGE ./uImage_nodt ++ sed "s/%version%/$kernver$gitbranch/" ${board}.its > ${board}.its.tmp ++ mkimage -f ${board}.its.tmp ${board}.itb ++ cp ${board}.itb ${board}-$kernver$gitbranch.itb ++ rm ${board}.its.tmp ++ else ++ cat $IMAGE $DTBFILE > arch/arm/boot/zImage-dtb ++ mkimage -A arm -O linux -T kernel -C none -a $LADDR -e $ENTRY -n "Linux Kernel $kernver$gitbranch" -d arch/arm/boot/zImage-dtb ./uImage ++ ++ echo "build uImage without appended DTB..." ++ export DTC_FLAGS="-@ --space 32768" ++ make ${CFLAGS} CONFIG_ARM_APPENDED_DTB=n &>/dev/null #output/errors can be ignored because they are printed before ++ ret=$? ++ if [[ $ret == 0 ]]; then ++ mkimage -A arm -O linux -T kernel -C none -a $LADDR -e $ENTRY -n "Linux Kernel $kernver$gitbranch" -d $IMAGE ./uImage_nodt ++ fi ++ fi ++ ++ if [[ "$builddir" != "" ]]; ++ then ++ if [[ -e uImage ]];then ++ cp {,$builddir/}uImage ++ fi ++ cp {,$builddir/}uImage_nodt ++ if [[ -e ${board}.itb ]];then ++ cp {,$builddir/}${board}.itb ++ fi ++ fi ++ fi ++ else ++ echo "No Configfile found, Please Configure Kernel" ++ fi ++ return $ret ++} ++ ++function prepare_SD { ++ SD=../SD ++ cd $(dirname $0) ++ mkdir -p ../SD >/dev/null 2>/dev/null ++ ++ echo "cleanup..." ++ for toDel in "$SD/BPI-BOOT/" "$SD/BPI-ROOT/"; do ++ rm -r ${toDel} 2>/dev/null ++ done ++ ++ echo "copy..." ++ ++ bindir=""; ++ if [[ -n "$builddir" ]];then bindir="$builddir/"; fi ++ ++ export INSTALL_MOD_PATH=$SD/BPI-ROOT/; ++ echo "INSTALL_MOD_PATH: $INSTALL_MOD_PATH" ++ kerndir="$SD/BPI-BOOT" ++ fdtdir=$kerndir ++ if [[ "$board" == "bpi-r2pro" ]];then ++ mkdir -p $kerndir/extlinux/ ++ cp ${bindir}arch/arm64/boot/Image.gz $kerndir/extlinux/ ++ cp ./$board.dtb $kerndir/extlinux/$board.dtb ++ else ++ if [[ "$board" =~ bpi-r2|bpi-r64 ]];then ++ kerndir=$SD/BPI-BOOT/bananapi/$board/linux ++ fdtdir="$kerndir/dtb" ++ fi ++ for createDir in "$kerndir" "$fdtdir" "$SD/BPI-ROOT/lib/modules" "$SD/BPI-ROOT/lib/firmware"; do ++ mkdir -p ${createDir} >/dev/null 2>/dev/null ++ done ++ if [[ -e ./uImage ]];then ++ cp ./uImage $kerndir/uImage ++ fi ++ if [[ -e ./uImage_nodt ]];then ++ cp ./uImage_nodt $kerndir/uImage_nodt ++ cp ./$board.dtb $fdtdir/$board.dtb ++ fi ++ fi ++ if [[ -e ./$board.itb ]];then ++ cp ./$board.itb $kerndir/$board.itb ++ fi ++ make modules_install ++ ++ #Add CryptoDev Module if exists or Blacklist ++ CRYPTODEV="utils/cryptodev/cryptodev-linux/cryptodev.ko" ++ mkdir -p "${INSTALL_MOD_PATH}/etc/modules-load.d" ++ mkdir -p "${INSTALL_MOD_PATH}/etc/modprobe.d" ++ ++ LOCALVERSION=$(find ../SD/BPI-ROOT/lib/modules/* -maxdepth 0 -type d |rev|cut -d"/" -f1 | rev) ++ EXTRA_MODUL_PATH="${SD}/BPI-ROOT/lib/modules/${LOCALVERSION}/kernel/extras" ++ if [ -e "${CRYPTODEV}" ]; then ++ echo Copy CryptoDev ++ mkdir -p "${EXTRA_MODUL_PATH}" ++ cp "${CRYPTODEV}" "${EXTRA_MODUL_PATH}" ++ #Load Cryptodev on BOOT ++ echo "cryptodev" >${INSTALL_MOD_PATH}/etc/modules-load.d/cryptodev.conf ++ ++ #Build Module Dependencies ++ /sbin/depmod -b "${SD}/BPI-ROOT/" ${LOCALVERSION} ++ else ++ #Blacklist Cryptodev Module ++ echo "blacklist cryptodev" >${INSTALL_MOD_PATH}/etc/modprobe.d/cryptodev.conf ++ fi ++ ++ if [[ -n "$(grep 'CONFIG_MT76=' $DOTCONFIG)" ]];then ++ echo "MT76 set, including the firmware-files..."; ++ cp drivers/net/wireless/mediatek/mt76/firmware/* $SD/BPI-ROOT/lib/firmware/ ++ fi ++ ++ if [[ "$board" == "bpi-r64" ]];then ++ mkdir -p $SD/BPI-ROOT/lib/firmware/mediatek ++ cp utils/firmware/mediatek/mt7622* $SD/BPI-ROOT/lib/firmware/mediatek/ ++ fi ++} ++ ++function installchoice ++{ ++ if [ -e "./uImage" ] || [ -e "./uImage_nodt" ]; then ++ echo "===========================================" ++ echo "1) pack" ++ if [[ $crosscompile -eq 0 ]];then ++ echo "2) install to System" ++ else ++ echo "2) install to SD-Card" ++ fi; ++ echo "3) deb-package" ++ echo "4) upload" ++ read -n1 -p "choice [1234]:" choice ++ echo ++ if [[ "$choice" == "1" ]]; then ++ $0 pack ++ elif [[ "$choice" == "2" ]];then ++ $0 install ++ elif [[ "$choice" == "3" ]];then ++ $0 deb ++ elif [[ "$choice" == "4" ]];then ++ $0 upload ++ else ++ echo "wrong option: $choice" ++ fi ++ fi ++} ++ ++function release ++{ ++ lc=$(git log -n 1 --pretty=format:'%s') ++ reltag="Release_${kernver}" ++ if [[ ${lc} =~ ^Merge ]]; ++ then ++ echo Merge; ++ else ++ echo "normal commit"; ++ lc=${lc//[^a-zA-Z0-9]/_} ++ reltag="${reltag}_${lc}" ++ fi ++ echo "RelTag:"$reltag ++ if [[ -z "$(git tag -l $reltag)" ]]; then ++ git tag $reltag ++ git push origin $reltag ++ else ++ echo "Tag already used, please use another" ++ fi ++} ++ ++#Test if the Kernel is there ++if [ -n "$kernver" ]; then ++ action=$1 ++ file=$2 ++ LANG=C ++ CFLAGS=-j${numproc} ++ ++ #echo $action ++ ++ case "$action" in ++ "checkdep") ++ echo "checking depencies..." ++ check_dep "build"; ++ if [[ $? -eq 0 ]];then echo "OK";else echo "failed";fi ++ ;; ++ "changelog") ++ echo "print changelog from last release of branch" ++ changelog ++ ;; ++ "changelog_file") ++ echo "write changelog from last release of branch to file" ++ changelog > changelog.txt ++ ;; ++ "reset") ++ echo "Reset Git" ++ ##Reset Git ++ git reset --hard HEAD ++ #call self and Import Config ++ $0 importconfig ++ ;; ++ ++ "update") ++ echo "Update Git Repo" ++ git pull ++ ;; ++ ++ "updatesrc") ++ echo "Update kernel source" ++ update_kernel_source ++ ;; ++ ++ "mount") ++ mount | grep "BPI-BOOT" > /dev/null ++ if [[ $? -ne 0 ]];then ++ udisksctl mount -b /dev/disk/by-label/BPI-BOOT ++ fi ++ mount | grep "BPI-ROOT" > /dev/null ++ if [[ $? -ne 0 ]];then ++ udisksctl mount -b /dev/disk/by-label/BPI-ROOT ++ fi ++ ;; ++ ++ "umount") ++ echo "umount SD Media" ++ dev=$(mount | grep BPI-ROOT | head -1 | sed -e 's/[0-9] .*$/?/' | sort -u) ++ echo "$dev" ++ if [[ ! -z "$dev" ]];then ++ umount $dev ++ fi ++ ;; ++ ++ "uenv") ++ echo "edit uEnv.txt on sd-card" ++ uenv=$(getuenvpath) ++ if [[ -n "$uenv" ]];then ++ edit $uenv ++ else ++ echo "uenv.txt not found" ++ fi ++ ;; ++ ++ "lskernel") ++ echo "list kernels on sd-card" ++ ls -lh /media/$USER/BPI-BOOT/bananapi/$board/linux/ ++ echo "available DTBs:" ++ ls -lh /media/$USER/BPI-BOOT/bananapi/$board/linux/dtb ++ ;; ++ ++ "defconfig") ++ echo "edit def config" ++ edit $DEFCONFIG ++ ;; ++ "deb") ++ echo "deb-package (currently testing-state)" ++ deb ++ ;; ++ "dtsi") ++ edit $DTSI ++ ;; ++ ++ "dts") ++ edit $DTS ++ ;; ++ "dtbs_check") ++ make dtbs_check 2>&1 | tee -a dtbs_check.log ++ ;; ++ ++ "importmylconfig") ++ echo "import myl config" ++ make mt7623n_myl_defconfig ++ ;; ++ ++ ++ "importconfig") ++ echo "import a defconfig file" ++ if [[ -e "${DEFCONFIG}" ]];then ++ DEFCONF="${DEFCONFIG##*/}" ++ echo "import $DEFCONF ($DEFCONFIG)" ++ make ${DEFCONF} ++ if [[ -n "$disable" ]];then ++ disable_option "$disable" ++ fi ++ else ++ echo "file ${DEFCONFIG} not found" ++ fi ++ ;; ++ ++ "importfullconfig") ++ echo "import full config" ++ if [[ -e "${DEFCONFIG}" ]];then ++ tmpfile=${DEFCONFIG%/*}/temp_defconfig ++ cat $DEFCONFIG > ${tmpfile} ++ if [[ -e config_generic ]];then ++ echo "append generic config" ++ cat config_generic >> $tmpfile ++ fi ++ if [[ -e config_${board} ]];then ++ echo "append board config" ++ cat config_${board} >> $tmpfile ++ fi ++ make temp_defconfig ++ else ++ echo "file ${DEFCONFIG} not found" ++ fi ++ ;; ++ ++ "ic") ++ echo "menu for multiple conf-files...currently in developement" ++ files=(); ++ i=1; ++ if [[ "$board" == "bpi-r2pro" ]];then ++ p=arch/arm64/configs/ ++ ff=rk3568_bpi-r2p_defconfig ++ elif [[ "$board" == "bpi-r64" ]];then ++ p=arch/arm64/configs/ ++ ff="mt7622*defconfig" ++ else ++ p=arch/arm/configs/ ++ ff="mt7623n*defconfig" ++ fi ++ for f in $(cd $p; ls $ff) ++ do ++ echo "[$i] $f" ++ files+=($f) ++ i=$(($i+1)) ++ done ++ read -n1 -p "choice [1..${#files[@]}]:" choice ++ echo ++ set -x ++ make ${files[$(($choice-1))]} ++ set +x ++ ;; ++ "config") ++ echo "change kernel-configuration (menuconfig)" ++ make menuconfig ++ ;; ++ ++ "pack") ++ echo "Pack Kernel to Archive" ++ pack ++ ;; ++ ++ "pack_debs") ++ echo "Pack Kernel to linux-*.deb" ++ pack_debs ++ ;; ++ ++ "install") ++ echo "Install Kernel to SD Card" ++ install ++ ;; ++ ++ "upload") ++ echo "Upload Kernel to TFTP-Server" ++ upload ++ ;; ++ ++ "build") ++ echo "Build Kernel" ++ echo "building with ${numproc} threads" ++ time build ++ #$0 cryptodev ++ ;; ++ "clean") ++ echo clean ++ make clean ++ if [[ "$builddir" != "" ]];then ++ rm -r $builddir/debian || true; ++ else ++ rm -r debian || true; ++ fi ++ ;; ++ "spidev") ++ echo "Build SPIDEV-Test" ++ ( ++ cd tools/spi; ++ make ++ ) ++ ;; ++ ++ "cryptodev") ++ echo "Build CryptoDev" ++ cdbuildscript=utils/cryptodev/build.sh ++ if [[ -e $cdbuildscript ]];then ++ $cdbuildscript ++ fi ++ ;; ++ ++ "utils") ++ echo "Build utils" ++ ( cd utils; make ) ++ ;; ++ ++ "release") ++ echo "create release tag for travis-ci build" ++ release ++ ;; ++ "all-pack") ++ echo "update repo, create kernel & build archive" ++ $0 update ++ $0 importconfig ++ $0 build ++ #$0 cryptodev ++ $0 pack ++ ;; ++ "install_modules") ++ install_modules ++ ;; ++ "mod2initrd") ++ mod2initrd ++ ;; ++ "help") ++ echo "print help" ++ sed -n -e '/case "$action" in/,/esac/{//!p}' $0 | grep -A1 '")$' | sed -e 's/echo "\(.*\)"/\1/' ++ ;; ++ *) ++ if [[ -n "$action" ]];then ++ echo "unknown command $action"; ++ exit 1; ++ fi; ++ $0 build ++ #$0 cryptodev ++ installchoice ++ ;; ++ esac ++fi +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0007-build.sh-add-additional-build-script-config-defconfi.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0007-build.sh-add-additional-build-script-config-defconfi.patch new file mode 100644 index 000000000..ac2910f3a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0007-build.sh-add-additional-build-script-config-defconfi.patch @@ -0,0 +1,3796 @@ +From 162c49815bc0911957610b77dbdb8fc82fa0c659 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 1 Feb 2025 14:49:06 +0100 +Subject: [PATCH 07/84] build.sh: add additional build-script,config, + defconfigs and fit sources + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 732 +++++++++++ + arch/arm64/configs/mt7622_bpi-r64_defconfig | 523 ++++++++ + arch/arm64/configs/mt7986a_bpi-r3_defconfig | 1265 +++++++++++++++++++ + arch/arm64/configs/quartz64_defconfig | 922 ++++++++++++++ + bpi-r2pro.its | 55 + + bpi-r3.its | 162 +++ + bpi-r64.its | 55 + + build.conf | 2 +- + 8 files changed, 3715 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/configs/mt7623n_evb_fwu_defconfig + create mode 100644 arch/arm64/configs/mt7622_bpi-r64_defconfig + create mode 100644 arch/arm64/configs/mt7986a_bpi-r3_defconfig + create mode 100644 arch/arm64/configs/quartz64_defconfig + create mode 100644 bpi-r2pro.its + create mode 100644 bpi-r3.its + create mode 100644 bpi-r64.its + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +new file mode 100644 +index 000000000000..be9e0b2a691b +--- /dev/null ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -0,0 +1,732 @@ ++CONFIG_LOCALVERSION="-bpi-r2" ++CONFIG_LOCALVERSION_AUTO=n ++ ++CONFIG_EARLY_PRINTK=y ++ ++#spectre/meltdown ++CONFIG_PAGE_TABLE_ISOLATION=y ++ ++CONFIG_SYSVIPC=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_CGROUPS=y ++CONFIG_NAMESPACES=y ++ ++#for lxc ++CONFIG_USER_NS=y ++CONFIG_MEMCG=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CPUSETS=y ++#some options for docker ++CONFIG_CGROUP_FREEZER=y ++CONFIG_OVERLAY_FS=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_MEMCG_SWAP_ENABLED=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CFS_BANDWIDTH=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++ ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_KALLSYMS_ALL=y ++CONFIG_EMBEDDED=y ++CONFIG_PERF_EVENTS=y ++CONFIG_MODULES=y ++CONFIG_MODULE_FORCE_LOAD=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_CMDLINE_PARTITION=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_ARM_THUMB=y ++CONFIG_ARM_THUMBEE=y ++CONFIG_ARM_ERRATA_720789=y ++CONFIG_ARM_ERRATA_754322=y ++CONFIG_ARM_ERRATA_754327=y ++CONFIG_ARM_ERRATA_764369=y ++CONFIG_ARM_ERRATA_775420=y ++CONFIG_ARM_ERRATA_798181=y ++ ++CONFIG_PL310_ERRATA_588369=y ++CONFIG_PL310_ERRATA_727915=y ++CONFIG_PL310_ERRATA_753970=y ++CONFIG_PL310_ERRATA_769419=y ++ ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_SMP=y ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_NR_CPUS=16 ++CONFIG_AEABI=y ++CONFIG_HIGHMEM=y ++CONFIG_CMA=y ++CONFIG_FORCE_MAX_ZONEORDER=12 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=496M debug=7 no_console_suspend" ++#CONFIG_CMDLINE_FORCE=y ++ ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++ ++CONFIG_KEXEC=y ++ ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++ ++CONFIG_VFP=y ++CONFIG_NEON=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_PM_AUTOSLEEP=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_ADVANCED_DEBUG=y ++CONFIG_APM_EMULATION=y ++ ++CONFIG_NET=y ++CONFIG_DUMMY=m ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_MIP6=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_BRIDGE=y ++CONFIG_NET_DSA=y ++CONFIG_VLAN_8021Q=y ++CONFIG_NETLINK_DIAG=y ++CONFIG_INET_UDP_DIAG=m ++CONFIG_NET_IPIP=m ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++ ++#added for lxc ++CONFIG_UNIX_DIAG=m ++CONFIG_PACKET_DIAG=m ++ ++#added for docker ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_SECCOMP=y ++ ++CONFIG_IPV6=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_NETFILTER_NETLINK=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV6=m ++CONFIG_NF_REJECT_IPV6=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MATCH_RT=m ++ ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP6_NF_TARGET_SYNPROXY=m ++ ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_IP_VS=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++ ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NF_TPROXY_IPV4=m ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_TPROXY_IPV6=m ++CONFIG_NF_TABLES_BRIDGE=m ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_XFRM=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_SYNPROXY=m ++CONFIG_NFTL=m ++CONFIG_NFTL_RW=y ++ ++CONFIG_NF_FLOW_TABLE=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NF_FLOW_TABLE_IPV6=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++ ++CONFIG_NET_MEDIATEK_HNAT=m ++CONFIG_DEBUG_SECTION_MISMATCH=y ++ ++#active ftp-support ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_NAT_FTP=m ++ ++ ++CONFIG_SYN_COOKIES=y ++ ++CONFIG_PPP=m ++CONFIG_PPPOE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_MPPE=m ++ ++#veth for lxc ++CONFIG_VETH=m ++ ++#for systemd ++CONFIG_AF_KCM=y ++CONFIG_CGROUP_BPF=y ++ ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=64 ++CONFIG_ARM_CCI400_PMU=y ++CONFIG_MTD=y ++CONFIG_OF_OVERLAY=y ++CONFIG_CONFIGFS_FS=m ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_SRAM=y ++CONFIG_EEPROM_93CX6=y ++CONFIG_IDE=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_ATA=y ++CONFIG_SATA_AHCI=y ++CONFIG_AHCI_MTK=m ++ ++CONFIG_NETDEVICES=y ++CONFIG_NET_DSA_MT7530=y ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NET_MEDIATEK_SOC=y ++ ++CONFIG_ICPLUS_PHY=y ++CONFIG_INPUT_EVDEV=y ++#CONFIG_INPUT_EVBUG=m ++CONFIG_KEYBOARD_MATRIX=y ++CONFIG_KEYBOARD_SAMSUNG=y ++CONFIG_KEYBOARD_MTK_PMIC=m ++CONFIG_MOUSE_PS2_ELANTECH=y ++CONFIG_MOUSE_PS2_SENTELIC=y ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_SERIO_SERPORT is not set ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=4 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=4 ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_8250_BTIF=y ++CONFIG_HW_RANDOM=y ++CONFIG_I2C=y ++CONFIG_I2C_MT65XX=y ++CONFIG_PINCTRL_MT2701=y ++# CONFIG_PINCTRL_MT6397 is not set ++CONFIG_WATCHDOG=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_MFD_MT6397=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_MT6323=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_RC_CORE=y ++CONFIG_RC_DEVICES=y ++CONFIG_LIRC=y ++CONFIG_IR_MTK=y ++CONFIG_RC_DECODERS=y ++CONFIG_IR_NEC_DECODER=m ++CONFIG_IR_RC5_DECODER=m ++CONFIG_IR_RC6_DECODER=m ++CONFIG_IR_JVC_DECODER=m ++CONFIG_IR_SONY_DECODER=m ++CONFIG_IR_SHARP_DECODER=m ++CONFIG_IR_SANYO_DECODER=m ++CONFIG_IR_RCMM_DECODER=m ++CONFIG_IR_XMP_DECODER=m ++CONFIG_MMC=y ++CONFIG_MMC_MTK=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_MT6323=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_DMADEVICES=y ++CONFIG_DMATEST=m ++CONFIG_COMMON_CLK_MT2701_HIFSYS=y ++CONFIG_COMMON_CLK_MT2701_ETHSYS=y ++CONFIG_ARM_TIMER_SP804=y ++CONFIG_MTK_IOMMU_V1=y ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_IIO=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_PHY_MT65XX_USB3=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_PMSG=y ++CONFIG_PSTORE_FTRACE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_DEBUG_INFO=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_DEBUG_LIST=y ++CONFIG_FUNCTION_TRACER=y ++CONFIG_FTRACE_SYSCALLS=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_DEBUG_LL=y ++CONFIG_DEBUG_UART_PHYS=0x11002000 ++CONFIG_DEBUG_UART_VIRT=0xf1002000 ++CONFIG_KEYS=y ++CONFIG_CRYPTO_RSA=y ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_CMAC=m ++CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++CONFIG_CRC_CCITT=m ++CONFIG_CRC_ITU_T=m ++CONFIG_CRYPTO_DEV_MEDIATEK=y ++ ++#ARM Accelerated Cryptographic Algorithms ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_SHA1_ARM_CE=m ++CONFIG_CRYPTO_SHA2_ARM_CE=m ++CONFIG_CRYPTO_SHA512_ARM=m ++CONFIG_CRYPTO_AES_ARM=m ++CONFIG_CRYPTO_AES_ARM_BS=m ++CONFIG_CRYPTO_AES_ARM_CE=m ++CONFIG_CRYPTO_GHASH_ARM_CE=m ++CONFIG_CRYPTO_CRC32_ARM_CE=m ++CONFIG_CRYPTO_CHACHA20_NEON=m ++ ++#LVM ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_BUFIO=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_SNAPSHOT=y ++CONFIG_DM_MIRROR=y ++CONFIG_DM_MULTIPATH=y ++CONFIG_DM_MULTIPATH_QL=y ++CONFIG_DM_MULTIPATH_ST=y ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DAX=y ++CONFIG_CRYPTO_CBC=y ++ ++#RAID ++CONFIG_DM_RAID=y ++CONFIG_MD_RAID0=y ++CONFIG_MD_RAID1=y ++CONFIG_MD_RAID10=y ++CONFIG_MD_RAID456=y ++ ++#RamFS ++#CONFIG_INITRAMFS_SOURCE="../rootfs_ttys0_rng.cpio.gz" ++#CONFIG_INITRAMFS_SOURCE="../initramfs.cpio" ++#CONFIG_INITRAMFS_FORCE=y ++ ++#Filesystem ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_MSDOS_FS=m ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_UTF8=y ++CONFIG_CIFS=m ++CONFIG_F2FS_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_SQUASHFS=m ++ ++#GPIO ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++ ++#wlan ++CONFIG_MAC80211=y ++CONFIG_MAC80211_MESH=y ++CONFIG_CFG80211=m ++ ++#internal wlan (not working yet) ++# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set ++CONFIG_MTK_COMBO=y ++CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y ++#used in 4.4, but should be set in Kconfig by selecting mt7623 COMBO ++#CONFIG_MTK_PLATFORM="mt7623" ++ ++CONFIG_MTK_COMBO_COMM=y ++CONFIG_MTK_COMBO_WIFI=y ++CONFIG_NL80211_TESTMODE=y ++ ++#internal Bluetooth (also not working yet) ++CONFIG_BT=y ++CONFIG_MTK_COMBO_BT=m ++CONFIG_MTK_COMBO_BT_HCI=y ++#needed for BT? ++#Bluetooth Classic (BR/EDR) features ++CONFIG_BT_BREDR=y ++#Bluetooth High Speed (HS) features ++CONFIG_BT_HS=y ++#Bluetooth Low Energy (LE) features ++CONFIG_BT_LE=y ++#Export Bluetooth internals in debugfs ++CONFIG_BT_DEBUGFS=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_BNEP=m ++ ++#to run bluetoothd rfkill needed ++CONFIG_RFKILL=y ++CONFIG_RFKILL_LEDS=y ++CONFIG_RFKILL_INPUT=y ++CONFIG_RFKILL_GPIO=y ++ ++#if you use a mt76x2 or mt76x3 pcie-card ++CONFIG_MT76x2E=m ++CONFIG_MT7615E=m ++CONFIG_MT7915E=m ++ ++#pcie ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PHY_MTK_TPHY=y ++ ++CONFIG_I2C_CHARDEV=m ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1307_CENTURY=y ++CONFIG_RTC_DRV_MT6397=y ++ ++CONFIG_SPI=y ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_SPIDEV=m ++CONFIG_SPI_MT65XX=m ++ ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=m ++ ++#Temperature sensor driver for mediatek SoCs ++CONFIG_MEDIATEK_MT6577_AUXADC=y ++CONFIG_THERMAL=y ++CONFIG_MTK_THERMAL=y ++CONFIG_MTK_EFUSE=y ++CONFIG_HWMON=y ++CONFIG_THERMAL_HWMON=y ++CONFIG_CPU_THERMAL=y ++ ++#HDMI ++CONFIG_DRM=y ++CONFIG_DRM_ARM=y ++CONFIG_DRM_MALI_DISPLAY=y ++CONFIG_DRM_MEDIATEK=y ++CONFIG_DRM_MEDIATEK_HDMI=y ++CONFIG_COMMON_CLK_MT2701_MMSYS=y ++CONFIG_COMMON_CLK_MT2701_IMGSYS=y ++CONFIG_COMMON_CLK_MT2701_VDECSYS=y ++CONFIG_FB=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_DRM_FBDEV_EMULATION=y ++ ++#mali ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++CONFIG_V4L_MEM2MEM_DRIVERS=y ++CONFIG_VIDEO_MEDIATEK_JPEG=y ++CONFIG_DRM_LIMA=m ++CONFIG_COMMON_CLK_MT2701_G3DSYS=y ++ ++#Sound ++CONFIG_SOUND=y ++CONFIG_SND=y #alsa core ++CONFIG_SND_SOC=y ++ ++#CONFIG_SOUND_OSS_CORE=y ++#CONFIG_SOUND_OSS_CORE_PRECLAIM=y ++#CONFIG_SND_OSSEMUL=y ++#CONFIG_SND_MIXER_OSS=m ++#CONFIG_SND_PCM_OSS=m #alsa The PCM OSS emulation module. ++ ++#USB/HID ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_SERIAL=y ++#CONFIG_NOP_USB_XCEIV=y ++#CONFIG_USB_GPIO_VBUS=y ++#CONFIG_USB_GADGET=y ++#CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_SERIAL=y ++#CONFIG_USB_CONFIGFS_ACM=y ++#CONFIG_USB_CONFIGFS_OBEX=y ++#CONFIG_USB_CONFIGFS_NCM=y ++#CONFIG_USB_CONFIGFS_ECM=y ++#CONFIG_USB_CONFIGFS_ECM_SUBSET=y ++#CONFIG_USB_CONFIGFS_RNDIS=y ++#CONFIG_USB_CONFIGFS_EEM=y ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++ ++CONFIG_HID=y ++CONFIG_HIDRAW=y ++#CONFIG_UHID=m ++CONFIG_HID_GENERIC=y ++ ++CONFIG_USB_HID=y ++#CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++ ++# CONFIG_USB_OHCI_LITTLE_ENDIAN=y ? ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++# CONFIG_USB_ARCH_HAS_HCD=y ? ++ ++#additional NET (e.g. tunneling incl. openvpn,vlan-base-support) ++CONFIG_TUN=m ++#vlan ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_NET_L3_MASTER_DEV=y ++CONFIG_IPVLAN=m ++CONFIG_MACVLAN=m ++CONFIG_NET_ACT_VLAN=m ++CONFIG_NET_CLS_ACT=y ++ ++# QoS and/or fair queueing ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_CSZ=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_INGRESS=m ++#CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_QOS=y ++CONFIG_NET_ESTIMATOR=y ++CONFIG_NET_CLS=y ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_ROUTE=y ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_POLICE=y ++ ++#unused drivers which are set by default ++CONFIG_WLAN_VENDOR_ADMTEK=n ++CONFIG_WLAN_VENDOR_ATH=y ++CONFIG_ATH9K=m ++CONFIG_ATH10K=m ++CONFIG_ATH10K_PCI=m ++CONFIG_ATH10K_USB=m ++CONFIG_WLAN_VENDOR_ATMEL=n ++CONFIG_WLAN_VENDOR_BROADCOM=n ++CONFIG_WLAN_VENDOR_CISCO=n ++CONFIG_WLAN_VENDOR_INTEL=n ++CONFIG_WLAN_VENDOR_INTERSIL=n ++CONFIG_WLAN_VENDOR_MARVELL=n ++CONFIG_WLAN_VENDOR_REALTEK=n ++CONFIG_WLAN_VENDOR_RALINK=n ++CONFIG_WLAN_VENDOR_RSI=n ++CONFIG_WLAN_VENDOR_ST=n ++CONFIG_WLAN_VENDOR_TI=n ++CONFIG_WLAN_VENDOR_ZYDAS=n ++CONFIG_WLAN_VENDOR_QUANTENNA=n ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++# CONFIG_NET_VENDOR_ALACRITECH is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_AQUANTIA is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_NET_PACKET_ENGINE is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_REALTEK is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_RDC is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SOLARFLARE is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_EXAR is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_HP is not set ++# CONFIG_NET_VENDOR_HUAWEI is not set ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_3COM is not set ++ ++#NFS Client ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_PNFS_FILE_LAYOUT=m ++CONFIG_PNFS_BLOCK=m ++CONFIG_PNFS_FLEXFILE_LAYOUT=m ++CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" ++CONFIG_NFS_V4_1_MIGRATION=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++ ++#NFS Server ++CONFIG_NFSD=m ++CONFIG_NFSD_V2_ACL=y ++CONFIG_NFSD_V3=y ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_NFSD_PNFS=y ++CONFIG_NFSD_BLOCKLAYOUT=y ++CONFIG_NFSD_SCSILAYOUT=y ++CONFIG_NFSD_FLEXFILELAYOUT=y ++CONFIG_NFSD_FAULT_INJECTION=y ++CONFIG_NFS_ACL_SUPPORT=m ++CONFIG_NFS_COMMON=y ++ ++CONFIG_ROOT_NFS=y ++ ++#xfs ++CONFIG_XFS_FS=m ++ ++#RTC/POWER ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_MT6323=y ++CONFIG_POWER_RESET_MT6397_RTC=y ++ ++#CONFIG_NET_MEDIATEK_HW_QOS=m ++ +diff --git a/arch/arm64/configs/mt7622_bpi-r64_defconfig b/arch/arm64/configs/mt7622_bpi-r64_defconfig +new file mode 100644 +index 000000000000..72359b09879a +--- /dev/null ++++ b/arch/arm64/configs/mt7622_bpi-r64_defconfig +@@ -0,0 +1,523 @@ ++CONFIG_LOCALVERSION="-bpi-r64" ++CONFIG_LOCALVERSION_AUTO=n ++ ++#CONFIG_COMPILE_TEST=y ++CONFIG_DEFAULT_HOSTNAME="(mt7622)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++# CONFIG_CROSS_MEMORY_ATTACH is not set ++CONFIG_AUDIT=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUPS=y ++# CONFIG_UTS_NS is not set ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_PERF_EVENTS=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_IOSCHED_DEADLINE is not set ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_PCI=y ++CONFIG_PCI_DEBUG=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_SCHED_MC=y ++CONFIG_NR_CPUS=2 ++CONFIG_PREEMPT=y ++# CONFIG_COMPACTION is not set ++# CONFIG_EFI is not set ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_COMPAT=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++CONFIG_SYNC_FILE=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_UNIX_DIAG=y ++CONFIG_PACKET_DIAG=m ++CONFIG_INET=y ++CONFIG_DUMMY=m ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_MIP6=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_NETLINK_DIAG=y ++CONFIG_INET_UDP_DIAG=m ++CONFIG_NET_IPIP=m ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++ ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++CONFIG_RFKILL=m ++ ++CONFIG_BT=y ++CONFIG_BT_RFCOMM=y ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=y ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=y ++# CONFIG_BT_HS is not set ++# CONFIG_BT_LE is not set ++CONFIG_BT_HCIVHCI=y ++CONFIG_BT_MTKUART=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_MTD=y ++# CONFIG_MTD_OF_PARTS is not set ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_MTK=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_MT81xx_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_BLK_DEV is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_ATA=y ++CONFIG_AHCI_MTK=y ++CONFIG_NETDEVICES=y ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++# CONFIG_NET_VENDOR_ALACRITECH is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_AQUANTIA is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_EXAR is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_HP is not set ++# CONFIG_NET_VENDOR_HUAWEI is not set ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NET_MEDIATEK_SOC=y ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_NET_PACKET_ENGINE is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_REALTEK is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_RDC is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SOLARFLARE is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++CONFIG_ICPLUS_PHY=y ++CONFIG_USB_CATC=y ++CONFIG_USB_KAWETH=y ++CONFIG_USB_PEGASUS=y ++CONFIG_USB_RTL8150=y ++CONFIG_USB_RTL8152=y ++CONFIG_USB_LAN78XX=y ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_CDC_EEM=y ++CONFIG_USB_NET_HUAWEI_CDC_NCM=y ++CONFIG_USB_NET_CDC_MBIM=y ++CONFIG_USB_NET_DM9601=y ++CONFIG_USB_NET_SR9700=y ++CONFIG_USB_NET_SR9800=y ++CONFIG_USB_NET_SMSC75XX=y ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=y ++CONFIG_USB_NET_PLUSB=y ++CONFIG_USB_NET_MCS7830=y ++CONFIG_USB_NET_RNDIS_HOST=y ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_CX82310_ETH=y ++CONFIG_USB_NET_KALMIA=y ++CONFIG_USB_NET_QMI_WWAN=y ++CONFIG_USB_NET_INT51X1=y ++CONFIG_USB_IPHETH=y ++CONFIG_USB_SIERRA_NET=y ++CONFIG_USB_VL600=y ++CONFIG_USB_NET_CH9200=y ++CONFIG_INPUT_POLLDEV=y ++CONFIG_INPUT_EVDEV=y ++#CONFIG_INPUT_EVBUG=y ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=y ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_SERIO_LIBPS2=y ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_LEGACY_PTY_COUNT=16 ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_HW_RANDOM=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MT65XX=y ++CONFIG_I2C_SLAVE=y ++CONFIG_I2C_DEBUG_CORE=y ++CONFIG_I2C_DEBUG_ALGO=y ++CONFIG_I2C_DEBUG_BUS=y ++CONFIG_SPI=y ++CONFIG_SPI_MT65XX=y ++CONFIG_PINCTRL_MT2701=y ++CONFIG_PINCTRL_MT8135=y ++CONFIG_PINCTRL_MT8127=y ++CONFIG_PINCTRL_MT7622=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_THERMAL=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_BANG_BANG=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CLOCK_THERMAL=y ++CONFIG_THERMAL_EMULATION=y ++CONFIG_HWMON=y ++CONFIG_THERMAL_HWMON=y ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_SYSFS=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y ++CONFIG_MFD_MT6397=y ++# CONFIG_ABX500_CORE is not set ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_MT6323=y ++CONFIG_REGULATOR_MT6380=y ++#CONFIG_RC_CORE=y ++CONFIG_RC_DEVICES=y ++CONFIG_IR_MTK=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_USB=y ++# CONFIG_USB_PCI is not set ++# CONFIG_USB_DEFAULT_PERSIST is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_USB_STORAGE=y ++CONFIG_MMC=y ++CONFIG_MMC_MTK=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_USER=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++#CONFIG_LEDS_TRIGGER_ACTIVITY=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_GPIO=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_MT7622=y ++CONFIG_DMADEVICES=y ++CONFIG_MTK_HSDMA=y ++CONFIG_DMATEST=y ++# CONFIG_COMMON_CLK_XGENE is not set ++# CONFIG_COMMON_CLK_MT6797 is not set ++CONFIG_COMMON_CLK_MT7622_ETHSYS=y ++CONFIG_COMMON_CLK_MT7622_HIFSYS=y ++CONFIG_COMMON_CLK_MT7622_AUDSYS=y ++# CONFIG_COMMON_CLK_MT8173 is not set ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_IIO=y ++CONFIG_MEDIATEK_MT6577_AUXADC=y ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_NVMEM_MTK_EFUSE=y ++CONFIG_EXT4_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_PRINTK_TIME=y ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 ++CONFIG_DYNAMIC_DEBUG=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_SECTION_MISMATCH=y ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_KERNEL=y ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_ECHAINIV=y ++CONFIG_CRYPTO_CRC32=y ++CONFIG_CRYPTO_CRC32C=y ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++ ++#for lxc ++CONFIG_USER_NS=y ++CONFIG_MEMCG=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CPUSETS=y ++#some options for docker ++CONFIG_CGROUP_FREEZER=y ++CONFIG_OVERLAY_FS=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_MEMCG_SWAP_ENABLED=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CFS_BANDWIDTH=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++ ++#added for docker ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_SECCOMP=y ++ ++CONFIG_GPIO_SYSFS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++ ++#IP / net ++CONFIG_IPV6=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_NETFILTER_NETLINK=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV6=m ++CONFIG_NF_REJECT_IPV6=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MATCH_RT=m ++ ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP6_NF_TARGET_SYNPROXY=m ++ ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_IP_VS=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++ ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NF_TPROXY_IPV4=m ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_TPROXY_IPV6=m ++CONFIG_NF_TABLES_BRIDGE=m ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_XFRM=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_SYNPROXY=m ++CONFIG_NFTL=m ++CONFIG_NFTL_RW=y ++ ++CONFIG_NF_FLOW_TABLE=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NF_FLOW_TABLE_IPV6=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++ ++ ++#active ftp-support ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_NAT_FTP=m ++ ++CONFIG_SYN_COOKIES=y ++ ++CONFIG_PPP=m ++CONFIG_PPPOE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_MPPE=m ++ ++#veth for lxc ++CONFIG_VETH=m ++ ++ ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_MT7615E=m ++CONFIG_MT7915E=m ++CONFIG_MT7622=m ++ ++CONFIG_NET_DSA=y ++CONFIG_NET_DSA_MT7530=y ++ ++#NFS Client ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_PNFS_FILE_LAYOUT=m ++CONFIG_PNFS_BLOCK=m ++CONFIG_PNFS_FLEXFILE_LAYOUT=m ++CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" ++CONFIG_NFS_V4_1_MIGRATION=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++ ++#NFS Server ++CONFIG_NFSD=m ++CONFIG_NFSD_V2_ACL=y ++CONFIG_NFSD_V3=y ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_NFSD_PNFS=y ++CONFIG_NFSD_BLOCKLAYOUT=y ++CONFIG_NFSD_SCSILAYOUT=y ++CONFIG_NFSD_FLEXFILELAYOUT=y ++CONFIG_NFSD_FAULT_INJECTION=y ++CONFIG_NFS_ACL_SUPPORT=m ++CONFIG_NFS_COMMON=y ++ ++CONFIG_ROOT_NFS=y ++ ++#xfs ++CONFIG_XFS_FS=m ++ ++#pstore/ramoops ++CONFIG_CPU_IDLE=y ++CONFIG_ARM_PSCI_CPUIDLE=y ++CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y ++CONFIG_MISC_FILESYSTEMS=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_COMPRESS=n ++#CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" ++CONFIG_PSTORE_CONSOLE=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y ++CONFIG_PSTORE_PMSG=y ++CONFIG_PSTORE_RAM=y ++ ++#CONFIG_BLK_DEV_INITRD=y ++#CONFIG_INITRAMFS_SOURCE="../buildroot/arm64_rootfs.cpio" ++CONFIG_SENSORS_PWM_FAN=m ++ ++#reduced phy driver ++#CONFIG_NET_REALTEK_MDIO=y ++ ++#real dsa driver ++#CONFIG_NET_DSA_REALTEK=y ++ ++#thermal since 6.3 ++CONFIG_MTK_THERMAL=y ++CONFIG_MTK_SOC_THERMAL=y ++ ++CONFIG_PANIC_TIMEOUT=30 +diff --git a/arch/arm64/configs/mt7986a_bpi-r3_defconfig b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +new file mode 100644 +index 000000000000..fccecc3b2375 +--- /dev/null ++++ b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +@@ -0,0 +1,1265 @@ ++CONFIG_LOCALVERSION="-bpi-r3" ++CONFIG_LOCALVERSION_AUTO=n ++ ++CONFIG_32BIT=y ++CONFIG_64BIT_TIME=y ++CONFIG_ADVISE_SYSCALLS=y ++CONFIG_AEABI=y ++CONFIG_AF_UNIX_OOB=y ++CONFIG_AIO=y ++CONFIG_ALLOW_DEV_COREDUMP=y ++CONFIG_ANON_INODES=y ++CONFIG_ARCH_BINFMT_ELF_STATE=y ++CONFIG_ARCH_FLATMEM_ENABLE=y ++CONFIG_ARM64_SW_TTBR0_PAN=y ++CONFIG_ARM_CPU_TOPOLOGY=y ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++CONFIG_ARM_GIC_MAX_NR=1 ++CONFIG_ATAGS_PROC=y ++CONFIG_ATA_BMDMA=y ++CONFIG_ATA_SFF=y ++CONFIG_ATM_BR2684_IPFILTER=y ++CONFIG_ATM_CLIP_NO_ICMP=y ++CONFIG_BASE_FULL=y ++CONFIG_BASE_SMALL=0 ++CONFIG_BCMA_POSSIBLE=y ++CONFIG_BINARY_PRINTF=y ++CONFIG_BINFMT_ELF=y ++CONFIG_BINFMT_SCRIPT=y ++CONFIG_BITREVERSE=y ++CONFIG_BLK_DEV=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 ++CONFIG_BLOCK=y ++CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 ++CONFIG_BOOT_RAW=y ++CONFIG_BPF=y ++CONFIG_BPF_JIT=y ++CONFIG_BPF_JIT_DEFAULT_ON=y ++CONFIG_BPF_SYSCALL=y ++CONFIG_BPF_UNPRIV_DEFAULT_OFF=y ++CONFIG_BQL=y ++CONFIG_BRANCH_PROFILE_NONE=y ++CONFIG_BRIDGE=y ++CONFIG_BRIDGE_IGMP_SNOOPING=y ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HCIUART_BCSP=y ++CONFIG_BT_HCIUART_H4=y ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BUG=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++CONFIG_BUILDTIME_TABLE_SORT=y ++CONFIG_BUILD_SALT="" ++CONFIG_CACHE_L2X0_PMU=y ++CONFIG_CARDBUS=y ++CONFIG_CC_CAN_LINK=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_CLS_U32_MARK=y ++CONFIG_CMDLINE="" ++CONFIG_COMPACTION=y ++#CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 ++CONFIG_CONSOLE_LOGLEVEL_QUIET=4 ++CONFIG_CONSTRUCTORS=y ++CONFIG_CPU_LITTLE_ENDIAN=y ++CONFIG_CPU_SW_DOMAIN_PAN=y ++CONFIG_CRAMFS_BLOCKDEV=y ++CONFIG_CRC32=y ++CONFIG_CRC32_SARWATE=y ++CONFIG_CROSS_COMPILE="" ++CONFIG_CRYPTO=y ++CONFIG_CRYPTO_ACOMP2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AES=y ++CONFIG_CRYPTO_AKCIPHER=y ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_CCM=y ++CONFIG_CRYPTO_CTR=y ++CONFIG_CRYPTO_GCM=y ++CONFIG_CRYPTO_GF128MUL=y ++CONFIG_CRYPTO_GHASH=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_KPP=y ++CONFIG_CRYPTO_KPP2=y ++CONFIG_CRYPTO_LIB_AES=y ++CONFIG_CRYPTO_LIB_ARC4=y ++CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_NULL=y ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_PCRYPT=y ++CONFIG_CRYPTO_SKCIPHER=y ++CONFIG_CRYPTO_SKCIPHER2=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_FS_ALLOW_ALL=y ++CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y ++CONFIG_DEBUG_KERNEL=y ++CONFIG_DEFAULT_CUBIC=y ++CONFIG_DEFAULT_DEADLINE=y ++CONFIG_DEFAULT_FQ_CODEL=y ++CONFIG_DEFAULT_HOSTNAME="(none)" ++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 ++CONFIG_DEFAULT_INIT="" ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_DEFAULT_NET_SCH="fq_codel" ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_DEVPORT=y ++CONFIG_DMA_COHERENT_POOL=y ++CONFIG_DMA_DECLARE_COHERENT=y ++CONFIG_DMA_NONCOHERENT_MMAP=y ++CONFIG_DOUBLEFAULT=y ++CONFIG_DQL=y ++CONFIG_DUMMY_CONSOLE_COLUMNS=80 ++CONFIG_DUMMY_CONSOLE_ROWS=25 ++CONFIG_DVB_MAX_ADAPTERS=16 ++CONFIG_DYNAMIC_DEBUG_CORE=y ++CONFIG_EFI_PARTITION=y ++CONFIG_ELFCORE=y ++CONFIG_EMBEDDED=y ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_EPOLL=y ++CONFIG_ETHERNET=y ++CONFIG_ETHTOOL_NETLINK=y ++CONFIG_EVENTFD=y ++CONFIG_EXPERT=y ++CONFIG_EXPORTFS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++CONFIG_EXTRA_TARGETS="" ++CONFIG_F2FS_FS_XATTR=y ++CONFIG_F2FS_STAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++CONFIG_FB_NOTIFY=y ++CONFIG_FIB_RULES=y ++CONFIG_FILE_LOCKING=y ++CONFIG_FLATMEM=y ++CONFIG_FLATMEM_MANUAL=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_FORTIFY_SOURCE=y ++CONFIG_FRAME_WARN=1024 ++CONFIG_FSNOTIFY=y ++CONFIG_FUTEX=y ++CONFIG_FUTEX_PI=y ++CONFIG_FW_LOADER=y ++CONFIG_FW_LOADER_USER_HELPER=y ++CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++CONFIG_GACT_PROB=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_IRQ_IPI=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PTDUMP=y ++CONFIG_GENERIC_VDSO_TIME_NS=y ++CONFIG_GPIOLIB_FASTPATH_LIMIT=512 ++CONFIG_GPIO_SYSFS=y ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_HARDEN_BRANCH_HISTORY=y ++CONFIG_HARDEN_EL2_VECTORS=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_HPET_MMAP_DEFAULT=y ++CONFIG_HW_PERF_EVENTS=y ++CONFIG_HW_RANDOM_TPM=y ++CONFIG_HZ=100 ++CONFIG_HZ_100=y ++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 ++CONFIG_INET=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_INIT_STACK_NONE=y ++CONFIG_INOTIFY_USER=y ++CONFIG_INPUT_MISC=y ++CONFIG_IO_STRICT_DEVMEM=y ++CONFIG_IO_WQ=y ++CONFIG_IPV6_NDISC_NODETYPE=y ++CONFIG_IPW2100_MONITOR=y ++CONFIG_IPW2200_MONITOR=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_VS_MH_TAB_INDEX=10 ++CONFIG_ISDN=y ++CONFIG_JFFS2_CMODE_PRIORITY=y ++CONFIG_JFFS2_COMPRESSION_OPTIONS=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++CONFIG_JFFS2_FS_XATTR=y ++CONFIG_JFFS2_LZMA=y ++CONFIG_JFFS2_RTIME=y ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_JOLIET=y ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_KASAN_STACK=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_KERNEL_XZ=y ++CONFIG_KERNFS=y ++CONFIG_KUSER_HELPERS=y ++CONFIG_LBDAF=y ++CONFIG_LDISC_AUTOLOAD=y ++CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y ++CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_CLASS_MULTICOLOR=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_NETDEV=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LINEAR_RANGES=y ++CONFIG_LLC=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_LOCKD_V4=y ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 ++CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" ++CONFIG_LSM_MMAP_MIN_ADDR=65536 ++CONFIG_LTO_NONE=y ++CONFIG_LZMA_COMPRESS=y ++CONFIG_LZMA_DECOMPRESS=y ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 ++CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_MEMBARRIER=y ++#CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++CONFIG_MII=y ++CONFIG_MISC_FILESYSTEMS=y ++CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y ++CONFIG_MMC_BLOCK_BOUNCE=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMU=y ++CONFIG_MMU_GATHER_RCU_TABLE_FREE=y ++CONFIG_MMU_GATHER_TABLE_FREE=y ++CONFIG_MODPROBE_PATH="/sbin/modprobe" ++CONFIG_MODULES=y ++CONFIG_MODULE_COMPRESS_NONE=y ++CONFIG_MODULE_STRIPPED=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MSDOS_PARTITION=y ++CONFIG_MTD=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_NOSWAP=y ++CONFIG_MTD_CFI_UTIL=y ++CONFIG_MTD_COMPLEX_MAPPINGS=y ++CONFIG_MTD_GEN_PROBE=y ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 ++CONFIG_MTD_NAND_IDS=y ++CONFIG_MTD_OF_PARTS=y ++CONFIG_MTD_PHYSMAP_OF=y ++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 ++CONFIG_MTD_ROOTFS_ROOT_DEV=y ++CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y ++CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 ++CONFIG_MTD_SPLIT=y ++CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" ++CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y ++CONFIG_MTD_SPLIT_SUPPORT=y ++CONFIG_MULTIUSER=y ++CONFIG_NET=y ++CONFIG_NETDEVICES=y ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NET_CADENCE=y ++CONFIG_NET_CLS=y ++CONFIG_NET_CLS_IND=y ++CONFIG_NET_CORE=y ++CONFIG_NET_EMATCH_STACK=32 ++CONFIG_NET_IPGRE_BROADCAST=y ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_DEFAULT=y ++CONFIG_NET_SCH_FIFO=y ++CONFIG_NET_SCH_FQ_CODEL=y ++CONFIG_NET_SOCK_MSG=y ++CONFIG_NET_VENDOR_3COM=y ++CONFIG_NET_VENDOR_8390=y ++CONFIG_NET_VENDOR_ADAPTEC=y ++CONFIG_NET_VENDOR_AGERE=y ++CONFIG_NET_VENDOR_ALACRITECH=y ++CONFIG_NET_VENDOR_ALTEON=y ++CONFIG_NET_VENDOR_AMAZON=y ++CONFIG_NET_VENDOR_AMD=y ++CONFIG_NET_VENDOR_AQUANTIA=y ++CONFIG_NET_VENDOR_ARC=y ++CONFIG_NET_VENDOR_ATHEROS=y ++CONFIG_NET_VENDOR_AURORA=y ++CONFIG_NET_VENDOR_BROADCOM=y ++CONFIG_NET_VENDOR_BROCADE=y ++CONFIG_NET_VENDOR_CADENCE=y ++CONFIG_NET_VENDOR_CAVIUM=y ++CONFIG_NET_VENDOR_CHELSIO=y ++CONFIG_NET_VENDOR_CIRRUS=y ++CONFIG_NET_VENDOR_CISCO=y ++CONFIG_NET_VENDOR_CORTINA=y ++CONFIG_NET_VENDOR_DEC=y ++CONFIG_NET_VENDOR_DLINK=y ++CONFIG_NET_VENDOR_EMULEX=y ++CONFIG_NET_VENDOR_EXAR=y ++CONFIG_NET_VENDOR_EZCHIP=y ++CONFIG_NET_VENDOR_FARADAY=y ++CONFIG_NET_VENDOR_FREESCALE=y ++CONFIG_NET_VENDOR_FUJITSU=y ++CONFIG_NET_VENDOR_GOOGLE=y ++CONFIG_NET_VENDOR_HISILICON=y ++CONFIG_NET_VENDOR_HP=y ++CONFIG_NET_VENDOR_HUAWEI=y ++CONFIG_NET_VENDOR_I825XX=y ++CONFIG_NET_VENDOR_IBM=y ++CONFIG_NET_VENDOR_INTEL=y ++CONFIG_NET_VENDOR_MARVELL=y ++CONFIG_NET_VENDOR_MELLANOX=y ++CONFIG_NET_VENDOR_MICREL=y ++CONFIG_NET_VENDOR_MICROCHIP=y ++CONFIG_NET_VENDOR_MICROSEMI=y ++CONFIG_NET_VENDOR_MYRI=y ++CONFIG_NET_VENDOR_NATSEMI=y ++CONFIG_NET_VENDOR_NETERION=y ++CONFIG_NET_VENDOR_NETRONOME=y ++CONFIG_NET_VENDOR_NI=y ++CONFIG_NET_VENDOR_NVIDIA=y ++CONFIG_NET_VENDOR_OKI=y ++CONFIG_NET_VENDOR_PACKET_ENGINES=y ++CONFIG_NET_VENDOR_PENSANDO=y ++CONFIG_NET_VENDOR_QLOGIC=y ++CONFIG_NET_VENDOR_QUALCOMM=y ++CONFIG_NET_VENDOR_RDC=y ++CONFIG_NET_VENDOR_REALTEK=y ++CONFIG_NET_VENDOR_RENESAS=y ++CONFIG_NET_VENDOR_ROCKER=y ++CONFIG_NET_VENDOR_SAMSUNG=y ++CONFIG_NET_VENDOR_SEEQ=y ++CONFIG_NET_VENDOR_SILAN=y ++CONFIG_NET_VENDOR_SIS=y ++CONFIG_NET_VENDOR_SMSC=y ++CONFIG_NET_VENDOR_SOCIONEXT=y ++CONFIG_NET_VENDOR_SOLARFLARE=y ++CONFIG_NET_VENDOR_STMICRO=y ++CONFIG_NET_VENDOR_SUN=y ++CONFIG_NET_VENDOR_SYNOPSYS=y ++CONFIG_NET_VENDOR_TEHUTI=y ++CONFIG_NET_VENDOR_TI=y ++CONFIG_NET_VENDOR_TOSHIBA=y ++CONFIG_NET_VENDOR_VIA=y ++CONFIG_NET_VENDOR_WIZNET=y ++CONFIG_NET_VENDOR_XILINX=y ++CONFIG_NET_VENDOR_XIRCOM=y ++CONFIG_NEW_LEDS=y ++CONFIG_NFSD_V3=y ++CONFIG_NFS_COMMON=y ++CONFIG_NFS_V3=y ++CONFIG_NF_CONNTRACK_PROCFS=y ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NLATTR=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_OF_RESERVED_MEM=y ++CONFIG_OPTIMIZE_INLINING=y ++CONFIG_OVERLAY_FS=y ++CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y ++CONFIG_OVERLAY_FS_XINO_AUTO=y ++CONFIG_PACKET=y ++CONFIG_PAGE_SIZE_4KB=y ++CONFIG_PANIC_ON_OOPS=y ++CONFIG_PANIC_ON_OOPS_VALUE=1 ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_PCIE_BUS_DEFAULT=y ++CONFIG_PCI_QUIRKS=y ++CONFIG_PCI_SYSCALL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_PINMUX=y ++CONFIG_POSIX_TIMERS=y ++CONFIG_PPC_4K_PAGES=y ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MULTILINK=y ++CONFIG_PREEMPT_NONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 ++CONFIG_PRINT_STACK_DEPTH=64 ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++CONFIG_RCU_KTHREAD_PRIO=0 ++CONFIG_RCU_NEED_SEGCBLIST=y ++CONFIG_RCU_STALL_COMMON=y ++CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_RFKILL=y ++CONFIG_RTC_DRV_CMOS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_INTF_DEV=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_LIB=y ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++CONFIG_RT_MUTEXES=y ++CONFIG_RUNTIME_TESTING_MENU=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_RXKAD=y ++CONFIG_SATA_MOBILE_LPM_POLICY=0 ++CONFIG_SBITMAP=y ++CONFIG_SCHED_HRTICK=y ++CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_LOWLEVEL=y ++CONFIG_SCSI_MOD=y ++CONFIG_SCSI_PROC_FS=y ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_SECURITY_DMESG_RESTRICT=y ++CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_16550A_VARIANTS=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_DMA=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_SERIAL_EARLYCON=y ++CONFIG_SHMEM=y ++CONFIG_SIGNALFD=y ++CONFIG_SLABINFO=y ++CONFIG_SLAB_MERGE_DEFAULT=y ++CONFIG_SLUB=y ++CONFIG_SLUB_CPU_PARTIAL=y ++CONFIG_SND_DRIVERS=y ++CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 ++CONFIG_SND_HDA_PREALLOC_SIZE=64 ++CONFIG_SND_MAX_CARDS=16 ++CONFIG_SND_OSSEMUL=y ++CONFIG_SND_PCI=y ++CONFIG_SND_PCM_OSS_PLUGINS=y ++CONFIG_SND_PROC_FS=y ++CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y ++CONFIG_SND_USB=y ++CONFIG_SND_VERBOSE_PROCFS=y ++CONFIG_SND_X86=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_SQUASHFS=y ++CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y ++CONFIG_SQUASHFS_EMBEDDED=y ++CONFIG_SQUASHFS_FILE_DIRECT=y ++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 ++CONFIG_SQUASHFS_XZ=y ++CONFIG_SSB_POSSIBLE=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_STAGING=y ++CONFIG_STANDALONE=y ++CONFIG_STDBINUTILS=y ++CONFIG_STP=y ++CONFIG_STRICT_KERNEL_RWX=y ++CONFIG_STRICT_MODULE_RWX=y ++CONFIG_STRIP_ASM_SYMS=y ++CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y ++CONFIG_SWAP=y ++CONFIG_SYMBOLIC_ERRNAME=y ++CONFIG_SYN_COOKIES=y ++CONFIG_SYSCTL=y ++CONFIG_SYSFS=y ++CONFIG_SYSTEM_TRUSTED_KEYS="" ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TEXTSEARCH=y ++CONFIG_THIN_ARCHIVES=y ++CONFIG_TICK_ONESHOT=y ++CONFIG_TIMERFD=y ++CONFIG_TINY_RCU=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_XATTR=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_TRACING_SUPPORT=y ++CONFIG_TRAD_SIGNALS=y ++CONFIG_TTY=y ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_XATTR=y ++CONFIG_UBIFS_FS_ZLIB=y ++CONFIG_UBIFS_FS_ZSTD=y ++CONFIG_UBSAN_ALIGNMENT=y ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_UID16=y ++CONFIG_UNIX=y ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX_SCM=y ++CONFIG_USBIP_VHCI_HC_PORTS=8 ++CONFIG_USBIP_VHCI_NR_HCS=1 ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB_ARMLINUX=y ++CONFIG_USB_AUTOSUSPEND_DELAY=2 ++CONFIG_USB_BELKIN=y ++CONFIG_USB_DEFAULT_PERSIST=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_TT_NEWSCHED=y ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_KEYSPAN_MPR=y ++CONFIG_USB_SERIAL_KEYSPAN_USA18X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y ++CONFIG_USB_SERIAL_SAFE_PADDED=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_VDSO=y ++CONFIG_VHOST_MENU=y ++CONFIG_VIRTIO_MENU=y ++CONFIG_VIRT_TO_BUS=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VMSPLIT_3G=y ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y ++CONFIG_WATCHDOG_OPEN_TIMEOUT=0 ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PRIV=y ++CONFIG_WEXT_PROC=y ++CONFIG_WEXT_SPY=y ++CONFIG_WILINK_PLATFORM_DATA=y ++CONFIG_WIRELESS=y ++CONFIG_WIRELESS_EXT=y ++CONFIG_WLAN=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_X86_SYSFB=y ++CONFIG_XEN_SCRUB_PAGES_DEFAULT=y ++CONFIG_XFRM=y ++CONFIG_XZ_DEC=y ++CONFIG_ZONE_DMA=y ++CONFIG_64BIT=y ++CONFIG_AQUANTIA_PHY=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_ARCH_KEEP_MEMBLOCK=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_STACKWALK=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARCH_WANTS_NO_INSTR=y ++CONFIG_ARM64=y ++CONFIG_ARM64_4K_PAGES=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_ARM64_ERRATUM_843419=y ++CONFIG_ARM64_ERRATUM_845719=y ++CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y ++CONFIG_ARM64_MODULE_PLTS=y ++CONFIG_ARM64_PAGE_SHIFT=12 ++CONFIG_ARM64_PA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++CONFIG_ARM64_TAGGED_ADDR_ABI=y ++CONFIG_ARM64_VA_BITS=39 ++CONFIG_ARM64_VA_BITS_39=y ++CONFIG_ARM_AMBA=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++CONFIG_ARM_PMU=y ++CONFIG_ARM_PSCI_FW=y ++CONFIG_ATA=y ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_MQ_PCI=y ++CONFIG_BLK_PM=y ++CONFIG_BLOCK_COMPAT=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_COMMON_CLK=y ++CONFIG_COMMON_CLK_MEDIATEK=y ++CONFIG_COMMON_CLK_MT2712=y ++CONFIG_COMMON_CLK_MT7622=y ++CONFIG_COMMON_CLK_MT7622_AUDSYS=y ++CONFIG_COMMON_CLK_MT7622_ETHSYS=y ++CONFIG_COMMON_CLK_MT7622_HIFSYS=y ++CONFIG_COMMON_CLK_MT7986=y ++CONFIG_COMMON_CLK_MT7986_ETHSYS=y ++CONFIG_COMMON_CLK_MT8183=y ++CONFIG_COMMON_CLK_MT8516=y ++CONFIG_COMPAT=y ++CONFIG_COMPAT_32BIT_TIME=y ++CONFIG_COMPAT_BINFMT_ELF=y ++CONFIG_COMPAT_NETLINK_MESSAGES=y ++CONFIG_COMPAT_OLD_SIGACTION=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ATTR_SET=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_RMAP=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CRC16=y ++CONFIG_CRYPTO_AES_ARM64=y ++CONFIG_CRYPTO_AES_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_CMAC=y ++CONFIG_CRYPTO_CRC32=y ++CONFIG_CRYPTO_CRC32C=y ++CONFIG_CRYPTO_CRYPTD=y ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_DRBG=y ++CONFIG_CRYPTO_DRBG_HMAC=y ++CONFIG_CRYPTO_DRBG_MENU=y ++CONFIG_CRYPTO_ECB=y ++CONFIG_CRYPTO_ECC=y ++CONFIG_CRYPTO_ECDH=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_HASH_INFO=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_JITTERENTROPY=y ++CONFIG_CRYPTO_LIB_SHA256=y ++CONFIG_CRYPTO_LZO=y ++CONFIG_CRYPTO_RNG=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=y ++CONFIG_CRYPTO_SHA256=y ++CONFIG_CRYPTO_SHA256_ARM64=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_SIMD=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_DCACHE_WORD_ACCESS=y ++CONFIG_DEBUG_MISC=y ++CONFIG_DIMLIB=y ++CONFIG_DMADEVICES=y ++CONFIG_DMATEST=y ++CONFIG_DMA_DIRECT_REMAP=y ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_ENGINE_RAID=y ++CONFIG_DMA_OF=y ++CONFIG_DMA_REMAP=y ++CONFIG_DMA_VIRTUAL_CHANNELS=y ++CONFIG_DTC=y ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_EDAC_SUPPORT=y ++CONFIG_EINT_MTK=y ++CONFIG_EXT4_FS=y ++CONFIG_F2FS_FS=y ++CONFIG_FIT_PARTITION=y ++CONFIG_FIXED_PHY=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_FRAME_POINTER=y ++CONFIG_FS_IOMAP=y ++CONFIG_FS_MBCACHE=y ++CONFIG_FWNODE_MDIO=y ++CONFIG_FW_LOADER_PAGED_BUF=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_GENERIC_ARCH_TOPOLOGY=y ++CONFIG_GENERIC_BUG=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_GENERIC_CPU_VULNERABILITIES=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_EARLY_IOREMAP=y ++CONFIG_GENERIC_FIND_FIRST_BIT=y ++CONFIG_GENERIC_GETTIMEOFDAY=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y ++CONFIG_GENERIC_MSI_IRQ=y ++CONFIG_GENERIC_MSI_IRQ_DOMAIN=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_PHY=y ++CONFIG_GENERIC_PINCONF=y ++CONFIG_GENERIC_PINCTRL_GROUPS=y ++CONFIG_GENERIC_PINMUX_FUNCTIONS=y ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GLOB=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_CDEV=y ++CONFIG_GRO_CELLS=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_HAS_DMA=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_MTK=y ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MT65XX=y ++CONFIG_ICPLUS_PHY=y ++CONFIG_IIO=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_IO_URING=y ++CONFIG_IRQCHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_IRQ_WORK=y ++CONFIG_JBD2=y ++CONFIG_JUMP_LABEL=y ++CONFIG_LIBFDT=y ++CONFIG_LOCK_DEBUGGING_SUPPORT=y ++CONFIG_LOCK_SPIN_ON_OWNER=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MAXLINEAR_GPHY=y ++CONFIG_MDIO_BUS=y ++CONFIG_MDIO_DEVICE=y ++CONFIG_MDIO_DEVRES=y ++CONFIG_MEDIATEK_GE_PHY=y ++#CONFIG_MEDIATEK_MT6577_AUXADC=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_MEMFD_CREATE=y ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 ++CONFIG_MFD_SYSCON=y ++CONFIG_MIGRATION=y ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_CQHCI=y ++CONFIG_MMC_MTK=y ++CONFIG_MODULES_TREE_LOOKUP=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_MTD_NAND_CORE=y ++CONFIG_MTD_NAND_ECC=y ++CONFIG_MTD_NAND_ECC_MEDIATEK=y ++CONFIG_MTD_NAND_ECC_SW_HAMMING=y ++CONFIG_MTD_NAND_MTK=y ++CONFIG_MTD_NAND_MTK_BMT=y ++CONFIG_MTD_PARSER_TRX=y ++CONFIG_MTD_RAW_NAND=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_SPLIT_FIRMWARE=y ++CONFIG_MTD_SPLIT_FIT_FW=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++CONFIG_MTD_UBI_BLOCK=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTK_EFUSE=y ++CONFIG_MTK_HSDMA=y ++CONFIG_MTK_INFRACFG=y ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_MTK_SCPSYS=y ++CONFIG_MTK_SCPSYS_PM_DOMAINS=y ++CONFIG_MTK_THERMAL=y ++CONFIG_MTK_SOC_THERMAL=y ++CONFIG_MTK_TIMER=y ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++CONFIG_NET_DEVLINK=y ++CONFIG_NET_DSA=y ++CONFIG_NET_DSA_MT7530=y ++CONFIG_NET_DSA_TAG_MTK=y ++CONFIG_NET_FLOW_LIMIT=y ++CONFIG_NET_MEDIATEK_SOC=y ++CONFIG_NET_MEDIATEK_SOC_WED=y ++CONFIG_NET_SELFTESTS=y ++CONFIG_NET_SWITCHDEV=y ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NLS=y ++CONFIG_NO_HZ_COMMON=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_NR_CPUS=4 ++CONFIG_NVMEM=y ++CONFIG_NVMEM_SYSFS=y ++CONFIG_OF=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_DYNAMIC=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_GPIO=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_KOBJ=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_OVERLAY=y ++CONFIG_OF_RESOLVE=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_PADATA=y ++CONFIG_PARTITION_PERCPU=y ++CONFIG_PCI=y ++CONFIG_PCIEAER=y ++CONFIG_PCIEASPM=y ++CONFIG_PCIEASPM_PERFORMANCE=y ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PCIE_MEDIATEK_GEN3=y ++CONFIG_PCIE_PME=y ++CONFIG_PCI_DEBUG=y ++CONFIG_PCI_DOMAINS=y ++CONFIG_PCI_DOMAINS_GENERIC=y ++CONFIG_PCI_MSI=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PERF_EVENTS=y ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_PHYLIB=y ++CONFIG_PHYLINK=y ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCTRL_MT7622=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_PINCTRL_MT8516=y ++CONFIG_PINCTRL_MTK=y ++CONFIG_PINCTRL_MTK_MOORE=y ++CONFIG_PINCTRL_MTK_V2=y ++CONFIG_PM=y ++CONFIG_PM_CLK=y ++CONFIG_PM_GENERIC_DOMAINS=y ++CONFIG_PM_GENERIC_DOMAINS_OF=y ++CONFIG_PM_OPP=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_POWER_SUPPLY=y ++CONFIG_PRINTK_TIME=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_COMPRESS=n ++#CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" ++CONFIG_PSTORE_CONSOLE=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS=y ++#CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y ++CONFIG_PSTORE_PMSG=y ++CONFIG_PSTORE_RAM=y ++CONFIG_PTP_1588_CLOCK_OPTIONAL=y ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=y ++CONFIG_PWM_SYSFS=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++CONFIG_RAS=y ++CONFIG_RATIONAL=y ++CONFIG_REALTEK_PHY=y ++CONFIG_REED_SOLOMON=y ++CONFIG_REED_SOLOMON_DEC8=y ++CONFIG_REED_SOLOMON_ENC8=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_MT6380=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_RFS_ACCEL=y ++CONFIG_RODATA_FULL_DEFAULT_ENABLED=y ++CONFIG_RPS=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_MT7622=y ++CONFIG_RTC_I2C_AND_SPI=y ++CONFIG_RTL8367S_GSW=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_SCHED_MC=y ++CONFIG_SCSI=y ++CONFIG_SCSI_COMMON=y ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_SERIAL_DEV_CTRL_TTYPORT=y ++CONFIG_SERIAL_MCTRL_GPIO=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SGL_ALLOC=y ++CONFIG_SG_POOL=y ++CONFIG_SMP=y ++CONFIG_SOCK_RX_QUEUE_MAPPING=y ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_SPI=y ++CONFIG_SPI_DYNAMIC=y ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_MEM=y ++CONFIG_SPI_MT65XX=y ++CONFIG_SPI_MTK_NOR=y ++CONFIG_SPI_MTK_SNFI=y ++CONFIG_SRCU=y ++CONFIG_SWCONFIG=y ++CONFIG_SWIOTLB=y ++CONFIG_SWPHY=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_SYSVIPC_COMPAT=y ++CONFIG_THERMAL=y ++CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y ++CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 ++CONFIG_THERMAL_EMULATION=y ++CONFIG_THERMAL_GOV_BANG_BANG=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_STEP_WISE=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_THERMAL_OF=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THREAD_INFO_IN_TASK=y ++CONFIG_TICK_CPU_ACCOUNTING=y ++CONFIG_TIMER_OF=y ++CONFIG_TIMER_PROBE=y ++CONFIG_TREE_RCU=y ++CONFIG_TREE_SRCU=y ++CONFIG_UBIFS_FS=y ++CONFIG_USB=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_VMAP_STACK=y ++CONFIG_WATCHDOG_CORE=y ++CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m ++CONFIG_WATCHDOG_SYSFS=y ++CONFIG_XPS=y ++CONFIG_XXHASH=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZONE_DMA32=y ++CONFIG_ZSTD_COMPRESS=y ++CONFIG_ZSTD_DECOMPRESS=y ++ ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DEVTMPFS_SAFE=y ++ ++CONFIG_WLAN_VENDOR_MEDIATEK=y ++CONFIG_CFG80211=m ++CONFIG_CFG80211_WEXT=y ++CONFIG_MAC80211=y ++CONFIG_MAC80211_LEDS=y ++CONFIG_MT7915E=m ++CONFIG_MT798X_WMAC=y ++ ++CONFIG_VFAT_FS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_852=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_15=y ++ ++CONFIG_USB_STORAGE=y ++CONFIG_I2C_GPIO=y ++CONFIG_SFP=y ++CONFIG_BLK_DEV_NVME=y ++CONFIG_NVME_HWMON=y ++ ++CONFIG_USB_USBNET=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_QMI_WWAN=m ++ ++CONFIG_NVMEM_MTK_EFUSE=y ++CONFIG_SENSORS_PWM_FAN=y ++ ++CONFIG_DUMMY=m ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_MIP6=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETLINK_DIAG=y ++CONFIG_INET_UDP_DIAG=m ++CONFIG_NET_IPIP=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_IPV6=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_NETFILTER_NETLINK=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV6=m ++CONFIG_NF_REJECT_IPV6=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP6_NF_TARGET_SYNPROXY=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_IP_VS=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++#CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TPROXY_IPV4=m ++CONFIG_NF_TPROXY_IPV6=m ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_XFRM=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_SYNPROXY=m ++CONFIG_NFTL=m ++CONFIG_NFTL_RW=y ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NF_FLOW_TABLE=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NF_FLOW_TABLE_IPV6=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_NAT_FTP=m ++CONFIG_PPP=m ++CONFIG_PPPOE=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_MPPE=m ++CONFIG_VETH=m ++CONFIG_TUN=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_NET_L3_MASTER_DEV=y ++CONFIG_IPVLAN=m ++CONFIG_MACVLAN=m ++CONFIG_NET_CLS_ACT=y ++# QoS and/or fair queueing ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_CSZ=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_INGRESS=m ++#CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_QOS=y ++CONFIG_NET_ESTIMATOR=y ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_ROUTE=y ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_POLICE=y ++ ++CONFIG_NET_ACT_VLAN=m ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_SAMPLE=y ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++# CONFIG_NET_ACT_BPF is not set ++CONFIG_NET_ACT_CONNMARK=m ++CONFIG_NET_ACT_CTINFO=m ++CONFIG_NET_ACT_SKBMOD=m ++# CONFIG_NET_ACT_IFE is not set ++CONFIG_NET_ACT_TUNNEL_KEY=m ++CONFIG_NET_ACT_CT=m ++# CONFIG_NET_ACT_GATE is not set ++ ++#NFS Client ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_PNFS_FILE_LAYOUT=m ++CONFIG_PNFS_BLOCK=m ++CONFIG_PNFS_FLEXFILE_LAYOUT=m ++CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" ++CONFIG_NFS_V4_1_MIGRATION=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++CONFIG_ROOT_NFS=y ++ ++#NFS Server ++CONFIG_NFSD=m ++CONFIG_NFSD_V2_ACL=y ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_NFSD_PNFS=y ++CONFIG_NFSD_BLOCKLAYOUT=y ++CONFIG_NFSD_SCSILAYOUT=y ++CONFIG_NFSD_FLEXFILELAYOUT=y ++CONFIG_NFSD_FAULT_INJECTION=y ++CONFIG_NFS_ACL_SUPPORT=m ++ ++#usb-tethering ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_RNDIS_HOST=m ++ ++#for lxc ++CONFIG_CGROUPS=y ++CONFIG_NAMESPACES=y ++CONFIG_USER_NS=y ++CONFIG_MEMCG=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CPUSETS=y ++CONFIG_UNIX_DIAG=m ++CONFIG_PACKET_DIAG=m ++CONFIG_FUSE_FS=m ++ ++#for docker ++CONFIG_CGROUP_FREEZER=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_MEMCG_SWAP_ENABLED=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CFS_BANDWIDTH=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_SECCOMP=y ++ ++CONFIG_NET_IPGRE=m ++CONFIG_NET_IPGRE_DEMUX=m ++ ++#for r3mini ++CONFIG_AIR_EN8811H_PHY=y ++CONFIG_LED_TRIGGER_PHY=y ++ ++CONFIG_EXTRA_FIRMWARE="airoha/EthMD32.dm.bin airoha/EthMD32.DSP.bin" ++CONFIG_EXTRA_FIRMWARE_DIR="utils/firmware/" ++ ++CONFIG_PANIC_TIMEOUT=30 +diff --git a/arch/arm64/configs/quartz64_defconfig b/arch/arm64/configs/quartz64_defconfig +new file mode 100644 +index 000000000000..0d079383b0c0 +--- /dev/null ++++ b/arch/arm64/configs/quartz64_defconfig +@@ -0,0 +1,922 @@ ++CONFIG_LOCALVERSION="-bpi-r2pro" ++CONFIG_LOCALVERSION_AUTO=n ++ ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_AUDIT=y ++CONFIG_GENERIC_IRQ_DEBUGFS=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_BPF_JIT=y ++CONFIG_PREEMPT=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=18 ++CONFIG_NUMA_BALANCING=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_HUGETLB=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_MISC=y ++CONFIG_USER_NS=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_KALLSYMS_ALL=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SCHED_MC=y ++CONFIG_SCHED_SMT=y ++CONFIG_NUMA=y ++CONFIG_KEXEC=y ++CONFIG_KEXEC_FILE=y ++CONFIG_CRASH_DUMP=y ++CONFIG_XEN=y ++CONFIG_RANDOMIZE_BASE=y ++CONFIG_HIBERNATION=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_ENERGY_MODEL=y ++CONFIG_ARM_CPUIDLE=y ++CONFIG_ARM_PSCI_CPUIDLE=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++#CONFIG_CPU_FREQ_GOV_POWERSAVE=m ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++#CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m ++CONFIG_CPUFREQ_DT=y ++#CONFIG_ACPI_CPPC_CPUFREQ=m ++CONFIG_ARM_SCPI_CPUFREQ=y ++CONFIG_ARM_SCMI_CPUFREQ=y ++CONFIG_ACPI=y ++CONFIG_ACPI_APEI=y ++CONFIG_ACPI_APEI_GHES=y ++CONFIG_ACPI_APEI_MEMORY_FAILURE=y ++CONFIG_ACPI_APEI_EINJ=y ++CONFIG_VIRTUALIZATION=y ++CONFIG_KVM=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++#CONFIG_CRYPTO_SHA512_ARM64_CE=m ++#CONFIG_CRYPTO_SHA3_ARM64=m ++#CONFIG_CRYPTO_SM3_ARM64_CE=m ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++#CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m ++CONFIG_CRYPTO_AES_ARM64=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++#CONFIG_CRYPTO_CHACHA20_NEON=m ++#CONFIG_CRYPTO_AES_ARM64_BS=m ++CONFIG_JUMP_LABEL=y ++CONFIG_COMPAT_32BIT_TIME=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_KSM=y ++CONFIG_MEMORY_FAILURE=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_CMA=y ++CONFIG_ZSWAP=y ++CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y ++CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC=y ++CONFIG_ZSWAP_DEFAULT_ON=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++#CONFIG_IP_PNP_BOOTP=y ++#CONFIG_IPV6=m ++#CONFIG_NETFILTER=y ++#CONFIG_NF_CONNTRACK=m ++#CONFIG_NF_CONNTRACK_EVENTS=y ++#CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++#CONFIG_NETFILTER_XT_TARGET_LOG=m ++#CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++#CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++#CONFIG_NF_LOG_IPV4=m ++#CONFIG_IP_NF_IPTABLES=m ++#CONFIG_IP_NF_FILTER=m ++#CONFIG_IP_NF_TARGET_REJECT=m ++#CONFIG_IP_NF_NAT=m ++#CONFIG_IP_NF_TARGET_MASQUERADE=m ++#CONFIG_IP_NF_MANGLE=m ++#CONFIG_IP6_NF_IPTABLES=m ++#CONFIG_IP6_NF_FILTER=m ++#CONFIG_IP6_NF_TARGET_REJECT=m ++#CONFIG_IP6_NF_MANGLE=m ++#CONFIG_IP6_NF_NAT=m ++#CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_BRIDGE=y ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_NET_DSA=y ++#CONFIG_VLAN_8021Q=m ++#CONFIG_VLAN_8021Q_GVRP=y ++#CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_NET_SCHED=y ++#CONFIG_NET_SCH_CBS=m ++#CONFIG_NET_SCH_ETF=m ++#CONFIG_NET_SCH_TAPRIO=m ++#CONFIG_NET_SCH_MQPRIO=m ++#CONFIG_NET_SCH_INGRESS=m ++#CONFIG_NET_CLS_BASIC=m ++#CONFIG_NET_CLS_FLOWER=m ++#CONFIG_NET_CLS_ACT=y ++#CONFIG_NET_ACT_GACT=m ++#CONFIG_NET_ACT_MIRRED=m ++#CONFIG_NET_ACT_GATE=m ++#CONFIG_QRTR=m ++#CONFIG_QRTR_TUN=m ++#CONFIG_CAN=m ++#CONFIG_CAN_FLEXCAN=m ++#CONFIG_BT=m ++#CONFIG_BT_RFCOMM=y ++#CONFIG_BT_RFCOMM_TTY=y ++#CONFIG_BT_BNEP=y ++#CONFIG_BT_BNEP_MC_FILTER=y ++#CONFIG_BT_BNEP_PROTO_FILTER=y ++#CONFIG_BT_HIDP=y ++#CONFIG_BT_HS=y ++#CONFIG_BT_LEDS=y ++#CONFIG_BT_MSFTEXT=y ++#CONFIG_BT_HCIBTUSB=m ++# CONFIG_BT_HCIBTUSB_BCM is not set ++#CONFIG_BT_HCIBTSDIO=m ++#CONFIG_BT_HCIUART=m ++#CONFIG_BT_HCIUART_LL=y ++#CONFIG_BT_HCIUART_BCM=y ++#CONFIG_BT_HCIUART_RTL=y ++CONFIG_CFG80211=y ++CONFIG_MAC80211=y ++CONFIG_MAC80211_LEDS=y ++CONFIG_RFKILL=y ++#CONFIG_NET_9P=y ++#CONFIG_NET_9P_VIRTIO=y ++#CONFIG_NFC=m ++#CONFIG_NFC_NCI=m ++#CONFIG_NFC_S3FWRN5_I2C=m ++CONFIG_PCI=y ++#CONFIG_PCIEPORTBUS=y ++CONFIG_PCI_DEBUG=y ++#CONFIG_PCI_REALLOC_ENABLE_AUTO=y ++#CONFIG_PCI_IOV=y ++#CONFIG_PCI_PASID=y ++#CONFIG_HOTPLUG_PCI=y ++#CONFIG_HOTPLUG_PCI_ACPI=y ++CONFIG_PCI_HOST_GENERIC=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PCIE_ROCKCHIP_HOST=y ++#CONFIG_PCIE_DW_PLAT_HOST=y ++CONFIG_PCI_ENDPOINT=y ++CONFIG_PCIE_ROCKCHIP_EP=y ++CONFIG_PCIE_ROCKCHIP_DW_HOST=y ++#CONFIG_PCI_ENDPOINT_CONFIGFS=y ++#CONFIG_PCI_EPF_TEST=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++#CONFIG_FW_LOADER_USER_HELPER=y ++#CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++#CONFIG_BRCMSTB_GISB_ARB=y ++#CONFIG_VEXPRESS_CONFIG=y ++CONFIG_ARM_SCMI_PROTOCOL=y ++CONFIG_ARM_SCPI_PROTOCOL=y ++CONFIG_SYSFB_SIMPLEFB=y ++#CONFIG_EFI_CAPSULE_LOADER=y ++#CONFIG_MTD=y ++#CONFIG_MTD_BLOCK=y ++#CONFIG_MTD_CFI=y ++#CONFIG_MTD_CFI_ADV_OPTIONS=y ++#CONFIG_MTD_CFI_INTELEXT=y ++#CONFIG_MTD_CFI_AMDSTD=y ++#CONFIG_MTD_CFI_STAA=y ++#CONFIG_MTD_PHYSMAP=y ++#CONFIG_MTD_PHYSMAP_OF=y ++#CONFIG_MTD_DATAFLASH=y ++#CONFIG_MTD_SST25L=y ++#CONFIG_MTD_RAW_NAND=y ++#CONFIG_MTD_NAND_DENALI_DT=y ++#CONFIG_MTD_SPI_NOR=y ++CONFIG_OF_OVERLAY=y ++CONFIG_ZRAM=y ++CONFIG_ZRAM_MEMORY_TRACKING=y ++CONFIG_BLK_DEV_LOOP=y ++#CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_BLK_DEV_NVME=y ++CONFIG_NVME_HWMON=y ++CONFIG_SRAM=y ++#CONFIG_DW_XDATA_PCIE=y ++#CONFIG_PCI_ENDPOINT_TEST=m ++#CONFIG_EEPROM_AT24=m ++#CONFIG_EEPROM_AT25=m ++#CONFIG_UACCE=m ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++#CONFIG_SCSI_SAS_ATA=y ++#CONFIG_SCSI_HISI_SAS=y ++#CONFIG_SCSI_HISI_SAS_PCI=y ++#CONFIG_MEGARAID_SAS=y ++#CONFIG_SCSI_MPT3SAS=m ++#CONFIG_SCSI_UFSHCD=y ++#CONFIG_SCSI_UFSHCD_PLATFORM=y ++CONFIG_ATA=y ++CONFIG_SATA_AHCI=y ++CONFIG_SATA_AHCI_PLATFORM=y ++#CONFIG_AHCI_CEVA=y ++#CONFIG_AHCI_QORIQ=y ++#CONFIG_SATA_SIL24=y ++#CONFIG_SATA_MV=y ++CONFIG_AHCI_DWC=y ++CONFIG_PATA_PLATFORM=y ++CONFIG_PATA_OF_PLATFORM=y ++#CONFIG_MD=y ++#CONFIG_BLK_DEV_MD=m ++#CONFIG_BLK_DEV_DM=m ++#CONFIG_DM_MIRROR=m ++#CONFIG_DM_ZERO=m ++CONFIG_NETDEVICES=y ++#CONFIG_MACVLAN=m ++#CONFIG_MACVTAP=m ++CONFIG_TUN=y ++#CONFIG_VETH=m ++CONFIG_VIRTIO_NET=y ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++# CONFIG_NET_VENDOR_ALACRITECH is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_AQUANTIA is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_ASIX is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++# CONFIG_NET_VENDOR_CADENCE is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++# CONFIG_NET_VENDOR_CORTINA is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++# CONFIG_NET_VENDOR_ENGLEDER is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_GOOGLE is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_HUAWEI is not set ++#CONFIG_E100=y ++#CONFIG_E1000=y ++#CONFIG_E1000E=y ++#CONFIG_IGB=y ++#CONFIG_IGBVF=y ++#CONFIG_IXGB=y ++#CONFIG_IXGBE=y ++#CONFIG_IXGBEVF=y ++#CONFIG_I40E=y ++#CONFIG_I40EVF=y ++#CONFIG_ICE=y ++#CONFIG_FM10K=y ++#CONFIG_IGC=y ++# CONFIG_NET_VENDOR_MICROSOFT is not set ++# CONFIG_NET_VENDOR_LITEX is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_MICROSEMI is not set ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETERION is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_NET_VENDOR_NI is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_NET_VENDOR_PENSANDO is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RDC is not set ++#CONFIG_R8169=y ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SOLARFLARE is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_SOCIONEXT is not set ++CONFIG_STMMAC_ETH=y ++CONFIG_DWMAC_DWC_QOS_ETH=y ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++# CONFIG_NET_VENDOR_VERTEXCOM is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++# CONFIG_NET_VENDOR_XILINX is not set ++#CONFIG_AQUANTIA_PHY=y ++#CONFIG_BROADCOM_PHY=m ++#CONFIG_BCM54140_PHY=m ++#CONFIG_BCM7XXX_PHY=m ++#CONFIG_MARVELL_PHY=m ++#CONFIG_MARVELL_10G_PHY=m ++#CONFIG_MICREL_PHY=y ++#CONFIG_MICROSEMI_PHY=y ++#CONFIG_MOTORCOMM_PHY=y ++#CONFIG_AT803X_PHY=y ++CONFIG_ROCKCHIP_PHY=y ++#CONFIG_VITESSE_PHY=y ++CONFIG_MDIO_BITBANG=y ++CONFIG_MDIO_BUS_MUX_GPIO=y ++CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y ++CONFIG_MDIO_BUS_MUX_MMIOREG=y ++#CONFIG_USB_PEGASUS=m ++#CONFIG_USB_RTL8150=m ++#CONFIG_USB_RTL8152=m ++#CONFIG_USB_LAN78XX=m ++#CONFIG_USB_USBNET=y ++#CONFIG_USB_NET_AX8817X=m ++#CONFIG_USB_NET_CDCETHER=m ++#CONFIG_USB_NET_CDC_NCM=m ++#CONFIG_USB_NET_DM9601=m ++#CONFIG_USB_NET_SR9800=m ++#CONFIG_USB_NET_SMSC75XX=m ++#CONFIG_USB_NET_SMSC95XX=m ++#CONFIG_USB_NET_NET1080=m ++#CONFIG_USB_NET_PLUSB=m ++#CONFIG_USB_NET_MCS7830=m ++#CONFIG_USB_NET_CDC_SUBSET=m ++#CONFIG_USB_NET_ZAURUS=m ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++#CONFIG_BRCMFMAC=m ++#CONFIG_BRCM_TRACING=y ++#CONFIG_BRCMDBG=y ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_MICROCHIP is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++#CONFIG_RTL8192CE=y ++#CONFIG_RTL8192SE=y ++#CONFIG_RTL8192DE=y ++#CONFIG_RTL8723AE=y ++#CONFIG_RTL8723BE=y ++#CONFIG_RTL8188EE=y ++#CONFIG_RTL8192EE=y ++#CONFIG_RTL8821AE=y ++#CONFIG_RTL8192CU=y ++#CONFIG_RTL8XXXU=y ++#CONFIG_RTL8XXXU_UNTESTED=y ++#CONFIG_RTW88=y ++#CONFIG_RTW88_8822BE=y ++#CONFIG_RTW88_8822CE=y ++#CONFIG_RTW88_8723DE=y ++#CONFIG_RTW88_8821CE=y ++#CONFIG_RTW88_DEBUG=y ++#CONFIG_RTW88_DEBUGFS=y ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++#CONFIG_INPUT_FF_MEMLESS=y ++#CONFIG_INPUT_MATRIXKMAP=y ++CONFIG_INPUT_EVDEV=y ++#CONFIG_KEYBOARD_ADC=m ++#CONFIG_KEYBOARD_GPIO=y ++#CONFIG_INPUT_TOUCHSCREEN=y ++#CONFIG_TOUCHSCREEN_CYTTSP5=y ++#CONFIG_TOUCHSCREEN_GOODIX=y ++CONFIG_INPUT_MISC=y ++#CONFIG_INPUT_PWM_VIBRA=m ++CONFIG_INPUT_RK805_PWRKEY=y ++#CONFIG_INPUT_WS8100_PEN=y ++# CONFIG_SERIO_SERPORT is not set ++CONFIG_SERIO_AMBAKMI=y ++CONFIG_LEGACY_PTY_COUNT=16 ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DW=y ++# CONFIG_SERIAL_8250_PERICOM is not set ++CONFIG_SERIAL_OF_PLATFORM=y ++#CONFIG_SERIAL_AMBA_PL011=y ++#CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++#CONFIG_SERIAL_XILINX_PS_UART=y ++#CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y ++#CONFIG_SERIAL_FSL_LPUART=y ++#CONFIG_SERIAL_FSL_LPUART_CONSOLE=y ++#CONFIG_SERIAL_FSL_LINFLEXUART=y ++#CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_VIRTIO_CONSOLE=y ++#CONFIG_IPMI_HANDLER=m ++#CONFIG_IPMI_DEVICE_INTERFACE=m ++#CONFIG_IPMI_SI=m ++# CONFIG_HW_RANDOM_CN10K is not set ++#CONFIG_TCG_TPM=y ++#CONFIG_TCG_TIS_I2C_INFINEON=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++#CONFIG_I2C_MUX_PCA954x=y ++CONFIG_I2C_DESIGNWARE_PLATFORM=y ++CONFIG_I2C_GPIO=y ++CONFIG_I2C_RK3X=y ++CONFIG_I2C_SLAVE=y ++CONFIG_SPI=y ++#CONFIG_SPI_CADENCE_QUADSPI=y ++#CONFIG_SPI_NXP_FLEXSPI=y ++CONFIG_SPI_GPIO=y ++#CONFIG_SPI_PL022=y ++CONFIG_SPI_ROCKCHIP=y ++#CONFIG_SPI_ROCKCHIP_SFC=y ++CONFIG_SPI_SPIDEV=y ++CONFIG_SPMI=y ++CONFIG_PINCTRL_RK805=y ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_GPIO_DWAPB=y ++CONFIG_GPIO_GENERIC_PLATFORM=y ++#CONFIG_GPIO_MB86S7X=y ++#CONFIG_GPIO_PL061=y ++#CONFIG_GPIO_SYSCON=y ++#CONFIG_GPIO_XGENE=y ++#CONFIG_GPIO_MAX732X=y ++#CONFIG_GPIO_PCA953X=y ++#CONFIG_GPIO_PCA953X_IRQ=y ++CONFIG_POWER_RESET_GPIO=y ++#CONFIG_PDA_POWER=m ++#CONFIG_GENERIC_ADC_BATTERY=m ++#CONFIG_BATTERY_SBS=m ++#CONFIG_CHARGER_SBS=m ++#CONFIG_MANAGER_SBS=m ++CONFIG_CHARGER_RK817=y ++CONFIG_SENSORS_ARM_SCMI=y ++CONFIG_SENSORS_ARM_SCPI=y ++CONFIG_SENSORS_GPIO_FAN=y ++CONFIG_SENSORS_PWM_FAN=y ++CONFIG_THERMAL_NETLINK=y ++CONFIG_THERMAL_STATISTICS=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_BANG_BANG=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y ++CONFIG_CPU_THERMAL=y ++CONFIG_DEVFREQ_THERMAL=y ++CONFIG_THERMAL_EMULATION=y ++#CONFIG_THERMAL_MMIO=m ++CONFIG_ROCKCHIP_THERMAL=y ++#CONFIG_GENERIC_ADC_THERMAL=m ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_NOWAYOUT=y ++CONFIG_WATCHDOG_SYSFS=y ++CONFIG_DW_WATCHDOG=y ++CONFIG_MFD_RK8XX=y ++CONFIG_MFD_RK8XX_I2C=y ++# CONFIG_MFD_VEXPRESS_SYSREG is not set ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_DEBUG=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_USERSPACE_CONSUMER=y ++#CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_GPIO=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_REGULATOR_RK808=y ++#CONFIG_REGULATOR_TPS65185=y ++CONFIG_REGULATOR_VCTRL=y ++#CONFIG_RC_CORE=m ++#CONFIG_RC_DECODERS=y ++#CONFIG_RC_DEVICES=y ++CONFIG_MEDIA_CEC_SUPPORT=y ++CONFIG_CEC_GPIO=y ++#CONFIG_MEDIA_SUPPORT=m ++#CONFIG_MEDIA_CAMERA_SUPPORT=y ++#CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++#CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++#CONFIG_MEDIA_SDR_SUPPORT=y ++#CONFIG_MEDIA_PLATFORM_SUPPORT=y ++# CONFIG_DVB_NET is not set ++#CONFIG_MEDIA_USB_SUPPORT=y ++#CONFIG_USB_VIDEO_CLASS=m ++#CONFIG_USB_GSPCA=m ++#CONFIG_V4L_PLATFORM_DRIVERS=y ++#CONFIG_V4L_MEM2MEM_DRIVERS=y ++#CONFIG_SDR_PLATFORM_DRIVERS=y ++#CONFIG_VIDEO_IMX219=m ++#CONFIG_VIDEO_OV5645=m ++CONFIG_DRM=y ++#CONFIG_DRM_I2C_CH7006=m ++#CONFIG_DRM_I2C_SIL164=m ++#CONFIG_DRM_I2C_NXP_TDA998X=m ++#CONFIG_DRM_MALI_DISPLAY=m ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_ROCKCHIP_VOP2=y ++CONFIG_ROCKCHIP_DW_HDMI=y ++CONFIG_ROCKCHIP_DW_MIPI_DSI=y ++CONFIG_ROCKCHIP_INNO_HDMI=y ++#CONFIG_ROCKCHIP_LVDS=y ++#CONFIG_DRM_ROCKCHIP_EBC=m ++#CONFIG_DRM_PANEL_LVDS=m ++#CONFIG_DRM_PANEL_SIMPLE=m ++#CONFIG_DRM_PANEL_EDP=m ++#CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=y ++#CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m ++#CONFIG_DRM_PANEL_RAYDIUM_RM67191=m ++#CONFIG_DRM_PANEL_SITRONIX_ST7703=m ++#CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m ++CONFIG_DRM_DISPLAY_CONNECTOR=y ++#CONFIG_DRM_LONTIUM_LT9611=m ++#CONFIG_DRM_LONTIUM_LT9611UXC=m ++#CONFIG_DRM_NWL_MIPI_DSI=m ++#CONFIG_DRM_SII902X=m ++#CONFIG_DRM_SIMPLE_BRIDGE=m ++#CONFIG_DRM_THINE_THC63LVD1024=m ++#CONFIG_DRM_TI_SN65DSI86=m ++#CONFIG_DRM_I2C_ADV7511=m ++#CONFIG_DRM_I2C_ADV7511_AUDIO=y ++CONFIG_DRM_DW_HDMI_CEC=y ++#CONFIG_DRM_PL111=m ++CONFIG_DRM_PANFROST=y ++CONFIG_FB=y ++# CONFIG_XEN_FBDEV_FRONTEND is not set ++CONFIG_FB_SIMPLE=y ++#CONFIG_BACKLIGHT_CLASS_DEVICE=y ++#CONFIG_BACKLIGHT_PWM=m ++#CONFIG_BACKLIGHT_LM3630A=y ++#CONFIG_BACKLIGHT_LP855X=m ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_HDA_INTEL=y ++CONFIG_SND_HDA_CODEC_HDMI=y ++CONFIG_SND_HDA_GENERIC=y ++CONFIG_SND_SOC=y ++#CONFIG_SND_SOC_FSL_ASRC=m ++#CONFIG_SND_SOC_FSL_SAI=m ++#CONFIG_SND_SOC_FSL_AUDMIX=m ++#CONFIG_SND_SOC_FSL_SSI=m ++#CONFIG_SND_SOC_FSL_SPDIF=m ++#CONFIG_SND_SOC_FSL_ESAI=m ++#CONFIG_SND_SOC_FSL_MICFIL=m ++#CONFIG_SND_SOC_FSL_EASRC=m ++#CONFIG_SND_SOC_IMX_AUDMUX=m ++CONFIG_SND_SOC_ROCKCHIP=y ++CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y ++CONFIG_SND_SOC_ROCKCHIP_PDM=y ++CONFIG_SND_SOC_ROCKCHIP_SPDIF=y ++#CONFIG_SND_SOC_ROCKCHIP_MAX98090=y ++#CONFIG_SND_SOC_ROCKCHIP_RT5645=y ++#CONFIG_SND_SOC_RK3288_HDMI_ANALOG=y ++#CONFIG_SND_SOC_RK3399_GRU_SOUND=y ++#CONFIG_SND_SOC_AK4613=m ++#CONFIG_SND_SOC_ES7134=m ++#CONFIG_SND_SOC_ES7241=m ++#CONFIG_SND_SOC_GTM601=m ++#CONFIG_SND_SOC_MAX98927=m ++#CONFIG_SND_SOC_PCM3168A_I2C=m ++#CONFIG_SND_SOC_RK3328=y ++CONFIG_SND_SOC_RK817=y ++#CONFIG_SND_SOC_RT5659=m ++#CONFIG_SND_SOC_SGTL5000=m ++CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y ++CONFIG_SND_SOC_SIMPLE_MUX=y ++CONFIG_SND_SOC_SPDIF=y ++#CONFIG_SND_SOC_TAS571X=m ++#CONFIG_SND_SOC_WM8904=m ++#CONFIG_SND_SOC_WM8960=m ++#CONFIG_SND_SOC_WM8962=m ++#CONFIG_SND_SOC_WSA881X=m ++#CONFIG_SND_SOC_LPASS_WSA_MACRO=m ++#CONFIG_SND_SOC_LPASS_VA_MACRO=m ++CONFIG_SND_SIMPLE_CARD=y ++#CONFIG_SND_AUDIO_GRAPH_CARD=y ++#CONFIG_HID_BATTERY_STRENGTH=y ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_ITE is not set ++# CONFIG_HID_KENSINGTON is not set ++#CONFIG_HID_LOGITECH_HIDPP=m ++#CONFIG_HID_REDRAGON=m ++#CONFIG_HID_MICROSOFT=m ++#CONFIG_HID_MONTEREY=m ++#CONFIG_HID_MULTITOUCH=y ++#CONFIG_I2C_HID_ACPI=m ++#CONFIG_I2C_HID_OF=m ++#CONFIG_I2C_HID_OF_GOODIX=m ++#CONFIG_USB_LED_TRIG=y ++#CONFIG_USB_ULPI_BUS=y ++CONFIG_USB_CONN_GPIO=y ++CONFIG_USB=y ++CONFIG_USB_OTG=y ++#CONFIG_USB_LEDS_TRIGGER_USBPORT=y ++#CONFIG_USB_MON=m ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++#CONFIG_USB_ACM=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC2=y ++#CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++#CONFIG_USB_SERIAL_SIMPLE=m ++#CONFIG_USB_SERIAL_CH341=m ++#CONFIG_USB_SERIAL_CP210X=m ++#CONFIG_USB_SERIAL_FTDI_SIO=m ++#CONFIG_USB_SERIAL_OPTION=m ++#CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_NOP_USB_XCEIV=y ++#CONFIG_USB_ULPI=y ++#CONFIG_USB_GADGET=y ++#CONFIG_USB_SNP_UDC_PLAT=y ++#CONFIG_USB_BDC_UDC=y ++#CONFIG_USB_CONFIGFS=y ++#CONFIG_USB_CONFIGFS_SERIAL=y ++#CONFIG_USB_CONFIGFS_ACM=y ++#CONFIG_USB_CONFIGFS_OBEX=y ++#CONFIG_USB_CONFIGFS_NCM=y ++#CONFIG_USB_CONFIGFS_ECM=y ++#CONFIG_USB_CONFIGFS_ECM_SUBSET=y ++#CONFIG_USB_CONFIGFS_RNDIS=y ++#CONFIG_USB_CONFIGFS_EEM=y ++#CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++#CONFIG_USB_CONFIGFS_F_FS=y ++#CONFIG_TYPEC=y ++#CONFIG_TYPEC_TCPM=y ++#CONFIG_TYPEC_TCPCI=y ++#CONFIG_TYPEC_FUSB302=y ++#CONFIG_TYPEC_UCSI=y ++#CONFIG_TYPEC_TPS6598X=m ++#CONFIG_TYPEC_HD3SS3220=m ++#CONFIG_TYPEC_WUSB3801=y ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_SDIO_UART=y ++CONFIG_MMC_DEBUG=y ++CONFIG_MMC_ARMMMCI=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_ACPI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_OF_DWCMSHC=y ++CONFIG_MMC_SDHCI_F_SDH30=y ++CONFIG_MMC_SPI=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_CQHCI=y ++CONFIG_MMC_HSQ=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PWM=y ++CONFIG_LEDS_REGULATOR=y ++CONFIG_LEDS_SYSCON=y ++CONFIG_LEDS_USER=y ++#CONFIG_LEDS_TRIGGER_TIMER=y ++#CONFIG_LEDS_TRIGGER_ONESHOT=y ++#CONFIG_LEDS_TRIGGER_DISK=y ++#CONFIG_LEDS_TRIGGER_MTD=y ++#CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++#CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++#CONFIG_LEDS_TRIGGER_CPU=y ++#CONFIG_LEDS_TRIGGER_ACTIVITY=y ++#CONFIG_LEDS_TRIGGER_GPIO=y ++#CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++#CONFIG_LEDS_TRIGGER_TRANSIENT=y ++#CONFIG_LEDS_TRIGGER_CAMERA=y ++#CONFIG_LEDS_TRIGGER_PANIC=y ++#CONFIG_LEDS_TRIGGER_NETDEV=y ++#CONFIG_LEDS_TRIGGER_PATTERN=y ++#CONFIG_LEDS_TRIGGER_AUDIO=y ++#CONFIG_LEDS_TRIGGER_TTY=y ++CONFIG_EDAC=y ++CONFIG_EDAC_GHES=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_RK808=y ++CONFIG_RTC_DRV_HYM8563=y ++#CONFIG_RTC_DRV_PCF85063=y ++#CONFIG_RTC_DRV_EFI=y ++CONFIG_DMADEVICES=y ++#CONFIG_AMBA_PL08X=y ++CONFIG_PL330_DMA=y ++#CONFIG_DW_DMAC=m ++#CONFIG_DW_DMAC_PCI=m ++#CONFIG_DW_EDMA_PCIE=m ++#CONFIG_UIO=m ++CONFIG_VFIO=y ++CONFIG_VFIO_NOIOMMU=y ++CONFIG_VFIO_PCI=y ++CONFIG_VIRTIO_PCI=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_MMIO=y ++# CONFIG_XEN_BALLOON is not set ++# CONFIG_XEN_DEV_EVTCHN is not set ++# CONFIG_XEN_BACKEND is not set ++# CONFIG_XENFS is not set ++# CONFIG_XEN_SYS_HYPERVISOR is not set ++# CONFIG_XEN_GNTDEV is not set ++# CONFIG_XEN_GRANT_DEV_ALLOC is not set ++#CONFIG_STAGING=y ++#CONFIG_RTL8192U=m ++#CONFIG_RTLLIB=m ++#CONFIG_RTL8192E=m ++#CONFIG_RTL8723BS=m ++#CONFIG_R8712U=m ++#CONFIG_R8188EU=m ++#CONFIG_STAGING_MEDIA=y ++#CONFIG_VIDEO_HANTRO=m ++#CONFIG_VIDEO_ROCKCHIP_VDEC=m ++#CONFIG_ASHMEM=y ++# CONFIG_SURFACE_PLATFORMS is not set ++CONFIG_COMMON_CLK_RK808=y ++CONFIG_COMMON_CLK_SCMI=y ++CONFIG_COMMON_CLK_SCPI=y ++CONFIG_COMMON_CLK_PWM=y ++CONFIG_COMMON_CLK_FIXED_MMIO=y ++CONFIG_HWSPINLOCK=y ++# CONFIG_FSL_ERRATUM_A008585 is not set ++# CONFIG_HISILICON_ERRATUM_161010101 is not set ++CONFIG_ARM_MHU=y ++CONFIG_PLATFORM_MHU=y ++CONFIG_ROCKCHIP_MBOX=y ++CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y ++CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y ++CONFIG_ROCKCHIP_IOMMU=y ++CONFIG_ARM_SMMU=y ++CONFIG_ARM_SMMU_V3=y ++CONFIG_ARM_SMMU_V3_SVA=y ++CONFIG_REMOTEPROC=y ++CONFIG_REMOTEPROC_CDEV=y ++#CONFIG_SOUNDWIRE=m ++#CONFIG_SOUNDWIRE_INTEL=m ++#CONFIG_SOUNDWIRE_QCOM=m ++CONFIG_ROCKCHIP_IODOMAIN=y ++CONFIG_ROCKCHIP_PM_DOMAINS=y ++#CONFIG_DEVFREQ_GOV_PERFORMANCE=m ++#CONFIG_DEVFREQ_GOV_POWERSAVE=m ++#CONFIG_DEVFREQ_GOV_USERSPACE=m ++#CONFIG_DEVFREQ_GOV_PASSIVE=m ++#CONFIG_ARM_RK3399_DMC_DEVFREQ=m ++CONFIG_EXTCON_ADC_JACK=y ++CONFIG_EXTCON_GPIO=y ++CONFIG_EXTCON_USB_GPIO=y ++CONFIG_MEMORY=y ++CONFIG_IIO=y ++CONFIG_IIO_ST_ACCEL_3AXIS=y ++#CONFIG_MAX9611=m ++#CONFIG_QCOM_SPMI_ADC5=m ++CONFIG_ROCKCHIP_SARADC=y ++#CONFIG_IIO_ST_LSM6DSX=m ++#CONFIG_SENSORS_ISL29018=m ++#CONFIG_VCNL4000=m ++#CONFIG_IIO_ST_MAGN_3AXIS=m ++#CONFIG_MPL3115=m ++CONFIG_PWM=y ++CONFIG_PWM_ROCKCHIP=y ++#CONFIG_PHY_ROCKCHIP_DP=y ++#CONFIG_PHY_ROCKCHIP_DPHY_RX0=y ++CONFIG_PHY_ROCKCHIP_EMMC=y ++CONFIG_PHY_ROCKCHIP_INNO_HDMI=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++#CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=y ++#CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y ++CONFIG_PHY_ROCKCHIP_PCIE=y ++CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y ++#CONFIG_PHY_ROCKCHIP_TYPEC=y ++CONFIG_PHY_ROCKCHIP_USB=y ++#CONFIG_ARM_SMMU_V3_PMU=m ++#CONFIG_ANDROID=y ++#CONFIG_ANDROID_BINDER_IPC=y ++#CONFIG_ANDROID_BINDERFS=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_ROCKCHIP_OTP=y ++#CONFIG_NVMEM_RMEM=m ++#CONFIG_TEE=y ++#CONFIG_OPTEE=y ++CONFIG_MUX_MMIO=y ++# CONFIG_SLIMBUS is not set ++CONFIG_INTERCONNECT=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++#CONFIG_BTRFS_FS=m ++#CONFIG_BTRFS_FS_POSIX_ACL=y ++#CONFIG_F2FS_FS=m ++#CONFIG_FANOTIFY=y ++#CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y ++#CONFIG_QUOTA=y ++CONFIG_AUTOFS4_FS=y ++#CONFIG_FUSE_FS=m ++#CONFIG_CUSE=m ++#CONFIG_OVERLAY_FS=m ++CONFIG_VFAT_FS=y ++#CONFIG_NTFS3_FS=y ++#CONFIG_NTFS3_LZX_XPRESS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_HUGETLBFS=y ++#CONFIG_EFIVAR_FS=y ++#CONFIG_SQUASHFS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_ROOT_NFS=y ++CONFIG_SMB_SERVER=y ++CONFIG_SMB_SERVER_KERBEROS5=y ++#CONFIG_9P_FS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_UNICODE=y ++CONFIG_SECURITY=y ++CONFIG_CRYPTO_CRYPTD=y ++CONFIG_CRYPTO_ECDH=y ++CONFIG_CRYPTO_ECHAINIV=y ++CONFIG_CRYPTO_MD4=y ++#CONFIG_CRYPTO_DES=m ++CONFIG_CRYPTO_ANSI_CPRNG=y ++#CONFIG_CRYPTO_USER_API_RNG=m ++#CONFIG_CRYPTO_DEV_CCREE=m ++#CONFIG_CRYPTO_DEV_HISI_SEC2=m ++#CONFIG_CRYPTO_DEV_HISI_ZIP=m ++#CONFIG_CRYPTO_DEV_HISI_HPRE=m ++#CONFIG_CRYPTO_DEV_HISI_TRNG=m ++#CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m ++CONFIG_PACKING=y ++CONFIG_INDIRECT_PIO=y ++#CONFIG_CRC_CCITT=m ++CONFIG_CRC8=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_PRINTK_TIME=y ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_INFO_REDUCED=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_KERNEL=y ++CONFIG_SOFTLOCKUP_DETECTOR=y ++CONFIG_WQ_WATCHDOG=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_BOOTTIME_TRACING=y ++CONFIG_FUNCTION_TRACER=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_MEMTEST=y ++ ++CONFIG_REGULATOR_FAN53555=y ++ ++#CONFIG_NET_REALTEK_MDIO=y ++#CONFIG_NET_DSA_REALTEK=y ++#CONFIG_NET_DSA_REALTEK_MDIO=y ++CONFIG_MT753X_GSW=y ++CONFIG_NET_DSA_MT7530=y ++ ++CONFIG_DRM_DW_HDMI_I2S_AUDIO=y ++ ++CONFIG_RK_HEADSET=y ++ ++#IR_Driver ++CONFIG_RC_CORE=y ++CONFIG_LIRC=y ++CONFIG_RC_DEVICES=y ++CONFIG_IR_GPIO_CIR=y ++CONFIG_RC_MAP=y ++# Decoders (might be optional) ++CONFIG_RC_DECODERS=y ++CONFIG_IR_IMON_DECODER=y ++CONFIG_IR_JVC_DECODER=y ++CONFIG_IR_MCE_KBD_DECODER=y ++CONFIG_IR_NEC_DECODER=y ++CONFIG_IR_RC5_DECODER=y ++CONFIG_IR_RC6_DECODER=y ++CONFIG_IR_RCMM_DECODER=y ++CONFIG_IR_SANYO_DECODER=y ++CONFIG_IR_SHARP_DECODER=y ++CONFIG_IR_SONY_DECODER=y ++CONFIG_IR_XMP_DECODER=y +diff --git a/bpi-r2pro.its b/bpi-r2pro.its +new file mode 100644 +index 000000000000..48f4031aca1e +--- /dev/null ++++ b/bpi-r2pro.its +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2020 Rockchip Electronics Co., Ltd ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ */ ++ ++/dts-v1/; ++ ++/ { ++ description = "U-Boot fitImage for bpi-r2pro aarch64 kernel"; ++ images { ++ kernel { ++ description = "Linux Kernel %version%"; ++ data = /incbin/("arch/arm64/boot/Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ entry = <0x02080000>; ++ load = <0x02080000>; ++ hash { ++ algo = "sha256"; ++ }; ++ }; ++ fdt { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ compression = "none"; ++ hash { ++ algo = "sha256"; ++ }; ++ }; ++/* ramdisk { ++ data = /incbin/("out/ramdisk"); ++ type = "ramdisk"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "none"; ++ load = <0xffffff02>; ++ hash { ++ algo = "sha256"; ++ }; ++ };*/ ++ }; ++ configurations { ++ default = "conf"; ++ conf { ++ fdt = "fdt"; ++ kernel = "kernel"; ++ //ramdisk = "ramdisk"; ++ }; ++ }; ++}; +diff --git a/bpi-r3.its b/bpi-r3.its +new file mode 100644 +index 000000000000..c92291da749a +--- /dev/null ++++ b/bpi-r3.its +@@ -0,0 +1,162 @@ ++/dts-v1/; ++ ++/ { ++ description = "U-Boot fitImage for bpi-r3 aarch64 kernel"; ++ #address-cells = <1>; ++ ++ images { ++ kernel-1 { ++ description = "Linux Kernel %version%"; ++ data = /incbin/("./arch/arm64/boot/Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ load = <0x44000000>; ++ entry = <0x44000000>; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-base { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ load = <0x47000000>; ++ compression = "none"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-base-mini { ++ description = "Flattened Device Tree blob for r3 mini"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-mini.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ load = <0x47000000>; ++ compression = "none"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-ov-sd { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtbo"); ++ type = "flat_dt"; ++ }; ++ fdt-ov-emmc { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtbo"); ++ type = "flat_dt"; ++ }; ++ fdt-ov-nand{ ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtbo"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ }; ++ fdt-ov-nor{ ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtbo"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ }; ++/* ramdisk-1 { ++ description = "ramdisk"; ++ data = /incbin/("./rootfs_arm64.cpio.gz"); ++ type = "ramdisk"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ };*/ ++ }; ++ configurations { ++ default = "conf-sd"; ++ conf-sd { ++ description = "Boot Linux kernel with SD FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-sd"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-emmc { ++ description = "Boot Linux kernel with EMMC FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-emmc"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-emmc-mini { ++ description = "Boot Linux kernel with R3mini + EMMC FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base-mini", "fdt-ov-emmc"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-sd-nand { ++ description = "Boot Linux kernel with SD+NAND FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-sd", "fdt-ov-nand"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-emmc-nand { ++ description = "Boot Linux kernel with EMMC+NAND FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-emmc", "fdt-ov-nand"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-sd-nor { ++ description = "Boot Linux kernel with SD+NOR FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-sd", "fdt-ov-nor"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ conf-emmc-nor { ++ description = "Boot Linux kernel with EMMC+NOR FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-base", "fdt-ov-emmc", "fdt-ov-nor"; ++ //ramdisk = "ramdisk-1"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ nand { ++ description = "NAND overlay"; ++ fdt = "fdt-ov-nand"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ nor { ++ description = "NOR overlay"; ++ fdt = "fdt-ov-nor"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ sata { ++ description = "SATA overlay"; ++ fdt = "fdt-ov-sata"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ }; ++}; +diff --git a/bpi-r64.its b/bpi-r64.its +new file mode 100644 +index 000000000000..c6b012255a16 +--- /dev/null ++++ b/bpi-r64.its +@@ -0,0 +1,55 @@ ++/dts-v1/; ++ ++/ { ++ description = "U-Boot fitImage for bpi-r64 aarch64 kernel"; ++ #address-cells = <1>; ++ ++ images { ++ kernel-1 { ++ description = "Linux Kernel %version%"; ++ data = /incbin/("./arch/arm64/boot/Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ load = <0x40080000>; ++ entry = <0x40080000>; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ fdt-1 { ++ description = "Flattened Device Tree blob"; ++ data = /incbin/("./arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ compression = "none"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++/* ramdisk@0 { ++ description = "ramdisk"; ++ data = /incbin/("./ramdisk.cpio"); ++ type = "ramdisk"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "none"; ++ hash@1 { ++ algo = "sha1"; ++ }; ++ };*/ ++ }; ++ configurations { ++ default = "conf-1"; ++ conf-1 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel-1"; ++ fdt = "fdt-1"; ++ //ramdisk = "ramdisk@0"; ++ hash-1 { ++ algo = "sha1"; ++ }; ++ }; ++ }; ++}; +diff --git a/build.conf b/build.conf +index 60d7ff7a4859..7681a4e75ce5 100644 +--- a/build.conf ++++ b/build.conf +@@ -13,7 +13,7 @@ board=bpi-r2 + #board=bpi-r64 + #board=bpi-r2pro + #board=bpi-r3 +-board=bpi-r4 ++#board=bpi-r4 + + #r64 with rtl8367 + #boardversion=v0.1 +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0008-defconfig-r3-fix-warning-about-BASE_SMALL.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0008-defconfig-r3-fix-warning-about-BASE_SMALL.patch new file mode 100644 index 000000000..e2ed87a83 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0008-defconfig-r3-fix-warning-about-BASE_SMALL.patch @@ -0,0 +1,25 @@ +From 4b3f2fdb02d16d5346b4b6c14f51a7000a3c5325 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 16 Jun 2025 09:03:11 +0200 +Subject: [PATCH 08/84] defconfig: r3: fix warning about BASE_SMALL + +--- + arch/arm64/configs/mt7986a_bpi-r3_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/mt7986a_bpi-r3_defconfig b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +index fccecc3b2375..32710280133d 100644 +--- a/arch/arm64/configs/mt7986a_bpi-r3_defconfig ++++ b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +@@ -21,7 +21,7 @@ CONFIG_ATA_SFF=y + CONFIG_ATM_BR2684_IPFILTER=y + CONFIG_ATM_CLIP_NO_ICMP=y + CONFIG_BASE_FULL=y +-CONFIG_BASE_SMALL=0 ++CONFIG_BASE_SMALL=n + CONFIG_BCMA_POSSIBLE=y + CONFIG_BINARY_PRINTF=y + CONFIG_BINFMT_ELF=y +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0009-build.conf-change-upload-target.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0009-build.conf-change-upload-target.patch new file mode 100644 index 000000000..57f4f3b86 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0009-build.conf-change-upload-target.patch @@ -0,0 +1,23 @@ +From b72f0fe031ab48a161637592b03012372dc6bcc7 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 16 Jun 2025 09:03:51 +0200 +Subject: [PATCH 09/84] build.conf: change upload target + +--- + build.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/build.conf b/build.conf +index 7681a4e75ce5..c6521172e2da 100644 +--- a/build.conf ++++ b/build.conf +@@ -1,5 +1,5 @@ + uploaduser=$USER +-uploadserver=r2 ++uploadserver=r3 + uploaddir=/var/lib/tftp + #uploaduser=root + #uploadserver=192.168.0.11 +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0010-arm-dts-mt7623-swap-mmc-and-put-uart2-first.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0010-arm-dts-mt7623-swap-mmc-and-put-uart2-first.patch new file mode 100644 index 000000000..1644d3eec --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0010-arm-dts-mt7623-swap-mmc-and-put-uart2-first.patch @@ -0,0 +1,87 @@ +From 1d780489e2f3b5de6d922d30a1a258113a031cef Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 12 Jul 2021 09:00:02 +0200 +Subject: [PATCH 10/84] arm: dts: mt7623: swap mmc and put uart2 first + +--- + arch/arm/boot/dts/mediatek/mt7623.dtsi | 42 +++++++++++++------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi +index fd7a89cc337d..0ad545ec0734 100644 +--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi ++++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi +@@ -372,6 +372,17 @@ auxadc: adc@11001000 { + #io-channel-cells = <1>; + }; + ++ uart2: serial@11004000 { ++ compatible = "mediatek,mt7623-uart", ++ "mediatek,mt6577-uart"; ++ reg = <0 0x11004000 0 0x400>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_UART2_SEL>, ++ <&pericfg CLK_PERI_UART2>; ++ clock-names = "baud", "bus"; ++ status = "disabled"; ++ }; ++ + uart0: serial@11002000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; +@@ -394,17 +405,6 @@ uart1: serial@11003000 { + status = "disabled"; + }; + +- uart2: serial@11004000 { +- compatible = "mediatek,mt7623-uart", +- "mediatek,mt6577-uart"; +- reg = <0 0x11004000 0 0x400>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_UART2_SEL>, +- <&pericfg CLK_PERI_UART2>; +- clock-names = "baud", "bus"; +- status = "disabled"; +- }; +- + uart3: serial@11005000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; +@@ -712,24 +712,24 @@ afe: audio-controller { + }; + }; + +- mmc0: mmc@11230000 { ++ mmc1: mmc@11240000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; +- reg = <0 0x11230000 0 0x1000>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_MSDC30_0>, +- <&topckgen CLK_TOP_MSDC30_0_SEL>; ++ reg = <0 0x11240000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_MSDC30_1>, ++ <&topckgen CLK_TOP_MSDC30_1_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + +- mmc1: mmc@11240000 { ++ mmc0: mmc@11230000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; +- reg = <0 0x11240000 0 0x1000>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_MSDC30_1>, +- <&topckgen CLK_TOP_MSDC30_1_SEL>; ++ reg = <0 0x11230000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_MSDC30_0>, ++ <&topckgen CLK_TOP_MSDC30_0_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0011-arm64-dts-disable-dtbs-for-dtbs_check.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0011-arm64-dts-disable-dtbs-for-dtbs_check.patch new file mode 100644 index 000000000..38240e1f4 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0011-arm64-dts-disable-dtbs-for-dtbs_check.patch @@ -0,0 +1,307 @@ +From 475a62480df18eb13c58fcfd75f0337cb2749104 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 11 Apr 2025 08:45:54 +0200 +Subject: [PATCH 11/84] arm64: dts: disable dtbs for dtbs_check + +--- + arch/arm64/boot/dts/Makefile | 70 ++++----- + arch/arm64/boot/dts/mediatek/Makefile | 204 +++++++++++++------------- + 2 files changed, 137 insertions(+), 137 deletions(-) + +diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile +index 79b73a21ddc2..42ebeaeedf3b 100644 +--- a/arch/arm64/boot/dts/Makefile ++++ b/arch/arm64/boot/dts/Makefile +@@ -1,37 +1,37 @@ + # SPDX-License-Identifier: GPL-2.0 +-subdir-y += actions +-subdir-y += airoha +-subdir-y += allwinner +-subdir-y += altera +-subdir-y += amazon +-subdir-y += amd +-subdir-y += amlogic +-subdir-y += apm +-subdir-y += apple +-subdir-y += arm +-subdir-y += bitmain +-subdir-y += blaize +-subdir-y += broadcom +-subdir-y += cavium +-subdir-y += exynos +-subdir-y += freescale +-subdir-y += hisilicon +-subdir-y += intel +-subdir-y += lg +-subdir-y += marvell ++#subdir-y += actions ++#subdir-y += airoha ++#subdir-y += allwinner ++#subdir-y += altera ++#subdir-y += amazon ++#subdir-y += amd ++#subdir-y += amlogic ++#subdir-y += apm ++#subdir-y += apple ++#subdir-y += arm ++#subdir-y += bitmain ++#subdir-y += blaize ++#subdir-y += broadcom ++#subdir-y += cavium ++#subdir-y += exynos ++#subdir-y += freescale ++#subdir-y += hisilicon ++#subdir-y += intel ++#subdir-y += lg ++#subdir-y += marvell + subdir-y += mediatek +-subdir-y += microchip +-subdir-y += nuvoton +-subdir-y += nvidia +-subdir-y += qcom +-subdir-y += realtek +-subdir-y += renesas +-subdir-y += rockchip +-subdir-y += socionext +-subdir-y += sprd +-subdir-y += st +-subdir-y += synaptics +-subdir-y += tesla +-subdir-y += ti +-subdir-y += toshiba +-subdir-y += xilinx ++#subdir-y += microchip ++#subdir-y += nuvoton ++#subdir-y += nvidia ++#subdir-y += qcom ++#subdir-y += realtek ++#subdir-y += renesas ++#subdir-y += rockchip ++#subdir-y += socionext ++#subdir-y += sprd ++#subdir-y += st ++#subdir-y += synaptics ++#subdir-y += tesla ++#subdir-y += ti ++#subdir-y += toshiba ++#subdir-y += xilinx +diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile +index f68865d06edd..e60462fa2b6f 100644 +--- a/arch/arm64/boot/dts/mediatek/Makefile ++++ b/arch/arm64/boot/dts/mediatek/Makefile +@@ -1,110 +1,110 @@ + # SPDX-License-Identifier: GPL-2.0 +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6779-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-sony-xperia-m5.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-openwrt-one.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6779-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-sony-xperia-m5.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-openwrt-one.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku2.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku3.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku4.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku5.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku6.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku7.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-dojo-r1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r2.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r3.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8370-genio-510-evk.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8390-genio-700-evk.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l-8-hd-panel.dtbo +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku2.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku3.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku4.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku5.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku6.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku7.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-dojo-r1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r2.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r3.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8370-genio-510-evk.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8390-genio-700-evk.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l-8-hd-panel.dtbo ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb + + # Device tree overlays support + DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0012-dt-bindings-interconnect-add-mt7988-cci-compatible.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0012-dt-bindings-interconnect-add-mt7988-cci-compatible.patch new file mode 100644 index 000000000..4c1af16c0 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0012-dt-bindings-interconnect-add-mt7988-cci-compatible.patch @@ -0,0 +1,45 @@ +From 8aa7779a777a3b78193affeca2676039052f7a08 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 20 May 2025 19:04:22 +0200 +Subject: [PATCH 12/84] dt-bindings: interconnect: add mt7988-cci compatible + +Add compatible for Mediatek MT7988 SoC with mediatek,mt8183-cci fallback +which is taken by driver. + +Signed-off-by: Frank Wunderlich +Acked-by: Rob Herring (Arm) +Reviewed-by: AngeloGioacchino Del Regno +Acked-by: Georgi Djakov +--- +v2: +- no RFC +- drop "items" as sugested by conor +--- + .../bindings/interconnect/mediatek,cci.yaml | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/interconnect/mediatek,cci.yaml b/Documentation/devicetree/bindings/interconnect/mediatek,cci.yaml +index 58611ba2a0f4..4d72525f407e 100644 +--- a/Documentation/devicetree/bindings/interconnect/mediatek,cci.yaml ++++ b/Documentation/devicetree/bindings/interconnect/mediatek,cci.yaml +@@ -17,9 +17,14 @@ description: | + + properties: + compatible: +- enum: +- - mediatek,mt8183-cci +- - mediatek,mt8186-cci ++ oneOf: ++ - enum: ++ - mediatek,mt8183-cci ++ - mediatek,mt8186-cci ++ - items: ++ - enum: ++ - mediatek,mt7988-cci ++ - const: mediatek,mt8183-cci + + clocks: + items: +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0013-arm64-dts-mediatek-mt7988-add-cci-node.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0013-arm64-dts-mediatek-mt7988-add-cci-node.patch new file mode 100644 index 000000000..c5161bad8 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0013-arm64-dts-mediatek-mt7988-add-cci-node.patch @@ -0,0 +1,92 @@ +From a6bb99087048bd61a6f71a76f6d5bda171da5fd7 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 1 Feb 2025 15:22:59 +0100 +Subject: [PATCH 13/84] arm64: dts: mediatek: mt7988: add cci node + +Add cci devicetree node for cpu frequency scaling. + +Signed-off-by: Daniel Golle +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- +v3: +- add mt7988-cci compatible as suggested by angelo +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 33 +++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index c46b31f8d653..560ec86dbec0 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -12,6 +12,35 @@ / { + #address-cells = <2>; + #size-cells = <2>; + ++ cci: cci { ++ compatible = "mediatek,mt7988-cci", "mediatek,mt8183-cci"; ++ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>, ++ <&topckgen CLK_TOP_XTAL>; ++ clock-names = "cci", "intermediate"; ++ operating-points-v2 = <&cci_opp>; ++ }; ++ ++ cci_opp: opp-table-cci { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ opp-480000000 { ++ opp-hz = /bits/ 64 <480000000>; ++ opp-microvolt = <850000>; ++ }; ++ opp-660000000 { ++ opp-hz = /bits/ 64 <660000000>; ++ opp-microvolt = <850000>; ++ }; ++ opp-900000000 { ++ opp-hz = /bits/ 64 <900000000>; ++ opp-microvolt = <850000>; ++ }; ++ opp-1080000000 { ++ opp-hz = /bits/ 64 <1080000000>; ++ opp-microvolt = <900000>; ++ }; ++ }; ++ + cpus { + #address-cells = <1>; + #size-cells = <0>; +@@ -25,6 +54,7 @@ cpu0: cpu@0 { + <&topckgen CLK_TOP_XTAL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; ++ mediatek,cci = <&cci>; + }; + + cpu1: cpu@1 { +@@ -36,6 +66,7 @@ cpu1: cpu@1 { + <&topckgen CLK_TOP_XTAL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; ++ mediatek,cci = <&cci>; + }; + + cpu2: cpu@2 { +@@ -47,6 +78,7 @@ cpu2: cpu@2 { + <&topckgen CLK_TOP_XTAL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; ++ mediatek,cci = <&cci>; + }; + + cpu3: cpu@3 { +@@ -58,6 +90,7 @@ cpu3: cpu@3 { + <&topckgen CLK_TOP_XTAL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; ++ mediatek,cci = <&cci>; + }; + + cluster0_opp: opp-table-0 { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0014-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0014-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch new file mode 100644 index 000000000..3b029f2c5 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0014-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch @@ -0,0 +1,32 @@ +From 6d1ea6d069461b0a97af8295fc5c46542b5b1cb4 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 4 May 2025 15:17:13 +0200 +Subject: [PATCH 14/84] arm64: dts: mediatek: mt7988a-bpi-r4: add proc-supply + for cci + +CCI requires proc-supply. Add it on board level. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- + arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 81ba045e0e0e..afa9e3b2b16a 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -40,6 +40,10 @@ reg_3p3v: regulator-3p3v { + }; + }; + ++&cci { ++ proc-supply = <&rt5190_buck3>; ++}; ++ + &cpu0 { + proc-supply = <&rt5190_buck3>; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0015-arm64-dts-mediatek-mt7988a-bpi-r4-drop-unused-pins.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0015-arm64-dts-mediatek-mt7988a-bpi-r4-drop-unused-pins.patch new file mode 100644 index 000000000..2ba6f3a74 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0015-arm64-dts-mediatek-mt7988a-bpi-r4-drop-unused-pins.patch @@ -0,0 +1,151 @@ +From 84dc2ca96d2acd136085ab98fcc92176c1be1aa9 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 17 May 2025 09:04:19 +0200 +Subject: [PATCH 15/84] arm64: dts: mediatek: mt7988a-bpi-r4: drop unused pins + +Pins were moved from SoC dtsi to Board level dtsi without cleaning up +to needed ones. Drop the unused pins now. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 89 ------------------- + 1 file changed, 89 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index afa9e3b2b16a..30affedf84d4 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -223,18 +223,6 @@ &pcie3 { + }; + + &pio { +- mdio0_pins: mdio0-pins { +- mux { +- function = "eth"; +- groups = "mdc_mdio0"; +- }; +- +- conf { +- pins = "SMI_0_MDC", "SMI_0_MDIO"; +- drive-strength = <8>; +- }; +- }; +- + i2c0_pins: i2c0-g0-pins { + mux { + function = "i2c"; +@@ -249,20 +237,6 @@ mux { + }; + }; + +- i2c1_sfp_pins: i2c1-sfp-g0-pins { +- mux { +- function = "i2c"; +- groups = "i2c1_sfp"; +- }; +- }; +- +- i2c2_0_pins: i2c2-g0-pins { +- mux { +- function = "i2c"; +- groups = "i2c2_0"; +- }; +- }; +- + i2c2_1_pins: i2c2-g1-pins { + mux { + function = "i2c"; +@@ -298,34 +272,6 @@ mux { + }; + }; + +- gbe0_led1_pins: gbe0-led1-pins { +- mux { +- function = "led"; +- groups = "gbe0_led1"; +- }; +- }; +- +- gbe1_led1_pins: gbe1-led1-pins { +- mux { +- function = "led"; +- groups = "gbe1_led1"; +- }; +- }; +- +- gbe2_led1_pins: gbe2-led1-pins { +- mux { +- function = "led"; +- groups = "gbe2_led1"; +- }; +- }; +- +- gbe3_led1_pins: gbe3-led1-pins { +- mux { +- function = "led"; +- groups = "gbe3_led1"; +- }; +- }; +- + i2p5gbe_led0_pins: 2p5gbe-led0-pins { + mux { + function = "led"; +@@ -333,13 +279,6 @@ mux { + }; + }; + +- i2p5gbe_led1_pins: 2p5gbe-led1-pins { +- mux { +- function = "led"; +- groups = "2p5gbe_led1"; +- }; +- }; +- + mmc0_pins_emmc_45: mmc0-emmc-45-pins { + mux { + function = "flash"; +@@ -361,40 +300,12 @@ mux { + }; + }; + +- snfi_pins: snfi-pins { +- mux { +- function = "flash"; +- groups = "snfi"; +- }; +- }; +- +- spi0_pins: spi0-pins { +- mux { +- function = "spi"; +- groups = "spi0"; +- }; +- }; +- + spi0_flash_pins: spi0-flash-pins { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + }; +- +- spi2_pins: spi2-pins { +- mux { +- function = "spi"; +- groups = "spi2"; +- }; +- }; +- +- spi2_flash_pins: spi2-flash-pins { +- mux { +- function = "spi"; +- groups = "spi2", "spi2_wp_hold"; +- }; +- }; + }; + + &pwm { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0016-arm64-dts-mediatek-mt7988a-bpi-r4-add-gpio-leds.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0016-arm64-dts-mediatek-mt7988a-bpi-r4-add-gpio-leds.patch new file mode 100644 index 000000000..d985f8ce9 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0016-arm64-dts-mediatek-mt7988a-bpi-r4-add-gpio-leds.patch @@ -0,0 +1,50 @@ +From c5a6b9feed48fc85b9dcae3b0a171df317e159f7 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 4 Jun 2025 17:50:22 +0200 +Subject: [PATCH 16/84] arm64: dts: mediatek: mt7988a-bpi-r4: add gpio leds + +Bananapi R4 has a green and a blue led which can be switched by gpio. +Green led is for running state so default on. + +Green led also shares pin with eeprom writeprotect where led off allows +writing to eeprom. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 30affedf84d4..21eb91c8609f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -21,6 +21,25 @@ fan: pwm-fan { + status = "okay"; + }; + ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_green: led-green { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&pio 79 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led_blue: led-blue { ++ function = LED_FUNCTION_WPS; ++ color = ; ++ gpios = <&pio 63 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0017-v9-coverletter-further-mt7988-devicetree-work.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0017-v9-coverletter-further-mt7988-devicetree-work.patch new file mode 100644 index 000000000..e69de29bb diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0018-dt-bindings-net-mediatek-net-update-mac-subnode-patt.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0018-dt-bindings-net-mediatek-net-update-mac-subnode-patt.patch new file mode 100644 index 000000000..23026e348 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0018-dt-bindings-net-mediatek-net-update-mac-subnode-patt.patch @@ -0,0 +1,32 @@ +From a156ad0546aec9ecca31c219f9658be8475d752b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 3 Jul 2025 20:19:35 +0200 +Subject: [PATCH 18/84] dt-bindings: net: mediatek,net: update mac subnode + pattern for mt7988 + +MT7888 have 3 Macs and so its nodes have names from mac0 - mac2. Update +pattern to fix this. + +Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding") +Signed-off-by: Frank Wunderlich +Reviewed-by: Krzysztof Kozlowski +--- + Documentation/devicetree/bindings/net/mediatek,net.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml +index 9e02fd80af83..175d1d011dc6 100644 +--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml ++++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml +@@ -382,7 +382,7 @@ allOf: + - const: xgp3 + + patternProperties: +- "^mac@[0-1]$": ++ "^mac@[0-2]$": + type: object + unevaluatedProperties: false + allOf: +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0019-dt-bindings-net-mediatek-net-allow-up-to-8-IRQs.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0019-dt-bindings-net-mediatek-net-allow-up-to-8-IRQs.patch new file mode 100644 index 000000000..f5749a79c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0019-dt-bindings-net-mediatek-net-allow-up-to-8-IRQs.patch @@ -0,0 +1,90 @@ +From 35f241527f0146b5608a2239684005469bca4d4d Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 3 Jul 2025 20:22:18 +0200 +Subject: [PATCH 19/84] dt-bindings: net: mediatek,net: allow up to 8 IRQs + +Increase the maximum IRQ count to 8 (4 FE + 4 RSS/LRO). + +Frame-engine-IRQs (max 4): +MT7621, MT7628: 1 FE-IRQ +MT7622, MT7623: 3 FE-IRQs (only two used by the driver for now) +MT7981, MT7986, MT7988: 4 FE-IRQs (only two used by the driver for now) + +Mediatek Filogic SoCs (mt798x) have 4 additional IRQs for RSS and/or +LRO. So MT798x have 8 IRQs in total. + +MT7981 does not have a ethernet-node yet. +MT7986 Ethernet node is updated with RSS/LRO IRQs in this series. +MT7988 Ethernet node is added in this series. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Krzysztof Kozlowski +--- +v9: +- set interrupt minitems to 8 for filogic + - mt7981 does not have a ethernet node yet, so no ABI break + - devicetree for mt7986 is updated later in this series, ABI-Break, + but RSS/LRO should use interrupt names and is simply disabled when + using older DT +- extend mt7986 example with PDMA-IRQs because minItems now 8 +v8: separate irq-count change from interrupt-names patch +--- + .../devicetree/bindings/net/mediatek,net.yaml | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml +index 175d1d011dc6..99dc0401eb9a 100644 +--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml ++++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml +@@ -40,7 +40,7 @@ properties: + + interrupts: + minItems: 1 +- maxItems: 4 ++ maxItems: 8 + + power-domains: + maxItems: 1 +@@ -272,7 +272,7 @@ allOf: + then: + properties: + interrupts: +- minItems: 4 ++ minItems: 8 + + clocks: + minItems: 15 +@@ -310,7 +310,7 @@ allOf: + then: + properties: + interrupts: +- minItems: 4 ++ minItems: 8 + + clocks: + minItems: 15 +@@ -348,7 +348,7 @@ allOf: + then: + properties: + interrupts: +- minItems: 4 ++ minItems: 8 + + clocks: + minItems: 24 +@@ -507,7 +507,11 @@ examples: + interrupts = , + , + , +- ; ++ , ++ , ++ , ++ , ++ ; + clocks = <ðsys CLK_ETH_FE_EN>, + <ðsys CLK_ETH_GP2_EN>, + <ðsys CLK_ETH_GP1_EN>, +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0020-dt-bindings-net-mediatek-net-allow-irq-names.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0020-dt-bindings-net-mediatek-net-allow-irq-names.patch new file mode 100644 index 000000000..49ddcda03 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0020-dt-bindings-net-mediatek-net-allow-irq-names.patch @@ -0,0 +1,141 @@ +From 2c7be45741bd444a44e0bf18a010ce378396d8ac Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 3 Jul 2025 20:31:42 +0200 +Subject: [PATCH 20/84] dt-bindings: net: mediatek,net: allow irq names + +In preparation for MT7988 and RSS/LRO allow the interrupt-names +property. +In this way driver can request the interrupts by name which is much +more readable in the driver code and SoC's dtsi than relying on a +specific order. + +Frame-engine-IRQs (fe0..3): +MT7621, MT7628: 1 FE-IRQ +MT7622, MT7623: 3 FE-IRQs (only two used by the driver for now) +MT7981, MT7986: 4 FE-IRQs (only two used by the driver for now) + +RSS/LRO IRQs (pdma0..3) additional only on Filogic (MT798x) with +count of 4. So all IRQ-names (8) for Filogic. + +Set boundaries for all compatibles same as irq count. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Krzysztof Kozlowski +--- +v9: +- add interrupt-names minitems to 8 for filogic + - mt7981 does not have a ethernet node yet + - devicetree for mt7986 is updated later in this series +- small rephrase IRQ => FE-IRQ and mention total count of IRQs on Filogic. +- kept angelos RB because of small change, i hope it is ok :) + +v8: + - fixed typo in mt7621 section "interrupt-namess" + - separated interrupt count from interrupt-names + - rephrased description a bit to explain the "why" +v7: fixed wrong rebase +v6: new patch splitted from the mt7988 changes +--- + .../devicetree/bindings/net/mediatek,net.yaml | 36 +++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml +index 99dc0401eb9a..d2b5461e73bc 100644 +--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml ++++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml +@@ -42,6 +42,18 @@ properties: + minItems: 1 + maxItems: 8 + ++ interrupt-names: ++ minItems: 1 ++ items: ++ - const: fe0 ++ - const: fe1 ++ - const: fe2 ++ - const: fe3 ++ - const: pdma0 ++ - const: pdma1 ++ - const: pdma2 ++ - const: pdma3 ++ + power-domains: + maxItems: 1 + +@@ -135,6 +147,10 @@ allOf: + minItems: 3 + maxItems: 3 + ++ interrupt-names: ++ minItems: 3 ++ maxItems: 3 ++ + clocks: + minItems: 4 + maxItems: 4 +@@ -166,6 +182,9 @@ allOf: + interrupts: + maxItems: 1 + ++ interrupt-names: ++ maxItems: 1 ++ + clocks: + minItems: 2 + maxItems: 2 +@@ -192,6 +211,10 @@ allOf: + minItems: 3 + maxItems: 3 + ++ interrupt-names: ++ minItems: 3 ++ maxItems: 3 ++ + clocks: + minItems: 11 + maxItems: 11 +@@ -232,6 +255,10 @@ allOf: + minItems: 3 + maxItems: 3 + ++ interrupt-names: ++ minItems: 3 ++ maxItems: 3 ++ + clocks: + minItems: 17 + maxItems: 17 +@@ -274,6 +301,9 @@ allOf: + interrupts: + minItems: 8 + ++ interrupt-names: ++ minItems: 8 ++ + clocks: + minItems: 15 + maxItems: 15 +@@ -312,6 +342,9 @@ allOf: + interrupts: + minItems: 8 + ++ interrupt-names: ++ minItems: 8 ++ + clocks: + minItems: 15 + maxItems: 15 +@@ -350,6 +383,9 @@ allOf: + interrupts: + minItems: 8 + ++ interrupt-names: ++ minItems: 8 ++ + clocks: + minItems: 24 + maxItems: 24 +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0021-dt-bindings-net-mediatek-net-add-sram-property.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0021-dt-bindings-net-mediatek-net-add-sram-property.patch new file mode 100644 index 000000000..c94f2164d --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0021-dt-bindings-net-mediatek-net-add-sram-property.patch @@ -0,0 +1,107 @@ +From ceafe6027cde06a1216ceb52a1f2da05d4c564fd Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 28 Jun 2025 10:42:49 +0200 +Subject: [PATCH 21/84] dt-bindings: net: mediatek,net: add sram property + +Meditak Filogic SoCs (MT798x) have dedicated MMIO-SRAM for dma operations. + +MT7981 and MT7986 currently use static offset to ethernet MAC register +which will be changed in separate patch once this way is accepted. + +Add "sram" property to map ethernet controller to dedicated mmio-sram node. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Krzysztof Kozlowski +--- +v9: +- add "sram: false" for non-filogic + +v8: +- splitted out mac subnode pattern +- dropped reg naming change +- rephrased description +- drop change of reg-name + +v6: +- split out the interrupt-names into separate patch +- update irq(name) min count to 4 +- add sram-property +- drop second reg entry and minitems as there is only 1 item left again + +v5: +- fix v4 logmessage and change description a bit describing how i get + the irq count. +- update binding for 8 irqs with different names (rx,tx => fe0..fe3) + including the 2 reserved irqs which can be used later +- change rx-ringX to pdmaX to be closer to hardware documentation + +v4: +- increase max interrupts to 6 because of adding RSS/LRO interrupts (4) + and dropping 2 reserved irqs (0+3) around rx+tx +- dropped Robs RB due to this change +- allow interrupt names +- add interrupt-names without reserved IRQs on mt7988 + this requires mtk driver patch: + https://patchwork.kernel.org/project/netdevbpf/patch/20250616080738.117993-2-linux@fw-web.de/ + +v2: +- change reg to list of items +--- + .../devicetree/bindings/net/mediatek,net.yaml | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml +index d2b5461e73bc..b45f67f92e80 100644 +--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml ++++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml +@@ -66,6 +66,10 @@ properties: + - const: gmac + - const: ppe + ++ sram: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: phandle to mmio SRAM ++ + mediatek,ethsys: + $ref: /schemas/types.yaml#/definitions/phandle + description: +@@ -162,6 +166,8 @@ allOf: + - const: gp1 + - const: gp2 + ++ sram: false ++ + mediatek,infracfg: false + + mediatek,wed: false +@@ -194,6 +200,8 @@ allOf: + - const: ethif + - const: fe + ++ sram: false ++ + mediatek,infracfg: false + + mediatek,wed: false +@@ -233,6 +241,8 @@ allOf: + - const: sgmii_ck + - const: eth2pll + ++ sram: false ++ + mediatek,infracfg: false + + mediatek,sgmiisys: +@@ -283,6 +293,8 @@ allOf: + - const: sgmii_ck + - const: eth2pll + ++ sram: false ++ + mediatek,sgmiisys: + minItems: 2 + maxItems: 2 +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0022-dt-bindings-net-dsa-mediatek-mt7530-add-dsa-port-def.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0022-dt-bindings-net-dsa-mediatek-mt7530-add-dsa-port-def.patch new file mode 100644 index 000000000..72a22527c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0022-dt-bindings-net-dsa-mediatek-mt7530-add-dsa-port-def.patch @@ -0,0 +1,51 @@ +From 7334c38f35771ab025253b803990d07864ca1ffb Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 6 May 2025 17:29:16 +0200 +Subject: [PATCH 22/84] dt-bindings: net: dsa: mediatek,mt7530: add dsa-port + definition for mt7988 + +Add own dsa-port binding for SoC with internal switch where only phy-mode +'internal' is valid. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Rob Herring (Arm) +Reviewed-by: AngeloGioacchino Del Regno +--- + .../bindings/net/dsa/mediatek,mt7530.yaml | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml +index 51205f9f2985..9b983fdbf3c7 100644 +--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml ++++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml +@@ -190,6 +190,18 @@ required: + - reg + + $defs: ++ builtin-dsa-port: ++ patternProperties: ++ "^(ethernet-)?ports$": ++ patternProperties: ++ "^(ethernet-)?port@[0-6]$": ++ if: ++ required: [ ethernet ] ++ then: ++ properties: ++ phy-mode: ++ const: internal ++ + mt7530-dsa-port: + patternProperties: + "^(ethernet-)?ports$": +@@ -297,7 +309,7 @@ allOf: + - airoha,en7581-switch + - airoha,an7583-switch + then: +- $ref: "#/$defs/mt7530-dsa-port" ++ $ref: "#/$defs/builtin-dsa-port" + properties: + gpio-controller: false + mediatek,mcm: false +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0023-dt-bindings-net-dsa-mediatek-mt7530-add-internal-mdi.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0023-dt-bindings-net-dsa-mediatek-mt7530-add-internal-mdi.patch new file mode 100644 index 000000000..60a0b7a9a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0023-dt-bindings-net-dsa-mediatek-mt7530-add-internal-mdi.patch @@ -0,0 +1,44 @@ +From 71bb13e3a85a6efd666cb698acb3f8227a7f2fa5 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 6 May 2025 18:56:25 +0200 +Subject: [PATCH 23/84] dt-bindings: net: dsa: mediatek,mt7530: add internal + mdio bus + +Mt7988 buildin switch has own mdio bus where ge-phys are connected. +Add related property for this. + +Signed-off-by: Frank Wunderlich +Reviewed-by: Rob Herring (Arm) +Reviewed-by: AngeloGioacchino Del Regno +--- +v2: +- change from patternproperty to property +- add unevaluatedProperties and mediatek,pio subproperty +--- + .../devicetree/bindings/net/dsa/mediatek,mt7530.yaml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml +index 9b983fdbf3c7..815a90808901 100644 +--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml ++++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml +@@ -136,6 +136,16 @@ properties: + See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt for + details for the regulator setup on these boards. + ++ mdio: ++ $ref: /schemas/net/mdio.yaml# ++ unevaluatedProperties: false ++ ++ properties: ++ mediatek,pio: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle pointing to the mediatek pinctrl node. ++ + mediatek,mcm: + type: boolean + description: +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0024-arm64-dts-mediatek-mt7986-add-sram-node.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0024-arm64-dts-mediatek-mt7986-add-sram-node.patch new file mode 100644 index 000000000..54b10c9aa --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0024-arm64-dts-mediatek-mt7986-add-sram-node.patch @@ -0,0 +1,53 @@ +From 088c4b18aeb6c7be84f381549a331a26735db576 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 27 Jun 2025 22:58:16 +0200 +Subject: [PATCH 24/84] arm64: dts: mediatek: mt7986: add sram node + +Currently sram is allocated in driver via offset from reg of ethernet +node. Change it to use a dedicated sram node like mt7988. + +Signed-off-by: Frank Wunderlich +--- + arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index 559990dcd1d1..550f569451fb 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -523,7 +523,7 @@ wed1: wed@15011000 { + + eth: ethernet@15100000 { + compatible = "mediatek,mt7986-eth"; +- reg = <0 0x15100000 0 0x80000>; ++ reg = <0 0x15100000 0 0x40000>; + interrupts = , + , + , +@@ -553,6 +553,7 @@ eth: ethernet@15100000 { + <&topckgen CLK_TOP_SGM_325M_SEL>; + assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, + <&apmixedsys CLK_APMIXED_SGMPLL>; ++ sram = <ð_sram>; + #address-cells = <1>; + #size-cells = <0>; + mediatek,ethsys = <ðsys>; +@@ -562,6 +563,15 @@ eth: ethernet@15100000 { + status = "disabled"; + }; + ++ /*15100000+0x40000*/ ++ eth_sram: sram@15140000 { ++ compatible = "mmio-sram"; ++ reg = <0 0x15140000 0 0x40000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x15140000 0 0x40000>; ++ }; ++ + wo_ccif0: syscon@151a5000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151a5000 0 0x1000>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0025-arm64-dts-mediatek-mt7986-add-interrupts-for-RSS-and.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0025-arm64-dts-mediatek-mt7986-add-interrupts-for-RSS-and.patch new file mode 100644 index 000000000..7ed03b3da --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0025-arm64-dts-mediatek-mt7986-add-interrupts-for-RSS-and.patch @@ -0,0 +1,36 @@ +From 676b92ba3ccac93969807ec86cfde2acbe80f99a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 12 Mar 2025 18:11:21 +0100 +Subject: [PATCH 25/84] arm64: dts: mediatek: mt7986: add interrupts for RSS + and interrupt names + +Add interrupts for RSS/LRO and names to access them via name instead of +index. + +Signed-off-by: Frank Wunderlich +--- + arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index 550f569451fb..a9e079fd42c6 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -527,7 +527,13 @@ eth: ethernet@15100000 { + interrupts = , + , + , +- ; ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = "fe0", "fe1", "fe2", "fe3", "pdma0", ++ "pdma1", "pdma2", "pdma3"; + clocks = <ðsys CLK_ETH_FE_EN>, + <ðsys CLK_ETH_GP2_EN>, + <ðsys CLK_ETH_GP1_EN>, +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0026-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0026-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch new file mode 100644 index 000000000..1a11f351f --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0026-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch @@ -0,0 +1,208 @@ +From db0b8ad2dbed7ab767af5684c83aea353d11e327 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 28 Nov 2024 18:48:07 +0100 +Subject: [PATCH 26/84] arm64: dts: mediatek: mt7988: add basic ethernet-nodes + +Add basic ethernet related nodes. + +Mac1+2 needs pcs (sgmii+usxgmii) to work correctly which will be linked +later when driver is merged. + +Signed-off-by: Daniel Golle +Signed-off-by: Frank Wunderlich +--- +v8: +- change ethernet register size to 0x40000 + range from 0x15140000 ~ 0x1517ffff is not usable on mt7988 => 0xDEADBEEF + +v6: +- fix whitespace-errors for pdma irqs (spaces vs. tabs) +- move sram from eth reg to own sram node (needs CONFIG_SRAM) + +v5: +- add reserved irqs and change names to fe0..fe3 +- change rx-ringX to pdmaX to be closer to documentation + +v4: +- comment for fixed-link on gmac0 +- update 2g5 phy node + - unit-name dec instead of hex to match reg property + - move compatible before reg + - drop phy-mode +- add interrupts for RSS +- add interrupt-names and drop reserved irqs for ethernet +- some reordering +- eth-reg and clock whitespace-fix based on angelos review +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 137 +++++++++++++++++++++- + 1 file changed, 134 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index 560ec86dbec0..897b5a82b53e 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -680,7 +680,28 @@ xphyu3port0: usb-phy@11e13000 { + }; + }; + +- clock-controller@11f40000 { ++ xfi_tphy0: phy@11f20000 { ++ compatible = "mediatek,mt7988-xfi-tphy"; ++ reg = <0 0x11f20000 0 0x10000>; ++ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, ++ <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>; ++ clock-names = "xfipll", "topxtal"; ++ resets = <&watchdog 14>; ++ mediatek,usxgmii-performance-errata; ++ #phy-cells = <0>; ++ }; ++ ++ xfi_tphy1: phy@11f30000 { ++ compatible = "mediatek,mt7988-xfi-tphy"; ++ reg = <0 0x11f30000 0 0x10000>; ++ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, ++ <&topckgen CLK_TOP_XFI_PHY_1_XTAL_SEL>; ++ clock-names = "xfipll", "topxtal"; ++ resets = <&watchdog 15>; ++ #phy-cells = <0>; ++ }; ++ ++ xfi_pll: clock-controller@11f40000 { + compatible = "mediatek,mt7988-xfi-pll"; + reg = <0 0x11f40000 0 0x1000>; + resets = <&watchdog 16>; +@@ -714,19 +735,129 @@ phy_calibration_p3: calib@97c { + }; + }; + +- clock-controller@15000000 { ++ ethsys: clock-controller@15000000 { + compatible = "mediatek,mt7988-ethsys", "syscon"; + reg = <0 0x15000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + +- clock-controller@15031000 { ++ ethwarp: clock-controller@15031000 { + compatible = "mediatek,mt7988-ethwarp"; + reg = <0 0x15031000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; ++ ++ eth: ethernet@15100000 { ++ compatible = "mediatek,mt7988-eth"; ++ reg = <0 0x15100000 0 0x40000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = "fe0", "fe1", "fe2", "fe3", "pdma0", ++ "pdma1", "pdma2", "pdma3"; ++ clocks = <ðsys CLK_ETHDMA_CRYPT0_EN>, ++ <ðsys CLK_ETHDMA_FE_EN>, ++ <ðsys CLK_ETHDMA_GP2_EN>, ++ <ðsys CLK_ETHDMA_GP1_EN>, ++ <ðsys CLK_ETHDMA_GP3_EN>, ++ <ðwarp CLK_ETHWARP_WOCPU2_EN>, ++ <ðwarp CLK_ETHWARP_WOCPU1_EN>, ++ <ðwarp CLK_ETHWARP_WOCPU0_EN>, ++ <ðsys CLK_ETHDMA_ESW_EN>, ++ <&topckgen CLK_TOP_ETH_GMII_SEL>, ++ <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>, ++ <&topckgen CLK_TOP_ETH_SYS_200M_SEL>, ++ <&topckgen CLK_TOP_ETH_SYS_SEL>, ++ <&topckgen CLK_TOP_ETH_XGMII_SEL>, ++ <&topckgen CLK_TOP_ETH_MII_SEL>, ++ <&topckgen CLK_TOP_NETSYS_SEL>, ++ <&topckgen CLK_TOP_NETSYS_500M_SEL>, ++ <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>, ++ <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>, ++ <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>, ++ <&topckgen CLK_TOP_NETSYS_WARP_SEL>, ++ <ðsys CLK_ETHDMA_XGP1_EN>, ++ <ðsys CLK_ETHDMA_XGP2_EN>, ++ <ðsys CLK_ETHDMA_XGP3_EN>; ++ clock-names = "crypto", "fe", "gp2", "gp1", "gp3", ++ "ethwarp_wocpu2", "ethwarp_wocpu1", ++ "ethwarp_wocpu0", "esw", "top_eth_gmii_sel", ++ "top_eth_refck_50m_sel", "top_eth_sys_200m_sel", ++ "top_eth_sys_sel", "top_eth_xgmii_sel", ++ "top_eth_mii_sel", "top_netsys_sel", ++ "top_netsys_500m_sel", "top_netsys_pao_2x_sel", ++ "top_netsys_sync_250m_sel", ++ "top_netsys_ppefb_250m_sel", ++ "top_netsys_warp_sel","xgp1", "xgp2", "xgp3"; ++ assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, ++ <&topckgen CLK_TOP_NETSYS_GSW_SEL>, ++ <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>, ++ <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>, ++ <&topckgen CLK_TOP_SGM_0_SEL>, ++ <&topckgen CLK_TOP_SGM_1_SEL>; ++ assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, ++ <&topckgen CLK_TOP_NET1PLL_D4>, ++ <&topckgen CLK_TOP_NET1PLL_D8_D4>, ++ <&topckgen CLK_TOP_NET1PLL_D8_D4>, ++ <&apmixedsys CLK_APMIXED_SGMPLL>, ++ <&apmixedsys CLK_APMIXED_SGMPLL>; ++ sram = <ð_sram>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mediatek,ethsys = <ðsys>; ++ mediatek,infracfg = <&topmisc>; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "internal"; ++ ++ /* Connected to internal switch */ ++ fixed-link { ++ speed = <10000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ status = "disabled"; ++ }; ++ ++ gmac2: mac@2 { ++ compatible = "mediatek,eth-mac"; ++ reg = <2>; ++ status = "disabled"; ++ }; ++ ++ mdio_bus: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* internal 2.5G PHY */ ++ int_2p5g_phy: ethernet-phy@15 { ++ compatible = "ethernet-phy-ieee802.3-c45"; ++ reg = <15>; ++ }; ++ }; ++ }; ++ ++ eth_sram: sram@15400000 { ++ compatible = "mmio-sram"; ++ reg = <0 0x15400000 0 0x200000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x15400000 0 0x200000>; ++ }; + }; + + thermal-zones { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0027-arm64-dts-mediatek-mt7988-add-switch-node.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0027-arm64-dts-mediatek-mt7988-add-switch-node.patch new file mode 100644 index 000000000..3f59f75ab --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0027-arm64-dts-mediatek-mt7988-add-switch-node.patch @@ -0,0 +1,184 @@ +From 2292b669f7c265c39f2836b894270305b1d32a39 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 1 Feb 2025 15:18:12 +0100 +Subject: [PATCH 27/84] arm64: dts: mediatek: mt7988: add switch node + +Add mt7988 builtin mt753x switch nodes. + +Signed-off-by: Daniel Golle +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- +v4: +- drop phy-mode for gsw-phy +- reorder phy-mode after phy-handle +- drop interrupt parent from switch + +v2: +- drop labels and led-function too (have to be in board) +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 148 ++++++++++++++++++++++ + 1 file changed, 148 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index 897b5a82b53e..366203a72d6d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -742,6 +742,154 @@ ethsys: clock-controller@15000000 { + #reset-cells = <1>; + }; + ++ switch: switch@15020000 { ++ compatible = "mediatek,mt7988-switch"; ++ reg = <0 0x15020000 0 0x8000>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ interrupts = ; ++ resets = <ðwarp MT7988_ETHWARP_RST_SWITCH>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ gsw_port0: port@0 { ++ reg = <0>; ++ phy-handle = <&gsw_phy0>; ++ phy-mode = "internal"; ++ }; ++ ++ gsw_port1: port@1 { ++ reg = <1>; ++ phy-handle = <&gsw_phy1>; ++ phy-mode = "internal"; ++ }; ++ ++ gsw_port2: port@2 { ++ reg = <2>; ++ phy-handle = <&gsw_phy2>; ++ phy-mode = "internal"; ++ }; ++ ++ gsw_port3: port@3 { ++ reg = <3>; ++ phy-handle = <&gsw_phy3>; ++ phy-mode = "internal"; ++ }; ++ ++ port@6 { ++ reg = <6>; ++ ethernet = <&gmac0>; ++ phy-mode = "internal"; ++ ++ fixed-link { ++ speed = <10000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ }; ++ ++ mdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mediatek,pio = <&pio>; ++ ++ gsw_phy0: ethernet-phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ interrupts = <0>; ++ nvmem-cells = <&phy_calibration_p0>; ++ nvmem-cell-names = "phy-cal-data"; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ gsw_phy0_led0: led@0 { ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ gsw_phy0_led1: led@1 { ++ reg = <1>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ gsw_phy1: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ interrupts = <1>; ++ nvmem-cells = <&phy_calibration_p1>; ++ nvmem-cell-names = "phy-cal-data"; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ gsw_phy1_led0: led@0 { ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ gsw_phy1_led1: led@1 { ++ reg = <1>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ gsw_phy2: ethernet-phy@2 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <2>; ++ interrupts = <2>; ++ nvmem-cells = <&phy_calibration_p2>; ++ nvmem-cell-names = "phy-cal-data"; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ gsw_phy2_led0: led@0 { ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ gsw_phy2_led1: led@1 { ++ reg = <1>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ gsw_phy3: ethernet-phy@3 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <3>; ++ interrupts = <3>; ++ nvmem-cells = <&phy_calibration_p3>; ++ nvmem-cell-names = "phy-cal-data"; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ gsw_phy3_led0: led@0 { ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ gsw_phy3_led1: led@1 { ++ reg = <1>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ }; ++ }; ++ + ethwarp: clock-controller@15031000 { + compatible = "mediatek,mt7988-ethwarp"; + reg = <0 0x15031000 0 0x1000>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0028-arm64-dts-mediatek-mt7988a-bpi-r4-add-aliases-for-et.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0028-arm64-dts-mediatek-mt7988a-bpi-r4-add-aliases-for-et.patch new file mode 100644 index 000000000..9522fa974 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0028-arm64-dts-mediatek-mt7988a-bpi-r4-add-aliases-for-et.patch @@ -0,0 +1,34 @@ +From 27b63d1a7ead4d934e1557bed3ee44f2a8295f61 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 5 Jun 2025 18:38:51 +0200 +Subject: [PATCH 28/84] arm64: dts: mediatek: mt7988a-bpi-r4: add aliases for + ethernet + +Add aliases for gmacs to allow bootloader setting mac-adresses. + +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- + arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 21eb91c8609f..20073eb4d1bd 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -8,6 +8,12 @@ + #include "mt7988a.dtsi" + + / { ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ ethernet2 = &gmac2; ++ }; ++ + chosen { + stdout-path = "serial0:115200n8"; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0029-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0029-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-.patch new file mode 100644 index 000000000..18d9e57d0 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0029-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-.patch @@ -0,0 +1,114 @@ +From f4e52f16c979828597c900959d7a955f699903be Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 3 May 2025 11:02:27 +0200 +Subject: [PATCH 29/84] arm64: dts: mediatek: mt7988a-bpi-r4: add sfp cages and + link to gmac + +Add SFP cages to Bananapi-R4 board. The 2.5g phy variant only contains the +wan-SFP, so add this to common dtsi and the lan-sfp only to the dual-SFP +variant. + +Signed-off-by: Daniel Golle +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- +v4: +- update 2g5-board (reorder and drop phy-connection-type) +- order sfp properties +v3: +- enable mac with 2.5g phy on r4 phy variant because driver is now mainline +--- + .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts | 11 +++++++++++ + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 19 +++++++++++++++++++ + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 19 +++++++++++++++++++ + 3 files changed, 49 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts +index 53de9c113f60..6f0c81e3fd94 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts +@@ -9,3 +9,14 @@ / { + model = "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)"; + chassis-type = "embedded"; + }; ++ ++&gmac1 { ++ phy = <&int_2p5g_phy>; ++ phy-mode = "internal"; ++ status = "okay"; ++}; ++ ++&int_2p5g_phy { ++ pinctrl-0 = <&i2p5gbe_led0_pins>; ++ pinctrl-names = "i2p5gbe-led"; ++}; +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts +index 36bd1ef2efab..4b3796ba82e3 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts +@@ -8,6 +8,25 @@ / { + compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; + model = "Banana Pi BPI-R4 (2x SFP+)"; + chassis-type = "embedded"; ++ ++ /* SFP2 cage (LAN) */ ++ sfp2: sfp2 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp2>; ++ maximum-power-milliwatt = <3000>; ++ ++ los-gpios = <&pio 2 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&pio 83 GPIO_ACTIVE_LOW>; ++ rate-select0-gpios = <&pio 3 GPIO_ACTIVE_LOW>; ++ tx-disable-gpios = <&pio 0 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpios = <&pio 1 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&gmac1 { ++ managed = "in-band-status"; ++ phy-mode = "usxgmii"; ++ sfp = <&sfp2>; + }; + + &pca9545 { +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 20073eb4d1bd..4d709ee527df 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -63,6 +63,19 @@ reg_3p3v: regulator-3p3v { + regulator-boot-on; + regulator-always-on; + }; ++ ++ /* SFP1 cage (WAN) */ ++ sfp1: sfp1 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp1>; ++ maximum-power-milliwatt = <3000>; ++ ++ los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>; ++ rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>; ++ tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>; ++ }; + }; + + &cci { +@@ -133,6 +146,12 @@ map-cpu-active-low { + }; + }; + ++&gmac2 { ++ managed = "in-band-status"; ++ phy-mode = "usxgmii"; ++ sfp = <&sfp1>; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0030-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-p.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0030-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-p.patch new file mode 100644 index 000000000..b96581303 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0030-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-p.patch @@ -0,0 +1,102 @@ +From 50fb825ca91959e8c00e3d792df1e09c0ef011c1 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 3 May 2025 13:06:40 +0200 +Subject: [PATCH 30/84] arm64: dts: mediatek: mt7988a-bpi-r4: configure switch + phys and leds + +Assign pinctrl to switch phys and leds. + +Signed-off-by: Daniel Golle +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +--- +v4: +- reorder switch phy(-led) properties +v2: +- add labels and led-function and include after dropping from soc dtsi +--- + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 61 +++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 4d709ee527df..7c9df606f60d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -4,6 +4,7 @@ + + #include + #include ++#include + + #include "mt7988a.dtsi" + +@@ -152,6 +153,66 @@ &gmac2 { + sfp = <&sfp1>; + }; + ++&gsw_phy0 { ++ pinctrl-0 = <&gbe0_led0_pins>; ++ pinctrl-names = "gbe-led"; ++}; ++ ++&gsw_phy0_led0 { ++ function = LED_FUNCTION_WAN; ++ color = ; ++ status = "okay"; ++}; ++ ++&gsw_port0 { ++ label = "wan"; ++}; ++ ++&gsw_phy1 { ++ pinctrl-0 = <&gbe1_led0_pins>; ++ pinctrl-names = "gbe-led"; ++}; ++ ++&gsw_phy1_led0 { ++ function = LED_FUNCTION_LAN; ++ color = ; ++ status = "okay"; ++}; ++ ++&gsw_port1 { ++ label = "lan1"; ++}; ++ ++&gsw_phy2 { ++ pinctrl-0 = <&gbe2_led0_pins>; ++ pinctrl-names = "gbe-led"; ++}; ++ ++&gsw_phy2_led0 { ++ function = LED_FUNCTION_LAN; ++ color = ; ++ status = "okay"; ++}; ++ ++&gsw_port2 { ++ label = "lan2"; ++}; ++ ++&gsw_phy3 { ++ pinctrl-0 = <&gbe3_led0_pins>; ++ pinctrl-names = "gbe-led"; ++}; ++ ++&gsw_phy3_led0 { ++ function = LED_FUNCTION_LAN; ++ color = ; ++ status = "okay"; ++}; ++ ++&gsw_port3 { ++ label = "lan3"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0031-arm64-dts-mediatek-mt7988a-bpi-r4-drop-readonly-from.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0031-arm64-dts-mediatek-mt7988a-bpi-r4-drop-readonly-from.patch new file mode 100644 index 000000000..ab05a8300 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0031-arm64-dts-mediatek-mt7988a-bpi-r4-drop-readonly-from.patch @@ -0,0 +1,31 @@ +From 060ce20b9896abbb7bd44f9637d78fbfd0ff1f23 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 5 Jul 2025 22:58:15 +0200 +Subject: [PATCH 31/84] arm64: dts: mediatek: mt7988a-bpi-r4: drop readonly + from bl2 partition + +This flag must be removed to allow nand install scripts writing the bl2. + +Fixes: 6b7642e9d095 ("arm64: dts: mediatek: mt7988a-bpi-r4: configure spi-nodes") +Signed-off-by: Frank Wunderlich +--- +v8: new patch +--- + arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 7c9df606f60d..6436263d2328 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -448,7 +448,6 @@ partitions { + partition@0 { + label = "bl2"; + reg = <0x0 0x200000>; +- read-only; + }; + }; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0032-dt-bindings-net-pcs-mediatek-sgmiisys-add-phys-and-r.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0032-dt-bindings-net-pcs-mediatek-sgmiisys-add-phys-and-r.patch new file mode 100644 index 000000000..58c3c6d24 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0032-dt-bindings-net-pcs-mediatek-sgmiisys-add-phys-and-r.patch @@ -0,0 +1,52 @@ +From 1d055f70cc1e201be29bbaf05947b2ef1644b259 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 1 May 2025 21:18:27 +0200 +Subject: [PATCH 32/84] dt-bindings: net: pcs: mediatek,sgmiisys: add phys and + resets + +For mt7988 we need 2 additional properties: + +- phys +- resets + +Signed-off-by: Frank Wunderlich +--- + .../bindings/net/pcs/mediatek,sgmiisys.yaml | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml +index 1bacc0eeff75..ca0f4f4ec765 100644 +--- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml ++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml +@@ -58,6 +58,11 @@ properties: + - const: sgmii_tx + - const: sgmii_rx + ++ phys: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ Phandle to the (xfi) phy. ++ + required: + - compatible + - clocks +@@ -65,6 +70,16 @@ properties: + + additionalProperties: false + ++ resets: ++ description: ++ A phandle to reset the sgmiisys controller. ++ items: ++ - items: ++ - description: ++ Phandle to the reset controller ++ - description: ++ value for reset ++ + required: + - compatible + - reg +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0033-dt-binding-sgmiisys-re-add-pcs-cells.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0033-dt-binding-sgmiisys-re-add-pcs-cells.patch new file mode 100644 index 000000000..586d237bf --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0033-dt-binding-sgmiisys-re-add-pcs-cells.patch @@ -0,0 +1,26 @@ +From dfcf69513fa1161889f0ae09bd20d00cce92b7af Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 5 May 2025 19:58:25 +0200 +Subject: [PATCH 33/84] dt-binding: sgmiisys: re-add pcs-cells" + +--- + .../devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml +index ca0f4f4ec765..375c166727c5 100644 +--- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml ++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml +@@ -58,6 +58,9 @@ properties: + - const: sgmii_tx + - const: sgmii_rx + ++ "#pcs-cells": ++ const: 0 ++ + phys: + $ref: /schemas/types.yaml#/definitions/phandle + description: +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0034-dts-re-add-sgmiisys.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0034-dts-re-add-sgmiisys.patch new file mode 100644 index 000000000..876de17fb --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0034-dts-re-add-sgmiisys.patch @@ -0,0 +1,61 @@ +From c656470a7109031ebafa95174a0ecd11d251b788 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 5 May 2025 20:01:00 +0200 +Subject: [PATCH 34/84] dts: re-add sgmiisys + +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 38 +++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index 366203a72d6d..e4833dbdd7af 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -277,6 +277,44 @@ pwm: pwm@10048000 { + status = "disabled"; + }; + ++ sgmiisys0: syscon@10060000 { ++ compatible = "mediatek,mt7988-sgmiisys0", ++ "simple-mfd", ++ "syscon"; ++ reg = <0 0x10060000 0 0x1000>; ++ resets = <&watchdog 1>; ++ #clock-cells = <1>; ++ ++ sgmiipcs0: pcs { ++ compatible = "mediatek,mt7988-sgmii"; ++ clocks = <&topckgen CLK_TOP_SGM_0_SEL>, ++ <&sgmiisys0 CLK_SGM0_TX_EN>, ++ <&sgmiisys0 CLK_SGM0_RX_EN>; ++ clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx"; ++ phys = <&xfi_tphy0>; ++ #pcs-cells = <0>; ++ }; ++ }; ++ ++ sgmiisys1: syscon@10070000 { ++ compatible = "mediatek,mt7988-sgmiisys1", ++ "simple-mfd", ++ "syscon"; ++ reg = <0 0x10070000 0 0x1000>; ++ resets = <&watchdog 2>; ++ #clock-cells = <1>; ++ ++ sgmiipcs1: pcs { ++ compatible = "mediatek,mt7988-sgmii"; ++ clocks = <&topckgen CLK_TOP_SGM_1_SEL>, ++ <&sgmiisys1 CLK_SGM1_TX_EN>, ++ <&sgmiisys1 CLK_SGM1_RX_EN>; ++ clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx"; ++ phys = <&xfi_tphy1>; ++ #pcs-cells = <0>; ++ }; ++ }; ++ + mcusys: mcusys@100e0000 { + compatible = "mediatek,mt7988-mcusys", "syscon"; + reg = <0 0x100e0000 0 0x1000>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0035-arm64-dts-mt7988-add-cpufreq-calibration-efuse-subno.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0035-arm64-dts-mt7988-add-cpufreq-calibration-efuse-subno.patch new file mode 100644 index 000000000..61e800ef4 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0035-arm64-dts-mt7988-add-cpufreq-calibration-efuse-subno.patch @@ -0,0 +1,27 @@ +From eeeadc20f05134123868769f8def2ce1ab0933ec Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 2 May 2025 12:29:54 +0200 +Subject: [PATCH 35/84] arm64: dts: mt7988: add cpufreq calibration efuse + subnode + +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index e4833dbdd7af..88f201ad78cf 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -752,6 +752,9 @@ efuse@11f50000 { + #address-cells = <1>; + #size-cells = <1>; + ++ cpufreq_calibration: calib@278 { ++ reg = <0x278 0x1>; ++ }; + lvts_calibration: calib@918 { + reg = <0x918 0x28>; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0036-net-ethernet-mtk_eth_soc-move-desc-assignment-below-.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0036-net-ethernet-mtk_eth_soc-move-desc-assignment-below-.patch new file mode 100644 index 000000000..3ef28ddd5 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0036-net-ethernet-mtk_eth_soc-move-desc-assignment-below-.patch @@ -0,0 +1,39 @@ +From 682eb678991b3dde629df9178e7e088bbe4b7039 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 26 Mar 2025 19:44:18 +0100 +Subject: [PATCH 36/84] net: ethernet: mtk_eth_soc: move desc assignment below + check for its txd3 + +The field desc->txd3 should be checked for TX_DMA_OWNER_CPU flag before +assign a new desc. + +old MTK-SDK uses same order: +https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c#2895 +new SDK seems not changing it. + +Fixes: 656e705243fd ("net-next: mediatek: add support for MT7623 ethernet") +Signed-off-by: Frank Wunderlich +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 9333f2b8e1d6..5b201c0214a0 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2439,10 +2439,11 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, + while ((cpu != dma) && budget) { + u32 next_cpu = desc->txd2; + +- desc = mtk_qdma_phys_to_virt(ring, desc->txd2); + if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) + break; + ++ desc = mtk_qdma_phys_to_virt(ring, desc->txd2); ++ + tx_buf = mtk_desc_to_tx_buf(ring, desc, + eth->soc->tx.desc_size); + if (!tx_buf->data) +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0037-dts-enable-mt818-36-for-cci-testing.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0037-dts-enable-mt818-36-for-cci-testing.patch new file mode 100644 index 000000000..dd6dbed67 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0037-dts-enable-mt818-36-for-cci-testing.patch @@ -0,0 +1,121 @@ +From b5d5dcd4cbbed8369b58ee562cc7717c39496c48 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 31 May 2025 13:09:24 +0200 +Subject: [PATCH 37/84] dts: enable mt818[36] for cci testing + +--- + arch/arm64/boot/dts/mediatek/Makefile | 98 +++++++++++++-------------- + 1 file changed, 49 insertions(+), 49 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile +index e60462fa2b6f..87608df68fab 100644 +--- a/arch/arm64/boot/dts/mediatek/Makefile ++++ b/arch/arm64/boot/dts/mediatek/Makefile +@@ -30,55 +30,55 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku0.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku1.dtb +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0038-Revert-dts-enable-mt818-36-for-cci-testing.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0038-Revert-dts-enable-mt818-36-for-cci-testing.patch new file mode 100644 index 000000000..91ddabbdd --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0038-Revert-dts-enable-mt818-36-for-cci-testing.patch @@ -0,0 +1,122 @@ +From bac17b5f648913aef5ff8b2559631dffbed56ab8 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 4 Jun 2025 22:33:49 +0200 +Subject: [PATCH 38/84] Revert "dts: enable mt818[36] for cci testing" + +This reverts commit 1e0327fc048d602fbc85ce160202bbe998a62cb0. +--- + arch/arm64/boot/dts/mediatek/Makefile | 98 +++++++++++++-------------- + 1 file changed, 49 insertions(+), 49 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile +index 87608df68fab..e60462fa2b6f 100644 +--- a/arch/arm64/boot/dts/mediatek/Makefile ++++ b/arch/arm64/boot/dts/mediatek/Makefile +@@ -30,55 +30,55 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb +-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku6.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel-sku7.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-fennel14-sku2.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-juniper-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kappa.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-kenzo.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-makomo-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-pico6.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-willow-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kakadu-sku22.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku32.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-katsu-sku38.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-ponyta-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku1.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327683.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262144.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacruel-sku262148.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb ++#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku0.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-geralt-ciri-sku1.dtb +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0039-enable-bpi-r3-DTBs-for-testing.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0039-enable-bpi-r3-DTBs-for-testing.patch new file mode 100644 index 000000000..8c3fa18b1 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0039-enable-bpi-r3-DTBs-for-testing.patch @@ -0,0 +1,37 @@ +From b012720e24c54270538cdb6808f895791084da49 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 15 Jun 2025 16:49:01 +0200 +Subject: [PATCH 39/84] enable bpi-r3 DTBs for testing + +--- + arch/arm64/boot/dts/mediatek/Makefile | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile +index e60462fa2b6f..d4f56f8e8463 100644 +--- a/arch/arm64/boot/dts/mediatek/Makefile ++++ b/arch/arm64/boot/dts/mediatek/Makefile +@@ -12,13 +12,13 @@ + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-openwrt-one.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0040-only-enable-mediatek-for-arm-to-increase-dtbs_check.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0040-only-enable-mediatek-for-arm-to-increase-dtbs_check.patch new file mode 100644 index 000000000..cfa180353 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0040-only-enable-mediatek-for-arm-to-increase-dtbs_check.patch @@ -0,0 +1,97 @@ +From 606aeff7dcc0f97ace6cb54e8098b9ca72a30c32 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 23 Jun 2025 22:17:54 +0200 +Subject: [PATCH 40/84] only enable mediatek for arm to increase dtbs_check + +--- + arch/arm/boot/dts/Makefile | 78 +++++++++++++++++++------------------- + 1 file changed, 39 insertions(+), 39 deletions(-) + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index efe38eb25301..8afa52394d6d 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1,41 +1,41 @@ + # SPDX-License-Identifier: GPL-2.0 +-subdir-y += actions +-subdir-y += airoha +-subdir-y += allwinner +-subdir-y += alphascale +-subdir-y += amazon +-subdir-y += amlogic +-subdir-y += arm +-subdir-y += aspeed +-subdir-y += axis +-subdir-y += broadcom +-subdir-y += calxeda +-subdir-y += cirrus +-subdir-y += cnxt +-subdir-y += gemini +-subdir-y += hisilicon +-subdir-y += hpe +-subdir-y += intel +-subdir-y += marvell ++#subdir-y += actions ++#subdir-y += airoha ++#subdir-y += allwinner ++#subdir-y += alphascale ++#subdir-y += amazon ++#subdir-y += amlogic ++#subdir-y += arm ++#subdir-y += aspeed ++#subdir-y += axis ++#subdir-y += broadcom ++#subdir-y += calxeda ++#subdir-y += cirrus ++#subdir-y += cnxt ++#subdir-y += gemini ++#subdir-y += hisilicon ++#subdir-y += hpe ++#subdir-y += intel ++#subdir-y += marvell + subdir-y += mediatek +-subdir-y += microchip +-subdir-y += moxa +-subdir-y += nspire +-subdir-y += nuvoton +-subdir-y += nvidia +-subdir-y += nxp +-subdir-y += qcom +-subdir-y += realtek +-subdir-y += renesas +-subdir-y += rockchip +-subdir-y += samsung +-subdir-y += sigmastar +-subdir-y += socionext +-subdir-y += st +-subdir-y += sunplus +-subdir-y += synaptics +-subdir-y += ti +-subdir-y += unisoc +-subdir-y += vt8500 +-subdir-y += xen +-subdir-y += xilinx ++#subdir-y += microchip ++#subdir-y += moxa ++#subdir-y += nspire ++#subdir-y += nuvoton ++#subdir-y += nvidia ++#subdir-y += nxp ++#subdir-y += qcom ++#subdir-y += realtek ++#subdir-y += renesas ++#subdir-y += rockchip ++#subdir-y += samsung ++#subdir-y += sigmastar ++#subdir-y += socionext ++#subdir-y += st ++#subdir-y += sunplus ++#subdir-y += synaptics ++#subdir-y += ti ++#subdir-y += unisoc ++#subdir-y += vt8500 ++#subdir-y += xen ++#subdir-y += xilinx +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0041-enable-some-arm64-dts-to-check-binding.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0041-enable-some-arm64-dts-to-check-binding.patch new file mode 100644 index 000000000..709599883 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0041-enable-some-arm64-dts-to-check-binding.patch @@ -0,0 +1,41 @@ +From f66d885af3510cd9fbe765354bea75955b791b95 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 23 Jun 2025 22:18:41 +0200 +Subject: [PATCH 41/84] enable some arm64 dts to check binding + +--- + arch/arm64/boot/dts/mediatek/Makefile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile +index d4f56f8e8463..d728953c10ad 100644 +--- a/arch/arm64/boot/dts/mediatek/Makefile ++++ b/arch/arm64/boot/dts/mediatek/Makefile +@@ -7,7 +7,7 @@ + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-openwrt-one.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb +@@ -25,12 +25,12 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo + dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb +-#dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb ++dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-burnet.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-cozmo.dtb + #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-jacuzzi-damu.dtb +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0042-defconfig-r4-add-sram-driver.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0042-defconfig-r4-add-sram-driver.patch new file mode 100644 index 000000000..077439e3a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0042-defconfig-r4-add-sram-driver.patch @@ -0,0 +1,25 @@ +From ba3dd9a702c9ba546f569fdd0da5e3dc0e533b8d Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 25 Jun 2025 21:08:16 +0200 +Subject: [PATCH 42/84] defconfig: r4: add sram driver + +--- + arch/arm64/configs/mt7988a_bpi-r4_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/mt7988a_bpi-r4_defconfig b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +index 69de56a20462..29bc60ce564f 100644 +--- a/arch/arm64/configs/mt7988a_bpi-r4_defconfig ++++ b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +@@ -1274,7 +1274,7 @@ CONFIG_SECCOMP=y + + CONFIG_I2C_MUX=y + CONFIG_I2C_MUX_PCA954x=y +- ++CONFIG_SRAM=y + CONFIG_PCS_MTK_USXGMII=y + + CONFIG_MT7915E=m +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0043-net-ethernet-mtk_eth_soc-improve-support-for-named-i.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0043-net-ethernet-mtk_eth_soc-improve-support-for-named-i.patch new file mode 100644 index 000000000..5e435f742 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0043-net-ethernet-mtk_eth_soc-improve-support-for-named-i.patch @@ -0,0 +1,52 @@ +From 67cbba9936c2fabc97392f3ac67ffd289a205c2f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 2 Jul 2025 14:14:29 +0100 +Subject: [PATCH 43/84] net: ethernet: mtk_eth_soc: improve support for named + interrupts + +Use platform_get_irq_byname_optional() to avoid outputting error +messages when using legacy device trees which rely identifying +interrupts only by index. Instead, output a warning notifying the user +to update their device tree. + +Signed-off-by: Daniel Golle +Reviewed-by: Andrew Lunn +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 5b201c0214a0..a119094645e4 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3350,17 +3350,22 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + int i; + + /* future SoCs beginning with MT7988 should use named IRQs in dts */ +- eth->irq[MTK_FE_IRQ_TX] = platform_get_irq_byname(pdev, "fe1"); +- eth->irq[MTK_FE_IRQ_RX] = platform_get_irq_byname(pdev, "fe2"); ++ eth->irq[MTK_FE_IRQ_TX] = platform_get_irq_byname_optional(pdev, "fe1"); ++ eth->irq[MTK_FE_IRQ_RX] = platform_get_irq_byname_optional(pdev, "fe2"); + if (eth->irq[MTK_FE_IRQ_TX] >= 0 && eth->irq[MTK_FE_IRQ_RX] >= 0) + return 0; + +- /* only use legacy mode if platform_get_irq_byname returned -ENXIO */ ++ /* only use legacy mode if platform_get_irq_byname_optional returned -ENXIO */ + if (eth->irq[MTK_FE_IRQ_TX] != -ENXIO) +- return eth->irq[MTK_FE_IRQ_TX]; ++ return dev_err_probe(&pdev->dev, eth->irq[MTK_FE_IRQ_TX], ++ "Error requesting FE TX IRQ\n"); + + if (eth->irq[MTK_FE_IRQ_RX] != -ENXIO) +- return eth->irq[MTK_FE_IRQ_RX]; ++ return dev_err_probe(&pdev->dev, eth->irq[MTK_FE_IRQ_RX], ++ "Error requesting FE RX IRQ\n"); ++ ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) ++ dev_warn(&pdev->dev, "legacy DT: missing interrupt-names."); + + /* legacy way: + * On MTK_SHARED_INT SoCs (MT7621 + MT7628) the first IRQ is taken +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0044-net-ethernet-mtk_eth_soc-fix-kernel-doc-comment.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0044-net-ethernet-mtk_eth_soc-fix-kernel-doc-comment.patch new file mode 100644 index 000000000..23eb7b60c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0044-net-ethernet-mtk_eth_soc-fix-kernel-doc-comment.patch @@ -0,0 +1,32 @@ +From 5a3c93c4023f57befd6cf590088e6095b70a001f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 2 Jul 2025 14:14:39 +0100 +Subject: [PATCH 44/84] net: ethernet: mtk_eth_soc: fix kernel-doc comment + +Fix and add some missing field descriptions to kernel-doc comment of +struct mtk_eth. + +Signed-off-by: Daniel Golle +Reviewed-by: Andrew Lunn +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 9261c0e13b59..1ad9075a9b69 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1243,8 +1243,9 @@ struct mtk_soc_data { + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver + * @dev: The device pointer +- * @dev: The device pointer used for dma mapping/alloc ++ * @dma_dev: The device pointer used for dma mapping/alloc + * @base: The mapped register i/o base ++ * @sram_base: The mapped SRAM base + * @page_lock: Make sure that register operations are atomic + * @tx_irq__lock: Make sure that IRQ register operations are atomic + * @rx_irq__lock: Make sure that IRQ register operations are atomic +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0045-net-ethernet-mtk_eth_soc-use-generic-allocator-for-S.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0045-net-ethernet-mtk_eth_soc-use-generic-allocator-for-S.patch new file mode 100644 index 000000000..e00f57214 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0045-net-ethernet-mtk_eth_soc-use-generic-allocator-for-S.patch @@ -0,0 +1,324 @@ +From 4ba463a09585baacc97b544c939f379a4d784e5b Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 2 Jul 2025 14:14:56 +0100 +Subject: [PATCH 45/84] net: ethernet: mtk_eth_soc: use generic allocator for + SRAM + +Use a dedicated "mmio-sram" node and the generic allocator +instead of open-coding SRAM allocation for DMA rings. +Keep support for legacy device trees but notify the user via a +warning to update, and let the ethernet driver create the +gen_pool in this case. + +Co-developed-by: Frank Wunderlich +Signed-off-by: Frank Wunderlich +Signed-off-by: Daniel Golle +Reviewed-by: Andrew Lunn +--- + drivers/net/ethernet/mediatek/Kconfig | 1 + + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 152 +++++++++++--------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 +- + 3 files changed, 90 insertions(+), 73 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig +index 7bfd3f230ff5..2ba361f8ce7d 100644 +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -17,6 +17,7 @@ config NET_MEDIATEK_SOC + select PINCTRL + select PHYLINK + select DIMLIB ++ select GENERIC_ALLOCATOR + select PAGE_POOL + select PAGE_POOL_STATS + select PCS_MTK_LYNXI +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index a119094645e4..7916c99d5ebb 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "mtk_eth_soc.h" + #include "mtk_wed.h" +@@ -1267,6 +1268,34 @@ static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask) + return (void *)data; + } + ++static void *mtk_dma_ring_alloc(struct mtk_eth *eth, size_t size, ++ dma_addr_t *dma_handle, bool use_sram) ++{ ++ void *dma_ring; ++ ++ if (use_sram && eth->sram_pool) { ++ dma_ring = (void *)gen_pool_alloc(eth->sram_pool, size); ++ if (!dma_ring) ++ return dma_ring; ++ *dma_handle = gen_pool_virt_to_phys(eth->sram_pool, ++ (unsigned long)dma_ring); ++ } else { ++ dma_ring = dma_alloc_coherent(eth->dma_dev, size, dma_handle, ++ GFP_KERNEL); ++ } ++ ++ return dma_ring; ++} ++ ++static void mtk_dma_ring_free(struct mtk_eth *eth, size_t size, void *dma_ring, ++ dma_addr_t dma_handle, bool in_sram) ++{ ++ if (in_sram && eth->sram_pool) ++ gen_pool_free(eth->sram_pool, (unsigned long)dma_ring, size); ++ else ++ dma_free_coherent(eth->dma_dev, size, dma_ring, dma_handle); ++} ++ + /* the qdma core needs scratch memory to be setup */ + static int mtk_init_fq_dma(struct mtk_eth *eth) + { +@@ -1276,13 +1305,8 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) + dma_addr_t dma_addr; + int i, j, len; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) +- eth->scratch_ring = eth->sram_base; +- else +- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, +- cnt * soc->tx.desc_size, +- ð->phy_scratch_ring, +- GFP_KERNEL); ++ eth->scratch_ring = mtk_dma_ring_alloc(eth, cnt * soc->tx.desc_size, ++ ð->phy_scratch_ring, true); + + if (unlikely(!eth->scratch_ring)) + return -ENOMEM; +@@ -2629,14 +2653,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) + if (!ring->buf) + goto no_tx_mem; + +- if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) { +- ring->dma = eth->sram_base + soc->tx.fq_dma_size * sz; +- ring->phys = eth->phy_scratch_ring + soc->tx.fq_dma_size * (dma_addr_t)sz; +- } else { +- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, +- &ring->phys, GFP_KERNEL); +- } +- ++ ring->dma = mtk_dma_ring_alloc(eth, ring_size * sz, &ring->phys, true); + if (!ring->dma) + goto no_tx_mem; + +@@ -2735,10 +2752,10 @@ static void mtk_tx_clean(struct mtk_eth *eth) + kfree(ring->buf); + ring->buf = NULL; + } +- if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { +- dma_free_coherent(eth->dma_dev, +- ring->dma_size * soc->tx.desc_size, +- ring->dma, ring->phys); ++ ++ if (ring->dma) { ++ mtk_dma_ring_free(eth, ring->dma_size * soc->tx.desc_size, ++ ring->dma, ring->phys, true); + ring->dma = NULL; + } + +@@ -2755,14 +2772,9 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + const struct mtk_soc_data *soc = eth->soc; + struct mtk_rx_ring *ring; +- int rx_data_len, rx_dma_size, tx_ring_size; ++ int rx_data_len, rx_dma_size; + int i; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) +- tx_ring_size = MTK_QDMA_RING_SIZE; +- else +- tx_ring_size = soc->tx.dma_size; +- + if (rx_flag == MTK_RX_FLAGS_QDMA) { + if (ring_no) + return -EINVAL; +@@ -2797,20 +2809,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) + ring->page_pool = pp; + } + +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || +- rx_flag != MTK_RX_FLAGS_NORMAL) { +- ring->dma = dma_alloc_coherent(eth->dma_dev, +- rx_dma_size * eth->soc->rx.desc_size, +- &ring->phys, GFP_KERNEL); +- } else { +- struct mtk_tx_ring *tx_ring = ð->tx_ring; +- +- ring->dma = tx_ring->dma + tx_ring_size * +- eth->soc->tx.desc_size * (ring_no + 1); +- ring->phys = tx_ring->phys + tx_ring_size * +- eth->soc->tx.desc_size * (ring_no + 1); +- } +- ++ ring->dma = mtk_dma_ring_alloc(eth, ++ rx_dma_size * eth->soc->rx.desc_size, ++ &ring->phys, ++ rx_flag == MTK_RX_FLAGS_NORMAL); + if (!ring->dma) + return -ENOMEM; + +@@ -2925,10 +2927,9 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_ + ring->data = NULL; + } + +- if (!in_sram && ring->dma) { +- dma_free_coherent(eth->dma_dev, +- ring->dma_size * eth->soc->rx.desc_size, +- ring->dma, ring->phys); ++ if (ring->dma) { ++ mtk_dma_ring_free(eth, ring->dma_size * eth->soc->rx.desc_size, ++ ring->dma, ring->phys, in_sram); + ring->dma = NULL; + } + +@@ -3296,15 +3297,16 @@ static void mtk_dma_free(struct mtk_eth *eth) + netdev_tx_reset_subqueue(eth->netdev[i], j); + } + +- if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { +- dma_free_coherent(eth->dma_dev, +- MTK_QDMA_RING_SIZE * soc->tx.desc_size, +- eth->scratch_ring, eth->phy_scratch_ring); ++ if (eth->scratch_ring) { ++ mtk_dma_ring_free(eth, soc->tx.fq_dma_size * soc->tx.desc_size, ++ eth->scratch_ring, eth->phy_scratch_ring, ++ true); + eth->scratch_ring = NULL; + eth->phy_scratch_ring = 0; + } ++ + mtk_tx_clean(eth); +- mtk_rx_clean(eth, ð->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM)); ++ mtk_rx_clean(eth, ð->rx_ring[0], true); + mtk_rx_clean(eth, ð->rx_ring_qdma, false); + + if (eth->hwlro) { +@@ -5016,9 +5018,30 @@ static int mtk_sgmii_init(struct mtk_eth *eth) + return 0; + } + ++static int mtk_setup_legacy_sram(struct mtk_eth *eth, struct resource *res) ++{ ++ dev_warn(eth->dev, "legacy DT: using hard-coded SRAM offset.\n"); ++ ++ if (res->start + MTK_ETH_SRAM_OFFSET + MTK_ETH_NETSYS_V2_SRAM_SIZE - 1 > ++ res->end) ++ return -EINVAL; ++ ++ eth->sram_pool = devm_gen_pool_create(eth->dev, ++ const_ilog2(MTK_ETH_SRAM_GRANULARITY), ++ NUMA_NO_NODE, dev_name(eth->dev)); ++ ++ if (IS_ERR(eth->sram_pool)) ++ return PTR_ERR(eth->sram_pool); ++ ++ return gen_pool_add_virt(eth->sram_pool, ++ (unsigned long)eth->base + MTK_ETH_SRAM_OFFSET, ++ res->start + MTK_ETH_SRAM_OFFSET, ++ MTK_ETH_NETSYS_V2_SRAM_SIZE, NUMA_NO_NODE); ++} ++ + static int mtk_probe(struct platform_device *pdev) + { +- struct resource *res = NULL, *res_sram; ++ struct resource *res = NULL; + struct device_node *mac_np; + struct mtk_eth *eth; + int err, i; +@@ -5038,20 +5061,6 @@ static int mtk_probe(struct platform_device *pdev) + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + eth->ip_align = NET_IP_ALIGN; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { +- /* SRAM is actual memory and supports transparent access just like DRAM. +- * Hence we don't require __iomem being set and don't need to use accessor +- * functions to read from or write to SRAM. +- */ +- if (mtk_is_netsys_v3_or_greater(eth)) { +- eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1); +- if (IS_ERR(eth->sram_base)) +- return PTR_ERR(eth->sram_base); +- } else { +- eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET; +- } +- } +- + if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); + if (!err) +@@ -5126,16 +5135,21 @@ static int mtk_probe(struct platform_device *pdev) + err = -EINVAL; + goto err_destroy_sgmii; + } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { +- if (mtk_is_netsys_v3_or_greater(eth)) { +- res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- if (!res_sram) { ++ eth->sram_pool = of_gen_pool_get(pdev->dev.of_node, ++ "sram", 0); ++ if (!eth->sram_pool) { ++ if (!mtk_is_netsys_v3_or_greater(eth)) { ++ err = mtk_setup_legacy_sram(eth, res); ++ if (err) ++ goto err_destroy_sgmii; ++ } else { ++ dev_err(&pdev->dev, ++ "Could not get SRAM pool\n"); + err = -EINVAL; + goto err_destroy_sgmii; + } +- eth->phy_scratch_ring = res_sram->start; +- } else { +- eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET; + } + } + } +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 1ad9075a9b69..0168e2fbc619 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -141,8 +141,10 @@ + #define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ + 0x54C : 0x50C + (_x * 0x1000); }) + +-/* Internal SRAM offset */ +-#define MTK_ETH_SRAM_OFFSET 0x40000 ++/* legacy DT support for internal SRAM */ ++#define MTK_ETH_SRAM_OFFSET 0x40000 ++#define MTK_ETH_SRAM_GRANULARITY 32 ++#define MTK_ETH_NETSYS_V2_SRAM_SIZE 0x40000 + + /* FE global misc reg*/ + #define MTK_FE_GLO_MISC 0x124 +@@ -1245,7 +1247,7 @@ struct mtk_soc_data { + * @dev: The device pointer + * @dma_dev: The device pointer used for dma mapping/alloc + * @base: The mapped register i/o base +- * @sram_base: The mapped SRAM base ++ * @sram_pool: Pointer to SRAM pool used for DMA descriptor rings + * @page_lock: Make sure that register operations are atomic + * @tx_irq__lock: Make sure that IRQ register operations are atomic + * @rx_irq__lock: Make sure that IRQ register operations are atomic +@@ -1291,7 +1293,7 @@ struct mtk_eth { + struct device *dev; + struct device *dma_dev; + void __iomem *base; +- void *sram_base; ++ struct gen_pool *sram_pool; + spinlock_t page_lock; + spinlock_t tx_irq_lock; + spinlock_t rx_irq_lock; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0046-defconfig-r3-add-sram.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0046-defconfig-r3-add-sram.patch new file mode 100644 index 000000000..1594de565 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0046-defconfig-r3-add-sram.patch @@ -0,0 +1,21 @@ +From 00ef5d4e0a6d6e118b03706c3e2bae2bf9a906a6 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 27 Jun 2025 22:58:49 +0200 +Subject: [PATCH 46/84] defconfig: r3: add sram + +--- + arch/arm64/configs/mt7986a_bpi-r3_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/mt7986a_bpi-r3_defconfig b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +index 32710280133d..29421f5f3e1f 100644 +--- a/arch/arm64/configs/mt7986a_bpi-r3_defconfig ++++ b/arch/arm64/configs/mt7986a_bpi-r3_defconfig +@@ -1263,3 +1263,4 @@ CONFIG_EXTRA_FIRMWARE="airoha/EthMD32.dm.bin airoha/EthMD32.DSP.bin" + CONFIG_EXTRA_FIRMWARE_DIR="utils/firmware/" + + CONFIG_PANIC_TIMEOUT=30 ++CONFIG_SRAM=y +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0047-WIP-dts64-r4-add-ubi-partition-to-spin-nand.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0047-WIP-dts64-r4-add-ubi-partition-to-spin-nand.patch new file mode 100644 index 000000000..9118fa811 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0047-WIP-dts64-r4-add-ubi-partition-to-spin-nand.patch @@ -0,0 +1,53 @@ +From b452c304864e95f043e8ea2cd5696fbd98bf0041 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 4 Jul 2025 19:51:42 +0200 +Subject: [PATCH 47/84] WIP: dts64: r4: add ubi partition to spin nand + +--- + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 30 +++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 6436263d2328..38e27ef6bc0c 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -449,6 +449,36 @@ partition@0 { + label = "bl2"; + reg = <0x0 0x200000>; + }; ++ ++ partition@200000 { ++ label = "ubi"; ++ reg = <0x200000 0x7e00000>; ++ compatible = "linux,ubi"; ++ ++ /*volumes { ++ ubi-volume-fip { ++ volname = "fip"; ++ }; ++ ++ ubi-volume-ubootenv { ++ volname = "ubootenv"; ++ nvmem-layout { ++ compatible = "u-boot,env-redundant-bool-layout"; ++ }; ++ }; ++ ++ ubi-volume-ubootenv2 { ++ volname = "ubootenv2"; ++ nvmem-layout { ++ compatible = "u-boot,env-redundant-bool-layout"; ++ }; ++ }; ++ ++ ubi_rootfs: ubi-volume-rootfs { ++ volname = "rootfs"; ++ }; ++ };*/ ++ }; + }; + }; + +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0048-add-mtd-rw-driver.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0048-add-mtd-rw-driver.patch new file mode 100644 index 000000000..c9d11745c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0048-add-mtd-rw-driver.patch @@ -0,0 +1,594 @@ +From 33e651e124d1f4fc3dabcc9b83da1fb7c52ce88c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 6 Jul 2025 17:00:18 +0200 +Subject: [PATCH 48/84] add mtd-rw driver + +from https://github.com/jclehner/mtd-rw +--- + drivers/mtd/Kconfig | 2 + + drivers/mtd/Makefile | 2 + + drivers/mtd/mtdrw/Kconfig | 8 + + drivers/mtd/mtdrw/LICENSE | 339 ++++++++++++++++++++++++++++++++++++ + drivers/mtd/mtdrw/Makefile | 15 ++ + drivers/mtd/mtdrw/README.md | 25 +++ + drivers/mtd/mtdrw/mtd-rw.c | 132 ++++++++++++++ + 7 files changed, 523 insertions(+) + create mode 100644 drivers/mtd/mtdrw/Kconfig + create mode 100644 drivers/mtd/mtdrw/LICENSE + create mode 100644 drivers/mtd/mtdrw/Makefile + create mode 100644 drivers/mtd/mtdrw/README.md + create mode 100644 drivers/mtd/mtdrw/mtd-rw.c + +diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig +index 796a2eccbef0..7bd7ea0d5ddc 100644 +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -222,4 +222,6 @@ source "drivers/mtd/ubi/Kconfig" + + source "drivers/mtd/hyperbus/Kconfig" + ++source "drivers/mtd/mtdrw/Kconfig" ++ + endif # MTD +diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile +index 593d0593a038..4c2437657a9c 100644 +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -31,3 +31,5 @@ obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ + obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ + obj-$(CONFIG_MTD_UBI) += ubi/ + obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ ++ ++obj-y += mtdrw/ +diff --git a/drivers/mtd/mtdrw/Kconfig b/drivers/mtd/mtdrw/Kconfig +new file mode 100644 +index 000000000000..a81af6f11b91 +--- /dev/null ++++ b/drivers/mtd/mtdrw/Kconfig +@@ -0,0 +1,8 @@ ++config MTD_RW ++ tristate "Module to make all MTD partitions writeable" ++ default n ++ help ++ Say M here to build a module which, upon loading, will make ++ all read-only MTD partitions writeable. Do not say Y here. ++ ++ If unsure, say N. +diff --git a/drivers/mtd/mtdrw/LICENSE b/drivers/mtd/mtdrw/LICENSE +new file mode 100644 +index 000000000000..23cb790338e1 +--- /dev/null ++++ b/drivers/mtd/mtdrw/LICENSE +@@ -0,0 +1,339 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Lesser General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ {description} ++ Copyright (C) {year} {fullname} ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ {signature of Ty Coon}, 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Lesser General ++Public License instead of this License. +diff --git a/drivers/mtd/mtdrw/Makefile b/drivers/mtd/mtdrw/Makefile +new file mode 100644 +index 000000000000..d1061ccf3a67 +--- /dev/null ++++ b/drivers/mtd/mtdrw/Makefile +@@ -0,0 +1,15 @@ ++# Build module only if kernel supports MTD ++ifdef CONFIG_MTD ++obj-m += mtd-rw.o ++endif ++ ++KDIR ?= /lib/modules/$(shell uname -r)/build ++ ++modules: ++ $(MAKE) -C $(KDIR) M=$$PWD modules ++ ++modules_install: ++ $(MAKE) -C $(KDIR) M=$$PWD modules_install ++ ++clean: ++ $(MAKE) -C $(KDIR) M=$$PWD clean +diff --git a/drivers/mtd/mtdrw/README.md b/drivers/mtd/mtdrw/README.md +new file mode 100644 +index 000000000000..dc3b08894ae5 +--- /dev/null ++++ b/drivers/mtd/mtdrw/README.md +@@ -0,0 +1,25 @@ ++mtd-rw - Write-enabler for MTD partitions ++========================================= ++ ++Sets the `MTD_WRITEABLE` flag on all MTD partitions that are marked readonly. ++When unloading, read-only partitions will be restored. This module is intended ++for embedded devices where the mtd partition layout may be hard-coded in the ++firmware. If, for some reason, you DO have to write to a read-only partition ++(which is often a bad idea), this module is the way to go. ++ ++The module is currently limited to the first 64 partitions, but this ++should suffice for most purposes. ++ ++Inspired by dougg3@electronics.stackexchange.com: ++https://electronics.stackexchange.com/a/116133/97342 ++ ++Usage: ++``` ++# insmod mtd-rw.ko i_want_a_brick=1 ++# dmesg | grep mtd-rw ++[52997.620000] mtd-rw: mtd0: setting writeable flag ++[52997.630000] mtd-rw: mtd1: setting writeable flag ++[52997.640000] mtd-rw: mtd3: setting writeable flag ++[52997.650000] mtd-rw: mtd4: setting writeable flag ++[52997.660000] mtd-rw: mtd6: setting writeable flag ++``` +diff --git a/drivers/mtd/mtdrw/mtd-rw.c b/drivers/mtd/mtdrw/mtd-rw.c +new file mode 100644 +index 000000000000..706714d3db77 +--- /dev/null ++++ b/drivers/mtd/mtdrw/mtd-rw.c +@@ -0,0 +1,132 @@ ++/* ++ * mtd-rw - Make all MTD partitions writeable. ++ * ++ * Copyright (C) 2016 Joseph C. Lehner ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. ++ * If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * This module is intended for embedded devices where the mtd partition ++ * layout may be hard-coded in the firmware. If, for some reason, you ++ * DO have to write to a read-only partition (which is often a bad idea), ++ * this module is the way to go. ++ * ++ * The module is currently limited to the first 64 partitions, but this ++ * should suffice for most purposes. ++ * ++ * Inspired by dougg3@electronics.stackexchange.com: ++ * https://electronics.stackexchange.com/a/116133/97342 ++ */ ++ ++#ifndef MODULE ++#error "Must be compiled as a module." ++#endif ++ ++#define MOD_WARNING KERN_WARNING "mtd-rw: " ++#define MOD_INFO KERN_INFO "mtd-rw: " ++#define MOD_ERR KERN_ERR "mtd-rw: " ++ ++#define MTD_MAX (8 * sizeof(unlocked)) ++ ++static uint64_t unlocked = 0; ++static unsigned mtd_last = 0; ++ ++static bool i_want_a_brick = false; ++module_param(i_want_a_brick, bool, S_IRUGO); ++MODULE_PARM_DESC(i_want_a_brick, "Make all partitions writeable"); ++ ++static int set_writeable(unsigned n, bool w) ++{ ++ struct mtd_info *mtd = get_mtd_device(NULL, n); ++ int err; ++ ++ if (IS_ERR(mtd)) { ++ if (PTR_ERR(mtd) != -ENODEV || !w) { ++ printk(MOD_ERR "mtd%d: error %ld\n", n, PTR_ERR(mtd)); ++ } ++ return PTR_ERR(mtd); ++ } ++ ++ err = -EEXIST; ++ ++ if (w && !(mtd->flags & MTD_WRITEABLE)) { ++ printk(MOD_INFO "mtd%d: setting writeable flag\n", n); ++ mtd->flags |= MTD_WRITEABLE; ++ err = 0; ++ } else if (!w && (mtd->flags & MTD_WRITEABLE)) { ++ printk(MOD_INFO "mtd%d: clearing writeable flag\n", n); ++ mtd->flags &= ~MTD_WRITEABLE; ++ err = 0; ++ } ++ ++ put_mtd_device(mtd); ++ return err; ++} ++ ++static int __init mtd_rw_init(void) ++{ ++ int i, err; ++ ++ if (!i_want_a_brick) { ++ printk(MOD_ERR "must specify i_want_a_brick=1 to continue\n"); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < MTD_MAX; ++i) { ++ err = set_writeable(i, true); ++ if (!err) { ++ unlocked |= (1 << i); ++ } else if (err == -ENODEV) { ++ break; ++ } ++ } ++ ++ if (i == MTD_MAX) { ++ printk(MOD_WARNING "partitions beyond mtd%d are ignored\n", i - 1); ++ } ++ ++ if (!unlocked) { ++ printk(MOD_INFO "no partitions to unlock\n"); ++ return -ENODEV; ++ } ++ ++ mtd_last = i; ++ ++ return 0; ++} ++ ++static void __exit mtd_rw_exit(void) ++{ ++ unsigned i; ++ ++ for (i = 0; i < mtd_last; ++i) { ++ if (unlocked & (1 << i)) { ++ set_writeable(i, false); ++ } ++ } ++} ++ ++module_init(mtd_rw_init); ++module_exit(mtd_rw_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Joseph C. Lehner "); ++MODULE_DESCRIPTION("Write-enabler for MTD partitions"); ++MODULE_VERSION("1"); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0049-arm64-dts-add-usxgmii-pcs-and-link-both-pcs.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0049-arm64-dts-add-usxgmii-pcs-and-link-both-pcs.patch new file mode 100644 index 000000000..9a5125979 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0049-arm64-dts-add-usxgmii-pcs-and-link-both-pcs.patch @@ -0,0 +1,56 @@ +From 2141bb55b2e6e0ce036206ada409d588588ed8ef Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 1 May 2025 19:46:37 +0200 +Subject: [PATCH 49/84] arm64: dts: add usxgmii pcs and link both pcs + +--- + arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +index 88f201ad78cf..bbe088ea620f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +@@ -315,6 +315,24 @@ sgmiipcs1: pcs { + }; + }; + ++ usxgmiisys0: pcs@10080000 { ++ compatible = "mediatek,mt7988-usxgmiisys"; ++ reg = <0 0x10080000 0 0x1000>; ++ resets = <&watchdog 12>; ++ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>; ++ phys = <&xfi_tphy0>; ++ #pcs-cells = <0>; ++ }; ++ ++ usxgmiisys1: pcs@10081000 { ++ compatible = "mediatek,mt7988-usxgmiisys"; ++ reg = <0 0x10081000 0 0x1000>; ++ resets = <&watchdog 13>; ++ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>; ++ phys = <&xfi_tphy1>; ++ #pcs-cells = <0>; ++ }; ++ + mcusys: mcusys@100e0000 { + compatible = "mediatek,mt7988-mcusys", "syscon"; + reg = <0 0x100e0000 0 0x1000>; +@@ -1020,12 +1038,14 @@ gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + status = "disabled"; ++ pcs-handle = <&sgmiipcs1>, <&usxgmiisys1>; + }; + + gmac2: mac@2 { + compatible = "mediatek,eth-mac"; + reg = <2>; + status = "disabled"; ++ pcs-handle = <&sgmiipcs0>, <&usxgmiisys0>; + }; + + mdio_bus: mdio-bus { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0050-arm64-dts-update-bpi-r4.dtsi-to-actual-state.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0050-arm64-dts-update-bpi-r4.dtsi-to-actual-state.patch new file mode 100644 index 000000000..268f011df --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0050-arm64-dts-update-bpi-r4.dtsi-to-actual-state.patch @@ -0,0 +1,142 @@ +From 6c08db21a2f0d37c9ffeba6c327aff67e3be28da Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 3 Nov 2024 11:18:31 +0100 +Subject: [PATCH 50/84] arm64: dts: update bpi-r4.dtsi to actual state + +--- + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 1 + + .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 40 +++++++++++++++++-- + 2 files changed, 38 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts +index 4b3796ba82e3..499f0c91c213 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts +@@ -27,6 +27,7 @@ &gmac1 { + managed = "in-band-status"; + phy-mode = "usxgmii"; + sfp = <&sfp2>; ++ status = "okay"; + }; + + &pca9545 { +diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +index 38e27ef6bc0c..a614729e9e47 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +@@ -3,6 +3,7 @@ + /dts-v1/; + + #include ++#include + #include + #include + +@@ -13,10 +14,20 @@ aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + ethernet2 = &gmac2; ++ led-boot = &led_green; ++ led-failsafe = &led_green; ++ led-running = &led_green; ++ led-upgrade = &led_green; + }; + + chosen { + stdout-path = "serial0:115200n8"; ++ bootargs = "loglevel=8 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0"; ++ rootdisk-spim-nand = <&ubi_rootfs>; ++ }; ++ ++ memory { ++ reg = <0x00 0x40000000 0x00 0x10000000>; + }; + + fan: pwm-fan { +@@ -28,6 +39,16 @@ fan: pwm-fan { + status = "okay"; + }; + ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ wps { ++ label = "WPS"; ++ linux,code = ; ++ gpios = <&pio 14 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ + gpio-leds { + compatible = "gpio-leds"; + +@@ -151,6 +172,7 @@ &gmac2 { + managed = "in-band-status"; + phy-mode = "usxgmii"; + sfp = <&sfp1>; ++ status = "okay"; + }; + + &gsw_phy0 { +@@ -280,7 +302,7 @@ pca9545: i2c-mux@70 { + #address-cells = <1>; + #size-cells = <0>; + +- i2c@0 { ++ i2c@0 { //eeprom,rtc,ngff + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; +@@ -288,12 +310,16 @@ i2c@0 { + pcf8563: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; ++ //interrupts = <&pio 6 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <0>; ++ //status = "disabled"; + }; + + eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; ++ address-bits = <8>; ++ page-size = <8>; + size = <256>; + }; + +@@ -304,6 +330,14 @@ i2c_sfp1: i2c@1 { + #size-cells = <0>; + reg = <1>; + }; ++ ++ i2c_wifi: i2c@3 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <3>; ++ ++ status = "disabled"; ++ }; + }; + }; + +@@ -455,7 +489,7 @@ partition@200000 { + reg = <0x200000 0x7e00000>; + compatible = "linux,ubi"; + +- /*volumes { ++ volumes { + ubi-volume-fip { + volname = "fip"; + }; +@@ -477,7 +511,7 @@ nvmem-layout { + ubi_rootfs: ubi-volume-rootfs { + volname = "rootfs"; + }; +- };*/ ++ }; + }; + }; + }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0051-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0051-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch new file mode 100644 index 000000000..4f75225d2 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0051-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -0,0 +1,578 @@ +From 2130ea2c451f40a26214c6702ea8230dd6da2044 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 12 Dec 2023 03:51:14 +0000 +Subject: [PATCH 51/84] net: ethernet: mtk_eth_soc: add paths and SerDes modes + for MT7988 + +MT7988 comes with two SerDes interfaces to connect external PHYs or +transceivers in USXGMII, 10GBase-R, 5GBase-R, 2500Base-X, 1000Base-X and +Cisco SGMII interface modes. + +Implement support for configuring for the new paths to SerDes interfaces. + +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/mtk_eth_path.c | 81 +++++++++- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 149 +++++++++++++++---- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++- + 3 files changed, 238 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c +index b4c01e2878f6..249b2fe7c10d 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -35,8 +35,16 @@ static const char *mtk_eth_path_name(u64 path) + return "gmac2_2p5gphy"; + case MTK_ETH_PATH_GMAC2_GEPHY: + return "gmac2_gephy"; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ return "gmac3_sgmii"; + case MTK_ETH_PATH_GDM1_ESW: + return "gdm1_esw"; ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ return "gmac1_usxgmii"; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ return "gmac2_usxgmii"; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ return "gmac3_usxgmii"; + default: + return "unknown path"; + } +@@ -190,7 +198,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) + return 0; + } + +-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) ++static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) ++{ ++ unsigned int val = 0; ++ bool updated = true; ++ int mac_id = 0; ++ ++ /* Disable SYSCFG1 SGMII */ ++ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); ++ ++ switch (path) { ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; ++ mac_id = MTK_GMAC1_ID; ++ break; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; ++ mac_id = MTK_GMAC2_ID; ++ break; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; ++ mac_id = MTK_GMAC3_ID; ++ break; ++ default: ++ updated = false; ++ }; ++ ++ if (updated) { ++ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, ++ SYSCFG0_SGMII_MASK, val); ++ ++ if (mac_id == MTK_GMAC2_ID) ++ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, ++ MUX_G2_USXGMII_SEL); ++ } ++ ++ dev_dbg(eth->dev, "path %s in %s updated = %d\n", ++ mtk_eth_path_name(path), __func__, updated); ++ ++ return 0; ++} ++ ++static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) + { + unsigned int val = 0; + bool updated = true; +@@ -207,6 +256,9 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) + case MTK_ETH_PATH_GMAC2_SGMII: + val |= SYSCFG0_SGMII_GMAC2_V2; + break; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ val |= SYSCFG0_SGMII_GMAC3_V2; ++ break; + default: + updated = false; + } +@@ -245,7 +297,15 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = { + }, { + .name = "mux_gmac12_to_gephy_sgmii", + .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, +- .set_path = set_mux_gmac12_to_gephy_sgmii, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_gephy_sgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_usxgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, ++ .set_path = set_mux_gmac123_to_usxgmii, + }, + }; + +@@ -278,12 +338,25 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path) + return err; + } + ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) ++{ ++ u64 path; ++ ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : ++ MTK_ETH_PATH_GMAC3_USXGMII; ++ ++ /* Setup proper MUXes along the path */ ++ return mtk_eth_mux_setup(eth, path); ++} ++ + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) + { + u64 path; + +- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : +- MTK_ETH_PATH_GMAC2_SGMII; ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : ++ MTK_ETH_PATH_GMAC3_SGMII; + + /* Setup proper MUXes along the path */ + return mtk_eth_mux_setup(eth, path); +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 7916c99d5ebb..ac7250003b1d 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -22,6 +22,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -514,23 +516,28 @@ static void mtk_setup_bridge_switch(struct mtk_eth *eth) + MTK_GSW_CFG); + } + +-static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, +- phy_interface_t interface) ++static bool mtk_check_gmac23_idle(struct mtk_mac *mac) + { +- struct mtk_mac *mac = container_of(config, struct mtk_mac, +- phylink_config); +- struct mtk_eth *eth = mac->hw; +- unsigned int sid; ++ u32 mac_fsm, gdm_fsm; + +- if (interface == PHY_INTERFACE_MODE_SGMII || +- phy_interface_mode_is_8023z(interface)) { +- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? +- 0 : mac->id; ++ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); + +- return eth->sgmii_pcs[sid]; +- } ++ switch (mac->id) { ++ case MTK_GMAC2_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); ++ break; ++ case MTK_GMAC3_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); ++ break; ++ default: ++ return true; ++ }; + +- return NULL; ++ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && ++ (gdm_fsm & 0xFFFF0000) == 0x00000000) ++ return true; ++ ++ return false; + } + + static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode, +@@ -593,6 +600,15 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, + goto init_err; + } + break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_5GBASER: ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { ++ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); ++ if (err) ++ goto init_err; ++ } ++ break; + case PHY_INTERFACE_MODE_INTERNAL: + if (mac->id == MTK_GMAC2_ID && + MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { +@@ -646,8 +662,6 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, + val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); + val |= SYSCFG0_GE_MODE(ge_mode, mac->id); + regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); +- +- mac->interface = state->interface; + } + + /* SGMII */ +@@ -664,9 +678,12 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, + + /* Save the syscfg0 value for mac_finish */ + mac->syscfg0 = val; +- } else if (phylink_autoneg_inband(mode)) { ++ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && ++ state->interface != PHY_INTERFACE_MODE_10GBASER && ++ state->interface != PHY_INTERFACE_MODE_5GBASER && ++ phylink_autoneg_inband(mode)) { + dev_err(eth->dev, +- "In-band mode not supported in non SGMII mode!\n"); ++ "In-band mode not supported in non-SerDes modes!\n"); + return; + } + +@@ -677,8 +694,22 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, + + if (mac->id == MTK_GMAC1_ID) + mtk_setup_bridge_switch(eth); ++ } else if (mtk_is_netsys_v3_or_greater(eth)) { ++ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); ++ ++ /* FIXME: In current hardware design, we have to reset FE ++ * when swtiching XGDM to GDM. Therefore, here trigger an SER ++ * to let GDM go back to the initial state. ++ */ ++ if ((mtk_interface_mode_is_xgmii(eth, mac->interface) || ++ mac->interface == PHY_INTERFACE_MODE_NA) && ++ !mtk_check_gmac23_idle(mac) && ++ !test_bit(MTK_RESETTING, ð->state)) ++ schedule_work(ð->pending_work); + } + ++ mac->interface = state->interface; ++ + return; + + err_phy: +@@ -729,6 +760,9 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, + mtk_m32(mac->hw, + MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, + MTK_MAC_MCR(mac->id)); ++ if (mtk_is_netsys_v3_or_greater(mac->hw)) ++ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, ++ MTK_XGMAC_STS(mac->id)); + } else if (mac->id != MTK_GMAC1_ID) { + /* XGMAC except for built-in switch */ + mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, +@@ -947,7 +981,6 @@ static int mtk_mac_enable_tx_lpi(struct phylink_config *config, u32 timer, + + static const struct phylink_mac_ops mtk_phylink_ops = { + .mac_prepare = mtk_mac_prepare, +- .mac_select_pcs = mtk_mac_select_pcs, + .mac_config = mtk_mac_config, + .mac_finish = mtk_mac_finish, + .mac_link_down = mtk_mac_link_down, +@@ -4774,7 +4807,8 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + phy_interface_t phy_mode; + struct phylink *phylink; + struct mtk_mac *mac; +- int id, err; ++ int id, err, count; ++ unsigned int sid; + int txqs = 1; + u32 val; + +@@ -4856,6 +4890,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD | + MAC_2500FD; + mac->phylink_config.lpi_timer_default = 1000; ++ mac->phylink_config.num_available_pcs = 0; + + /* MT7623 gmac0 is now missing its speed-specific PLL configuration + * in its .mac_config method (since state->speed is not valid there. +@@ -4886,13 +4921,52 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + + if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) { + __set_bit(PHY_INTERFACE_MODE_SGMII, +- mac->phylink_config.supported_interfaces); ++ mac->phylink_config.pcs_interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, +- mac->phylink_config.supported_interfaces); ++ mac->phylink_config.pcs_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, +- mac->phylink_config.supported_interfaces); ++ mac->phylink_config.pcs_interfaces); ++ ++ if (mtk_is_netsys_v3_or_greater(mac->hw)) { ++ __set_bit(PHY_INTERFACE_MODE_5GBASER, ++ mac->phylink_config.pcs_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, ++ mac->phylink_config.pcs_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, ++ mac->phylink_config.pcs_interfaces); ++ ++ err = fwnode_phylink_pcs_parse(of_fwnode_handle(np), NULL, &count); ++ if (err == -ENODEV) { ++ err = 0; ++ goto no_pcs; ++ } ++ ++ if (count > 2) ++ err = -ENOMEM; ++ ++ if (err) ++ goto free_netdev; ++ ++ err = fwnode_phylink_pcs_parse(of_fwnode_handle(np), mac->available_pcs, &count); ++ if (err) ++ goto free_netdev; ++ ++ mac->phylink_config.available_pcs = mac->available_pcs; ++ mac->phylink_config.num_available_pcs = count; ++ } else { ++ sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? ++ 0 : id; ++ ++ mac->phylink_config.available_pcs = ð->sgmii_pcs[sid]; ++ mac->phylink_config.num_available_pcs = 1; ++ } ++ ++ phy_interface_or(mac->phylink_config.supported_interfaces, ++ mac->phylink_config.supported_interfaces, ++ mac->phylink_config.pcs_interfaces); + } + ++no_pcs: + if (mtk_is_netsys_v3_or_greater(mac->hw) && + MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW) && + id == MTK_GMAC1_ID) { +@@ -4902,18 +4976,16 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + phy_interface_zero(mac->phylink_config.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + mac->phylink_config.supported_interfaces); ++ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { ++ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; ++ __set_bit(PHY_INTERFACE_MODE_5GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, ++ mac->phylink_config.supported_interfaces); + } + +- phylink = phylink_create(&mac->phylink_config, +- of_fwnode_handle(mac->of_node), +- phy_mode, &mtk_phylink_ops); +- if (IS_ERR(phylink)) { +- err = PTR_ERR(phylink); +- goto free_netdev; +- } +- +- mac->phylink = phylink; +- + if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && + id == MTK_GMAC2_ID) + __set_bit(PHY_INTERFACE_MODE_INTERNAL, +@@ -4936,6 +5008,16 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + eth->netdev[id]->irq = eth->irq[MTK_FE_IRQ_SHARED]; + eth->netdev[id]->dev.of_node = np; + ++ phylink = phylink_create(&mac->phylink_config, ++ of_fwnode_handle(mac->of_node), ++ phy_mode, &mtk_phylink_ops); ++ if (IS_ERR(phylink)) { ++ err = PTR_ERR(phylink); ++ goto free_netdev; ++ } ++ ++ mac->phylink = phylink; ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN; + else +@@ -5112,7 +5194,8 @@ static int mtk_probe(struct platform_device *pdev) + regmap_write(cci, 0, 3); + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) && ++ !mtk_is_netsys_v3_or_greater(eth)) { + err = mtk_sgmii_init(eth); + + if (err) +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 0168e2fbc619..88406e80dfec 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -567,6 +568,7 @@ + #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) + #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) ++#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) + + + /* ethernet subsystem clock register */ +@@ -608,6 +610,7 @@ + #define TOP_MISC_NETSYS_PCS_MUX 0x0 + #define NETSYS_PCS_MUX_MASK GENMASK(1, 0) + #define MUX_G2_USXGMII_SEL BIT(1) ++#define MUX_HSGMII1_G1_SEL BIT(0) + + #define USB_PHY_SWITCH_REG 0x218 + #define QPHY_SEL_MASK GENMASK(1, 0) +@@ -633,6 +636,8 @@ + #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) + #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + ++/* Debug Purpose Register */ ++#define MTK_PSE_FQFC_CFG 0x100 + #define MTK_FE_CDM1_FSM 0x220 + #define MTK_FE_CDM2_FSM 0x224 + #define MTK_FE_CDM3_FSM 0x238 +@@ -641,6 +646,11 @@ + #define MTK_FE_CDM6_FSM 0x328 + #define MTK_FE_GDM1_FSM 0x228 + #define MTK_FE_GDM2_FSM 0x22C ++#define MTK_FE_GDM3_FSM 0x23C ++#define MTK_FE_PSE_FREE 0x240 ++#define MTK_FE_DROP_FQ 0x244 ++#define MTK_FE_DROP_FC 0x248 ++#define MTK_FE_DROP_PPE 0x24C + + #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + +@@ -978,6 +988,7 @@ enum mkt_eth_capabilities { + MTK_RGMII_BIT = 0, + MTK_TRGMII_BIT, + MTK_SGMII_BIT, ++ MTK_USXGMII_BIT, + MTK_2P5GPHY_BIT, + MTK_ESW_BIT, + MTK_GEPHY_BIT, +@@ -1002,6 +1013,8 @@ enum mkt_eth_capabilities { + MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, + MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, + MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_RGMII_BIT, +@@ -1011,13 +1024,18 @@ enum mkt_eth_capabilities { + MTK_ETH_PATH_GMAC2_SGMII_BIT, + MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, + MTK_ETH_PATH_GMAC2_GEPHY_BIT, ++ MTK_ETH_PATH_GMAC3_SGMII_BIT, + MTK_ETH_PATH_GDM1_ESW_BIT, ++ MTK_ETH_PATH_GMAC1_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC2_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC3_USXGMII_BIT, + }; + + /* Supported hardware group on SoCs */ + #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) + #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) + #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) ++#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) + #define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) + #define MTK_ESW BIT_ULL(MTK_ESW_BIT) + #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) +@@ -1047,6 +1065,10 @@ enum mkt_eth_capabilities { + BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) + #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ + BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) + + /* Supported path present on SoCs */ + #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) +@@ -1056,7 +1078,11 @@ enum mkt_eth_capabilities { + #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) + #define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) + #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) ++#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) + #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) ++#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) + + #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) + #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) +@@ -1065,7 +1091,11 @@ enum mkt_eth_capabilities { + #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) + #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) + #define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) ++#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) + #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) ++#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) ++#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) ++#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) + + /* MUXes present on SoCs */ + /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ +@@ -1092,6 +1122,12 @@ enum mkt_eth_capabilities { + #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ + (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) + ++#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) ++ ++#define MTK_MUX_GMAC123_TO_USXGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) ++ + #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) + + #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ +@@ -1123,9 +1159,12 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1 | MTK_SRAM) + +-#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC2_2P5GPHY | \ +- MTK_MUX_GMAC2_TO_2P5GPHY | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ +- MTK_RSTCTRL_PPE2 | MTK_SRAM) ++#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ ++ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ ++ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ ++ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ ++ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ ++ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1372,6 +1411,8 @@ struct mtk_mac { + struct device_node *of_node; + struct phylink *phylink; + struct phylink_config phylink_config; ++ struct phylink_pcs *current_pcs; ++ struct phylink_pcs *available_pcs[2]; + struct mtk_eth *hw; + struct mtk_hw_stats *hw_stats; + __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; +@@ -1506,6 +1547,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); + + int mtk_eth_offload_init(struct mtk_eth *eth, u8 id); + int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0052-net-phylink-keep-and-use-MAC-supported_interfaces-in.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0052-net-phylink-keep-and-use-MAC-supported_interfaces-in.patch new file mode 100644 index 000000000..3517db358 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0052-net-phylink-keep-and-use-MAC-supported_interfaces-in.patch @@ -0,0 +1,108 @@ +From 7d9a25bf143c3edee1ad46a57ac64acc0c49316d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:13:55 +0200 +Subject: [PATCH 52/84] net: phylink: keep and use MAC supported_interfaces in + phylink struct + +Add in phylink struct a copy of supported_interfaces from phylink_config +and make use of that instead of relying on phylink_config value. + +This in preparation for support of PCS handling internally to phylink +where a PCS can be removed or added after the phylink is created and we +need both a reference of the supported_interfaces value from +phylink_config and an internal value that can be updated with the new +PCS info. + +Signed-off-by: Christian Marangi +--- + drivers/net/phy/phylink.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index 229a503d601e..a0cfa49fe84c 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -59,6 +59,11 @@ struct phylink { + /* The link configuration settings */ + struct phylink_link_state link_config; + ++ /* What interface are supported by the current link. ++ * Can change on removal or addition of new PCS. ++ */ ++ DECLARE_PHY_INTERFACE_MASK(supported_interfaces); ++ + /* The current settings */ + phy_interface_t cur_interface; + +@@ -612,7 +617,7 @@ static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, + static int phylink_validate(struct phylink *pl, unsigned long *supported, + struct phylink_link_state *state) + { +- const unsigned long *interfaces = pl->config->supported_interfaces; ++ const unsigned long *interfaces = pl->supported_interfaces; + + if (state->interface == PHY_INTERFACE_MODE_NA) + return phylink_validate_mask(pl, NULL, supported, state, +@@ -1825,6 +1830,9 @@ struct phylink *phylink_create(struct phylink_config *config, + mutex_init(&pl->state_mutex); + INIT_WORK(&pl->resolve, phylink_resolve); + ++ phy_interface_copy(pl->supported_interfaces, ++ config->supported_interfaces); ++ + pl->config = config; + if (config->type == PHYLINK_NETDEV) { + pl->netdev = to_net_dev(config->dev); +@@ -1983,7 +1991,7 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, + * those which the host supports. + */ + phy_interface_and(interfaces, phy->possible_interfaces, +- pl->config->supported_interfaces); ++ pl->supported_interfaces); + + if (phy_interface_empty(interfaces)) { + phylink_err(pl, "PHY has no common interfaces\n"); +@@ -2706,12 +2714,12 @@ static phy_interface_t phylink_sfp_select_interface(struct phylink *pl, + return interface; + } + +- if (!test_bit(interface, pl->config->supported_interfaces)) { ++ if (!test_bit(interface, pl->supported_interfaces)) { + phylink_err(pl, + "selection of interface failed, SFP selected %s (%u) but MAC supports %*pbl\n", + phy_modes(interface), interface, + (int)PHY_INTERFACE_MODE_MAX, +- pl->config->supported_interfaces); ++ pl->supported_interfaces); + return PHY_INTERFACE_MODE_NA; + } + +@@ -3598,14 +3606,14 @@ static int phylink_sfp_config_optical(struct phylink *pl) + + phylink_dbg(pl, "optical SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n", + (int)PHY_INTERFACE_MODE_MAX, +- pl->config->supported_interfaces, ++ pl->supported_interfaces, + (int)PHY_INTERFACE_MODE_MAX, + pl->sfp_interfaces); + + /* Find the union of the supported interfaces by the PCS/MAC and + * the SFP module. + */ +- phy_interface_and(interfaces, pl->config->supported_interfaces, ++ phy_interface_and(interfaces, pl->supported_interfaces, + pl->sfp_interfaces); + if (phy_interface_empty(interfaces)) { + phylink_err(pl, "unsupported SFP module: no common interface modes\n"); +@@ -3751,7 +3759,7 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) + + /* Set the PHY's host supported interfaces */ + phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, +- pl->config->supported_interfaces); ++ pl->supported_interfaces); + + /* Do the initial configuration */ + return phylink_sfp_config_phy(pl, phy); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0053-net-phy-introduce-phy_interface_copy-helper.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0053-net-phy-introduce-phy_interface_copy-helper.patch new file mode 100644 index 000000000..f8eb386bb --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0053-net-phy-introduce-phy_interface_copy-helper.patch @@ -0,0 +1,36 @@ +From 8ba5b5a70e5c337ecbb42de895dc06c50f129de3 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:13:56 +0200 +Subject: [PATCH 53/84] net: phy: introduce phy_interface_copy helper + +Introduce phy_interface_copy helper as a shorthand to copy the PHY +interface bitmap to a different location. + +This is useful if a PHY interface bitmap needs to be stored in a +different variable and needs to be reset to an original value saved in a +different bitmap. + +Signed-off-by: Christian Marangi +--- + include/linux/phy.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/linux/phy.h b/include/linux/phy.h +index e194dad1623d..6e09b2290726 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -173,6 +173,11 @@ static inline void phy_interface_or(unsigned long *dst, const unsigned long *a, + bitmap_or(dst, a, b, PHY_INTERFACE_MODE_MAX); + } + ++static inline void phy_interface_copy(unsigned long *dst, const unsigned long *src) ++{ ++ bitmap_copy(dst, src, PHY_INTERFACE_MODE_MAX); ++} ++ + static inline void phy_interface_set_rgmii(unsigned long *intf) + { + __set_bit(PHY_INTERFACE_MODE_RGMII, intf); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0054-net-phylink-introduce-internal-phylink-PCS-handling.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0054-net-phylink-introduce-internal-phylink-PCS-handling.patch new file mode 100644 index 000000000..28dc27d7a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0054-net-phylink-introduce-internal-phylink-PCS-handling.patch @@ -0,0 +1,388 @@ +From 5515ca927f396489c7bc2224289777e60295e0f0 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:13:57 +0200 +Subject: [PATCH 54/84] net: phylink: introduce internal phylink PCS handling + +Introduce internal handling of PCS for phylink. This is an alternative +to .mac_select_pcs that moves the selection logic of the PCS entirely to +phylink with the usage of supported_interface value in the PCS struct. + +MAC should now provide an array of available PCS in phylink_config in +.available_pcs and fill the .num_available_pcs with the number of +elements in the array. MAC should also define a new bitmap, +pcs_interfaces, in phylink_config to define for what interface mode a +dedicated PCS is required. + +On phylink_create() this array is parsed and a linked list of PCS is +created based on the PCS passed in phylink_config. +Also the supported_interface value in phylink struct is updated with the +new supported_interface from the provided PCS. + +On phylink_start() every PCS in phylink PCS list gets attached to the +phylink instance. This is done by setting the phylink value in +phylink_pcs struct to the phylink instance. + +On phylink_stop(), every PCS in phylink PCS list is detached from the +phylink instance. This is done by setting the phylink value in +phylink_pcs struct to NULL. + +On phylink_stop(), every PCS in phylink PCS list is removed from the +list. + +phylink_validate_mac_and_pcs(), phylink_major_config() and +phylink_inband_caps() are updated to support this new implementation +with the PCS list stored in phylink. + +They will make use of phylink_validate_pcs_interface() that will loop +for every PCS in the phylink PCS available list and find one that supports +the passed interface. + +phylink_validate_pcs_interface() apply the same logic of .mac_select_pcs +where if a supported_interface value is not set for the PCS struct, then +it's assumed every interface is supported. + +It's required for a MAC that implement either a .mac_select_pcs or make +use of the PCS list implementation. Implementing both will result in a fail +on MAC/PCS validation. + +phylink value in phylink_pcs struct with this implementation is used to +track from PCS side when it's attached to a phylink instance. PCS driver +will make use of this information to correctly detach from a phylink +instance if needed. + +The .mac_select_pcs implementation is not changed but it's expected that +every MAC driver migrates to the new implementation to later deprecate +and remove .mac_select_pcs. + +Signed-off-by: Christian Marangi +--- + drivers/net/phy/phylink.c | 147 +++++++++++++++++++++++++++++++++----- + include/linux/phylink.h | 10 +++ + 2 files changed, 139 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index a0cfa49fe84c..8539519536b2 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -59,6 +59,9 @@ struct phylink { + /* The link configuration settings */ + struct phylink_link_state link_config; + ++ /* List of available PCS */ ++ struct list_head pcs_list; ++ + /* What interface are supported by the current link. + * Can change on removal or addition of new PCS. + */ +@@ -146,6 +149,8 @@ static const phy_interface_t phylink_sfp_interface_preference[] = { + + static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); + ++static void phylink_run_resolve(struct phylink *pl); ++ + /** + * phylink_set_port_modes() - set the port type modes in the ethtool mask + * @mask: ethtool link mode mask +@@ -501,22 +506,59 @@ static void phylink_validate_mask_caps(unsigned long *supported, + linkmode_and(state->advertising, state->advertising, mask); + } + ++static int phylink_validate_pcs_interface(struct phylink_pcs *pcs, ++ phy_interface_t interface) ++{ ++ /* If PCS define an empty supported_interfaces value, assume ++ * all interface are supported. ++ */ ++ if (phy_interface_empty(pcs->supported_interfaces)) ++ return 0; ++ ++ /* Ensure that this PCS supports the interface mode */ ++ if (!test_bit(interface, pcs->supported_interfaces)) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static int phylink_validate_mac_and_pcs(struct phylink *pl, + unsigned long *supported, + struct phylink_link_state *state) + { +- struct phylink_pcs *pcs = NULL; + unsigned long capabilities; ++ struct phylink_pcs *pcs; ++ bool pcs_found = false; + int ret; + + /* Get the PCS for this interface mode */ + if (pl->mac_ops->mac_select_pcs) { ++ /* Make sure either PCS internal validation or .mac_select_pcs ++ * is used. Return error if both are defined. ++ */ ++ if (!list_empty(&pl->pcs_list)) { ++ phylink_err(pl, "either phylink_pcs_add() or .mac_select_pcs must be used\n"); ++ return -EINVAL; ++ } ++ + pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); + if (IS_ERR(pcs)) + return PTR_ERR(pcs); ++ ++ pcs_found = !!pcs; ++ } else { ++ /* Check every assigned PCS and search for one that supports ++ * the interface. ++ */ ++ list_for_each_entry(pcs, &pl->pcs_list, list) { ++ if (!phylink_validate_pcs_interface(pcs, state->interface)) { ++ pcs_found = true; ++ break; ++ } ++ } + } + +- if (pcs) { ++ if (pcs_found) { + /* The PCS, if present, must be setup before phylink_create() + * has been called. If the ops is not initialised, print an + * error and backtrace rather than oopsing the kernel. +@@ -528,13 +570,10 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, + return -EINVAL; + } + +- /* Ensure that this PCS supports the interface which the MAC +- * returned it for. It is an error for the MAC to return a PCS +- * that does not support the interface mode. +- */ +- if (!phy_interface_empty(pcs->supported_interfaces) && +- !test_bit(state->interface, pcs->supported_interfaces)) { +- phylink_err(pl, "MAC returned PCS which does not support %s\n", ++ /* Recheck PCS to handle legacy way for .mac_select_pcs */ ++ ret = phylink_validate_pcs_interface(pcs, state->interface); ++ if (ret) { ++ phylink_err(pl, "selected PCS does not support %s\n", + phy_modes(state->interface)); + return -EINVAL; + } +@@ -939,12 +978,22 @@ static unsigned int phylink_inband_caps(struct phylink *pl, + phy_interface_t interface) + { + struct phylink_pcs *pcs; ++ bool pcs_found = false; + +- if (!pl->mac_ops->mac_select_pcs) +- return 0; ++ if (pl->mac_ops->mac_select_pcs) { ++ pcs = pl->mac_ops->mac_select_pcs(pl->config, ++ interface); ++ pcs_found = !!pcs; ++ } else { ++ list_for_each_entry(pcs, &pl->pcs_list, list) { ++ if (!phylink_validate_pcs_interface(pcs, interface)) { ++ pcs_found = true; ++ break; ++ } ++ } ++ } + +- pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); +- if (!pcs) ++ if (!pcs_found) + return 0; + + return phylink_pcs_inband_caps(pcs, interface); +@@ -1230,10 +1279,36 @@ static void phylink_major_config(struct phylink *pl, bool restart, + pl->major_config_failed = true; + return; + } ++ /* Find a PCS in available PCS list for the requested interface. ++ * This doesn't overwrite the previous .mac_select_pcs as either ++ * .mac_select_pcs or PCS list implementation are permitted. ++ * ++ * Skip searching if the MAC doesn't require a dedicaed PCS for ++ * the requested interface. ++ */ ++ } else if (test_bit(state->interface, pl->config->pcs_interfaces)) { ++ bool pcs_found = false; ++ ++ list_for_each_entry(pcs, &pl->pcs_list, list) { ++ if (!phylink_validate_pcs_interface(pcs, ++ state->interface)) { ++ pcs_found = true; ++ break; ++ } ++ } ++ ++ if (!pcs_found) { ++ phylink_err(pl, ++ "couldn't find a PCS for %s\n", ++ phy_modes(state->interface)); + +- pcs_changed = pl->pcs != pcs; ++ pl->major_config_failed = true; ++ return; ++ } + } + ++ pcs_changed = pl->pcs != pcs; ++ + phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); + + phylink_dbg(pl, "major config, active %s/%s/%s\n", +@@ -1260,10 +1335,12 @@ static void phylink_major_config(struct phylink *pl, bool restart, + if (pcs_changed) { + phylink_pcs_disable(pl->pcs); + +- if (pl->pcs) +- pl->pcs->phylink = NULL; ++ if (pl->mac_ops->mac_select_pcs) { ++ if (pl->pcs) ++ pl->pcs->phylink = NULL; + +- pcs->phylink = pl; ++ pcs->phylink = pl; ++ } + + pl->pcs = pcs; + } +@@ -1812,8 +1889,9 @@ struct phylink *phylink_create(struct phylink_config *config, + phy_interface_t iface, + const struct phylink_mac_ops *mac_ops) + { ++ struct phylink_pcs *pcs; + struct phylink *pl; +- int ret; ++ int i, ret; + + /* Validate the supplied configuration */ + if (phy_interface_empty(config->supported_interfaces)) { +@@ -1829,9 +1907,21 @@ struct phylink *phylink_create(struct phylink_config *config, + mutex_init(&pl->phydev_mutex); + mutex_init(&pl->state_mutex); + INIT_WORK(&pl->resolve, phylink_resolve); ++ INIT_LIST_HEAD(&pl->pcs_list); ++ ++ /* Fill the PCS list with available PCS from phylink config */ ++ for (i = 0; i < config->num_available_pcs; i++) { ++ pcs = config->available_pcs[i]; ++ ++ list_add(&pcs->list, &pl->pcs_list); ++ } + + phy_interface_copy(pl->supported_interfaces, + config->supported_interfaces); ++ list_for_each_entry(pcs, &pl->pcs_list, list) ++ phy_interface_or(pl->supported_interfaces, ++ pl->supported_interfaces, ++ pcs->supported_interfaces); + + pl->config = config; + if (config->type == PHYLINK_NETDEV) { +@@ -1910,10 +2000,16 @@ EXPORT_SYMBOL_GPL(phylink_create); + */ + void phylink_destroy(struct phylink *pl) + { ++ struct phylink_pcs *pcs, *tmp; ++ + sfp_bus_del_upstream(pl->sfp_bus); + if (pl->link_gpio) + gpiod_put(pl->link_gpio); + ++ /* Remove every PCS from phylink PCS list */ ++ list_for_each_entry_safe(pcs, tmp, &pl->pcs_list, list) ++ list_del(&pcs->list); ++ + cancel_work_sync(&pl->resolve); + kfree(pl); + } +@@ -2396,6 +2492,7 @@ static irqreturn_t phylink_link_handler(int irq, void *data) + */ + void phylink_start(struct phylink *pl) + { ++ struct phylink_pcs *pcs; + bool poll = false; + + ASSERT_RTNL(); +@@ -2422,6 +2519,10 @@ void phylink_start(struct phylink *pl) + + pl->pcs_state = PCS_STATE_STARTED; + ++ /* link available PCS to phylink struct */ ++ list_for_each_entry(pcs, &pl->pcs_list, list) ++ pcs->phylink = pl; ++ + phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED); + + if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { +@@ -2466,6 +2567,8 @@ EXPORT_SYMBOL_GPL(phylink_start); + */ + void phylink_stop(struct phylink *pl) + { ++ struct phylink_pcs *pcs; ++ + ASSERT_RTNL(); + + if (pl->sfp_bus) +@@ -2483,6 +2586,14 @@ void phylink_stop(struct phylink *pl) + pl->pcs_state = PCS_STATE_DOWN; + + phylink_pcs_disable(pl->pcs); ++ ++ /* Drop link between phylink and PCS */ ++ list_for_each_entry(pcs, &pl->pcs_list, list) ++ pcs->phylink = NULL; ++ ++ /* Restore original supported interfaces */ ++ phy_interface_copy(pl->supported_interfaces, ++ pl->config->supported_interfaces); + } + EXPORT_SYMBOL_GPL(phylink_stop); + +diff --git a/include/linux/phylink.h b/include/linux/phylink.h +index 30659b615fca..ef0b5a0729c8 100644 +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -150,12 +150,16 @@ enum phylink_op_type { + * if MAC link is at %MLO_AN_FIXED mode. + * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx + * are supported by the MAC/PCS. ++ * @pcs_interfaces: bitmap describing for which PHY_INTERFACE_MODE_xxx a ++ * dedicated PCS is required. + * @lpi_interfaces: bitmap describing which PHY interface modes can support + * LPI signalling. + * @mac_capabilities: MAC pause/speed/duplex capabilities. + * @lpi_capabilities: MAC speeds which can support LPI signalling + * @lpi_timer_default: Default EEE LPI timer setting. + * @eee_enabled_default: If set, EEE will be enabled by phylink at creation time ++ * @available_pcs: array of available phylink_pcs PCS ++ * @num_available_pcs: num of available phylink_pcs PCS + */ + struct phylink_config { + struct device *dev; +@@ -168,11 +172,14 @@ struct phylink_config { + void (*get_fixed_state)(struct phylink_config *config, + struct phylink_link_state *state); + DECLARE_PHY_INTERFACE_MASK(supported_interfaces); ++ DECLARE_PHY_INTERFACE_MASK(pcs_interfaces); + DECLARE_PHY_INTERFACE_MASK(lpi_interfaces); + unsigned long mac_capabilities; + unsigned long lpi_capabilities; + u32 lpi_timer_default; + bool eee_enabled_default; ++ struct phylink_pcs **available_pcs; ++ unsigned int num_available_pcs; + }; + + void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed); +@@ -469,6 +476,9 @@ struct phylink_pcs { + struct phylink *phylink; + bool poll; + bool rxc_always_on; ++ ++ /* private: */ ++ struct list_head list; + }; + + /** +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0055-net-phylink-add-phylink_release_pcs-to-externally-re.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0055-net-phylink-add-phylink_release_pcs-to-externally-re.patch new file mode 100644 index 000000000..e6c517471 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0055-net-phylink-add-phylink_release_pcs-to-externally-re.patch @@ -0,0 +1,142 @@ +From b9b90aa82fedf47b035bc1f7196037e0cb481e41 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:13:58 +0200 +Subject: [PATCH 55/84] net: phylink: add phylink_release_pcs() to externally + release a PCS + +Add phylink_release_pcs() to externally release a PCS from a phylink +instance. This can be used to handle case when a single PCS needs to be +removed and the phylink instance needs to be refreshed. + +On calling phylink_release_pcs(), the PCS will be removed from the +phylink internal PCS list and the phylink supported_interfaces value is +reparsed with the remaining PCS interfaces. + +Also a phylink resolve is triggered to handle the PCS removal. + +It's also added to phylink a flag to make phylink resolve reconfigure +the interface mode (even if it didn't change). This is needed to handle +the special case when the current PCS used by phylink is removed and a +major_config is needed to propagae the configuration change. With this +option enabled we also force mac_config even if the PHY link is not up +for the in-band case. + +Signed-off-by: Christian Marangi +--- + drivers/net/phy/phylink.c | 58 ++++++++++++++++++++++++++++++++++++++- + include/linux/phylink.h | 2 ++ + 2 files changed, 59 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index 8539519536b2..ef393e49a314 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -86,6 +86,7 @@ struct phylink { + bool link_failed; + bool suspend_link_up; + bool major_config_failed; ++ bool reconfig_interface; + bool mac_supports_eee_ops; + bool mac_supports_eee; + bool phy_enable_tx_lpi; +@@ -897,6 +898,55 @@ static void phylink_resolve_an_pause(struct phylink_link_state *state) + } + } + ++/** ++ * phylink_release_pcs - Removes a PCS from the phylink PCS available list ++ * @pcs: a pointer to the phylink_pcs struct to be released ++ * ++ * This function release a PCS from the phylink PCS available list if ++ * actually in use. It also refreshes the supported interfaces of the ++ * phylink instance by copying the supported interfaces from the phylink ++ * conf and merging the supported interfaces of the remaining available PCS ++ * in the list and trigger a resolve. ++ */ ++void phylink_release_pcs(struct phylink_pcs *pcs) ++{ ++ struct phylink *pl; ++ ++ ASSERT_RTNL(); ++ ++ pl = pcs->phylink; ++ if (!pl) ++ return; ++ ++ list_del(&pcs->list); ++ pcs->phylink = NULL; ++ ++ /* Check if we are removing the PCS currently ++ * in use by phylink. If this is the case, ++ * force phylink resolve to reconfigure the interface ++ * mode and set the phylink PCS to NULL. ++ */ ++ if (pl->pcs == pcs) { ++ mutex_lock(&pl->state_mutex); ++ ++ pl->reconfig_interface = true; ++ pl->pcs = NULL; ++ ++ mutex_unlock(&pl->state_mutex); ++ } ++ ++ /* Refresh supported interfaces */ ++ phy_interface_copy(pl->supported_interfaces, ++ pl->config->supported_interfaces); ++ list_for_each_entry(pcs, &pl->pcs_list, list) ++ phy_interface_or(pl->supported_interfaces, ++ pl->supported_interfaces, ++ pcs->supported_interfaces); ++ ++ phylink_run_resolve(pl); ++} ++EXPORT_SYMBOL_GPL(phylink_release_pcs); ++ + static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface) + { +@@ -1700,6 +1750,10 @@ static void phylink_resolve(struct work_struct *w) + if (phy) + link_state.link &= pl->phy_state.link; + ++ /* Force mac_config if we need to reconfig the interface */ ++ if (pl->reconfig_interface) ++ mac_config = true; ++ + /* Only update if the PHY link is up */ + if (phy && pl->phy_state.link) { + /* If the interface has changed, force a link down +@@ -1734,7 +1788,8 @@ static void phylink_resolve(struct work_struct *w) + phylink_apply_manual_flow(pl, &link_state); + + if (mac_config) { +- if (link_state.interface != pl->link_config.interface) { ++ if (link_state.interface != pl->link_config.interface || ++ pl->reconfig_interface) { + /* The interface has changed, force the link down and + * then reconfigure. + */ +@@ -1744,6 +1799,7 @@ static void phylink_resolve(struct work_struct *w) + } + phylink_major_config(pl, false, &link_state); + pl->link_config.interface = link_state.interface; ++ pl->reconfig_interface = false; + } + } + +diff --git a/include/linux/phylink.h b/include/linux/phylink.h +index ef0b5a0729c8..c5496c063b6a 100644 +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -717,6 +717,8 @@ void phylink_disconnect_phy(struct phylink *); + int phylink_set_fixed_link(struct phylink *, + const struct phylink_link_state *); + ++void phylink_release_pcs(struct phylink_pcs *pcs); ++ + void phylink_mac_change(struct phylink *, bool up); + void phylink_pcs_change(struct phylink_pcs *, bool up); + +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0056-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0056-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch new file mode 100644 index 000000000..06d310cce --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0056-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch @@ -0,0 +1,401 @@ +From 05d36511b44291340cdb31205d39b3e53ab56e04 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:13:59 +0200 +Subject: [PATCH 56/84] net: pcs: implement Firmware node support for PCS + driver + +Implement the foundation of Firmware node support for PCS driver. + +To support this, implement a simple Provider API where a PCS driver can +expose multiple PCS with an xlate .get function. + +PCS driver will have to call fwnode_pcs_add_provider() and pass the +firmware node pointer and a xlate function to return the correct PCS for +the passed #pcs-cells. + +This will register the PCS in a global list of providers so that +consumer can access it. + +Consumer will then use fwnode_pcs_get() to get the actual PCS by passing +the firmware node pointer and the index for #pcs-cells. + +For simple implementation where #pcs-cells is 0 and the PCS driver +expose a single PCS, the xlate function fwnode_pcs_simple_get() is +provided. + +For advanced implementation a custom xlate function is required. + +PCS driver on removal should first delete as a provider with +the usage of fwnode_pcs_del_provider() and then call +phylink_release_pcs() on every PCS the driver provides and + +A generic function fwnode_phylink_pcs_parse() is provided for any MAC +driver that will declare PCS in DT (or ACPI). +This function will parse "pcs-handle" property and fill the passed array +with the parsed PCS in availabel_pcs up to the passed num_pcs value. +It's also possible to pass NULL as array to only parse the PCS and +update the num_pcs value with the count of scanned PCS. + +Co-developed-by: Daniel Golle +Signed-off-by: Daniel Golle +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/Kconfig | 7 ++ + drivers/net/pcs/Makefile | 1 + + drivers/net/pcs/pcs.c | 201 +++++++++++++++++++++++++++++++ + include/linux/pcs/pcs-provider.h | 41 +++++++ + include/linux/pcs/pcs.h | 56 +++++++++ + 5 files changed, 306 insertions(+) + create mode 100644 drivers/net/pcs/pcs.c + create mode 100644 include/linux/pcs/pcs-provider.h + create mode 100644 include/linux/pcs/pcs.h + +diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig +index f6aa437473de..2951aa2f4cda 100644 +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -5,6 +5,13 @@ + + menu "PCS device drivers" + ++config FWNODE_PCS ++ tristate ++ depends on (ACPI || OF) ++ depends on PHYLINK ++ help ++ Firmware node PCS accessors ++ + config PCS_XPCS + tristate "Synopsys DesignWare Ethernet XPCS" + select PHYLINK +diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile +index 4f7920618b90..3005cdd89ab7 100644 +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + # Makefile for Linux PCS drivers + ++obj-$(CONFIG_FWNODE_PCS) += pcs.o + pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ + pcs-xpcs-nxp.o pcs-xpcs-wx.o + +diff --git a/drivers/net/pcs/pcs.c b/drivers/net/pcs/pcs.c +new file mode 100644 +index 000000000000..14a5cd3eeda1 +--- /dev/null ++++ b/drivers/net/pcs/pcs.c +@@ -0,0 +1,201 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_DESCRIPTION("PCS library"); ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_LICENSE("GPL"); ++ ++struct fwnode_pcs_provider { ++ struct list_head link; ++ ++ struct fwnode_handle *fwnode; ++ struct phylink_pcs *(*get)(struct fwnode_reference_args *pcsspec, ++ void *data); ++ ++ void *data; ++}; ++ ++static LIST_HEAD(fwnode_pcs_providers); ++static DEFINE_MUTEX(fwnode_pcs_mutex); ++ ++struct phylink_pcs *fwnode_pcs_simple_get(struct fwnode_reference_args *pcsspec, ++ void *data) ++{ ++ return data; ++} ++EXPORT_SYMBOL_GPL(fwnode_pcs_simple_get); ++ ++int fwnode_pcs_add_provider(struct fwnode_handle *fwnode, ++ struct phylink_pcs *(*get)(struct fwnode_reference_args *pcsspec, ++ void *data), ++ void *data) ++{ ++ struct fwnode_pcs_provider *pp; ++ ++ if (!fwnode) ++ return 0; ++ ++ pp = kzalloc(sizeof(*pp), GFP_KERNEL); ++ if (!pp) ++ return -ENOMEM; ++ ++ pp->fwnode = fwnode_handle_get(fwnode); ++ pp->data = data; ++ pp->get = get; ++ ++ mutex_lock(&fwnode_pcs_mutex); ++ list_add(&pp->link, &fwnode_pcs_providers); ++ mutex_unlock(&fwnode_pcs_mutex); ++ pr_debug("Added pcs provider from %pfwf\n", fwnode); ++ ++ fwnode_dev_initialized(fwnode, true); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(fwnode_pcs_add_provider); ++ ++void fwnode_pcs_del_provider(struct fwnode_handle *fwnode) ++{ ++ struct fwnode_pcs_provider *pp; ++ ++ if (!fwnode) ++ return; ++ ++ mutex_lock(&fwnode_pcs_mutex); ++ list_for_each_entry(pp, &fwnode_pcs_providers, link) { ++ if (pp->fwnode == fwnode) { ++ list_del(&pp->link); ++ fwnode_dev_initialized(pp->fwnode, false); ++ fwnode_handle_put(pp->fwnode); ++ kfree(pp); ++ break; ++ } ++ } ++ mutex_unlock(&fwnode_pcs_mutex); ++} ++EXPORT_SYMBOL_GPL(fwnode_pcs_del_provider); ++ ++static int fwnode_parse_pcsspec(const struct fwnode_handle *fwnode, int index, ++ const char *name, ++ struct fwnode_reference_args *out_args) ++{ ++ int ret = -ENOENT; ++ ++ if (!fwnode) ++ return -ENOENT; ++ ++ if (name) ++ index = fwnode_property_match_string(fwnode, "pcs-names", ++ name); ++ ++ ret = fwnode_property_get_reference_args(fwnode, "pcs-handle", ++ "#pcs-cells", ++ -1, index, out_args); ++ if (ret || (name && index < 0)) ++ return ret; ++ ++ return 0; ++} ++ ++static struct phylink_pcs * ++fwnode_pcs_get_from_pcsspec(struct fwnode_reference_args *pcsspec) ++{ ++ struct fwnode_pcs_provider *provider; ++ struct phylink_pcs *pcs = ERR_PTR(-EPROBE_DEFER); ++ ++ if (!pcsspec) ++ return ERR_PTR(-EINVAL); ++ ++ mutex_lock(&fwnode_pcs_mutex); ++ list_for_each_entry(provider, &fwnode_pcs_providers, link) { ++ if (provider->fwnode == pcsspec->fwnode) { ++ pcs = provider->get(pcsspec, provider->data); ++ if (!IS_ERR(pcs)) ++ break; ++ } ++ } ++ mutex_unlock(&fwnode_pcs_mutex); ++ ++ return pcs; ++} ++ ++static struct phylink_pcs *__fwnode_pcs_get(struct fwnode_handle *fwnode, ++ int index, const char *con_id) ++{ ++ struct fwnode_reference_args pcsspec; ++ struct phylink_pcs *pcs; ++ int ret; ++ ++ ret = fwnode_parse_pcsspec(fwnode, index, con_id, &pcsspec); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ pcs = fwnode_pcs_get_from_pcsspec(&pcsspec); ++ fwnode_handle_put(pcsspec.fwnode); ++ ++ return pcs; ++} ++ ++struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, int index) ++{ ++ return __fwnode_pcs_get(fwnode, index, NULL); ++} ++EXPORT_SYMBOL_GPL(fwnode_pcs_get); ++ ++static int fwnode_phylink_pcs_count(struct fwnode_handle *fwnode, ++ unsigned int *num_pcs) ++{ ++ struct fwnode_reference_args out_args; ++ int index = 0; ++ int ret; ++ ++ while (true) { ++ ret = fwnode_property_get_reference_args(fwnode, "pcs-handle", ++ "#pcs-cells", ++ -1, index, &out_args); ++ /* We expect to reach an -ENOENT error while counting */ ++ if (ret) ++ break; ++ ++ fwnode_handle_put(out_args.fwnode); ++ index++; ++ } ++ ++ /* Update num_pcs with parsed PCS */ ++ *num_pcs = index; ++ ++ /* Return error if we didn't found any PCS */ ++ return index > 0 ? 0 : -ENOENT; ++} ++ ++int fwnode_phylink_pcs_parse(struct fwnode_handle *fwnode, ++ struct phylink_pcs **available_pcs, ++ unsigned int *num_pcs) ++{ ++ int i; ++ ++ if (!fwnode_property_present(fwnode, "pcs-handle")) ++ return -ENODEV; ++ ++ /* With available_pcs NULL, only count the PCS */ ++ if (!available_pcs) ++ return fwnode_phylink_pcs_count(fwnode, num_pcs); ++ ++ for (i = 0; i < *num_pcs; i++) { ++ struct phylink_pcs *pcs; ++ ++ pcs = fwnode_pcs_get(fwnode, i); ++ if (IS_ERR(pcs)) ++ return PTR_ERR(pcs); ++ ++ available_pcs[i] = pcs; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(fwnode_phylink_pcs_parse); +diff --git a/include/linux/pcs/pcs-provider.h b/include/linux/pcs/pcs-provider.h +new file mode 100644 +index 000000000000..2fcc1d696c97 +--- /dev/null ++++ b/include/linux/pcs/pcs-provider.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++#ifndef __LINUX_PCS_PROVIDER_H ++#define __LINUX_PCS_PROVIDER_H ++ ++/** ++ * fwnode_pcs_simple_get - Simple xlate function to retrieve PCS ++ * @pcsspec: reference arguments ++ * @data: Context data (assumed assigned to the single PCS) ++ * ++ * Returns the PCS. (pointed by data) ++ */ ++struct phylink_pcs *fwnode_pcs_simple_get(struct fwnode_reference_args *pcsspec, ++ void *data); ++ ++/** ++ * fwnode_pcs_add_provider - Registers a new PCS provider ++ * @np: Firmware node ++ * @get: xlate function to retrieve the PCS ++ * @data: Context data ++ * ++ * Register and add a new PCS to the global providers list ++ * for the firmware node. A function to get the PCS from ++ * firmware node with the use fwnode reference arguments. ++ * To the get function is also passed the interface type ++ * requested for the PHY. PCS driver will use the passed ++ * interface to understand if the PCS can support it or not. ++ * ++ * Returns 0 on success or -ENOMEM on allocation failure. ++ */ ++int fwnode_pcs_add_provider(struct fwnode_handle *fwnode, ++ struct phylink_pcs *(*get)(struct fwnode_reference_args *pcsspec, ++ void *data), ++ void *data); ++ ++/** ++ * fwnode_pcs_del_provider - Removes a PCS provider ++ * @fwnode: Firmware node ++ */ ++void fwnode_pcs_del_provider(struct fwnode_handle *fwnode); ++ ++#endif /* __LINUX_PCS_PROVIDER_H */ +diff --git a/include/linux/pcs/pcs.h b/include/linux/pcs/pcs.h +new file mode 100644 +index 000000000000..c7a4d63bcd6d +--- /dev/null ++++ b/include/linux/pcs/pcs.h +@@ -0,0 +1,56 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++#ifndef __LINUX_PCS_H ++#define __LINUX_PCS_H ++ ++#include ++ ++#if IS_ENABLED(CONFIG_FWNODE_PCS) ++/** ++ * fwnode_pcs_get - Retrieves a PCS from a firmware node ++ * @fwnode: firmware node ++ * @index: index fwnode PCS handle in firmware node ++ * ++ * Get a PCS from the firmware node at index. ++ * ++ * Returns a pointer to the phylink_pcs or a negative ++ * error pointer. Can return -EPROBE_DEFER if the PCS is not ++ * present in global providers list (either due to driver ++ * still needs to be probed or it failed to probe/removed) ++ */ ++struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, ++ int index); ++ ++/** ++ * fwnode_phylink_pcs_parse - generic PCS parse for fwnode PCS provider ++ * @fwnode: firmware node ++ * @available_pcs: pointer to preallocated array of PCS ++ * @num_pcs: where to store count of parsed PCS ++ * ++ * Generic helper function to fill available_pcs array with PCS parsed ++ * from a "pcs-handle" fwnode property defined in firmware node up to ++ * passed num_pcs. ++ * ++ * If available_pcs is NULL, num_pcs is updated with the count of the ++ * parsed PCS. ++ * ++ * Returns 0 or a negative error. ++ */ ++int fwnode_phylink_pcs_parse(struct fwnode_handle *fwnode, ++ struct phylink_pcs **available_pcs, ++ unsigned int *num_pcs); ++#else ++static inline struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, ++ int index) ++{ ++ return ERR_PTR(-ENOENT); ++} ++ ++static inline int fwnode_phylink_pcs_parse(struct fwnode_handle *fwnode, ++ struct phylink_pcs **available_pcs, ++ unsigned int *num_pcs) ++{ ++ return -EOPNOTSUPP; ++} ++#endif ++ ++#endif /* __LINUX_PCS_H */ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0057-net-phylink-support-late-PCS-provider-attach.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0057-net-phylink-support-late-PCS-provider-attach.patch new file mode 100644 index 000000000..69610599a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0057-net-phylink-support-late-PCS-provider-attach.patch @@ -0,0 +1,263 @@ +From eb72f36586bb4c7f52180d6c3158e5a33de99c7f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:14:00 +0200 +Subject: [PATCH 57/84] net: phylink: support late PCS provider attach + +Add support in phylink for late PCS provider attach to a phylink +instance. This works by creating a global notifier for the PCS provider +and making each phylink instance that makes use of fwnode subscribe to +this notifier. + +The PCS notifier will emit the event FWNODE_PCS_PROVIDER_ADD every time +a new PCS provider is added. + +phylink will then react to this event and will call the new function +fwnode_phylink_pcs_get_from_fwnode() that will check if the PCS fwnode +provided by the event is present in the phy-handle property of the +phylink instance. + +If a related PCS is found, then such PCS is added to the phylink +instance PCS list. + +Then we link the PCS to the phylink instance if it's not disable and we +refresh the supported interfaces of the phylink instance. + +Finally we check if we are in a major_config_failed scenario and trigger +an interface reconfiguration in the next phylink resolve. + +If link was previously torn down due to removal of PCS, the link will be +established again as the PCS came back and is not available to phylink. + +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/pcs.c | 34 +++++++++++++++++++++++++ + drivers/net/phy/phylink.c | 52 +++++++++++++++++++++++++++++++++++++++ + include/linux/pcs/pcs.h | 48 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 134 insertions(+) + +diff --git a/drivers/net/pcs/pcs.c b/drivers/net/pcs/pcs.c +index 14a5cd3eeda1..a7352effa92f 100644 +--- a/drivers/net/pcs/pcs.c ++++ b/drivers/net/pcs/pcs.c +@@ -22,6 +22,13 @@ struct fwnode_pcs_provider { + + static LIST_HEAD(fwnode_pcs_providers); + static DEFINE_MUTEX(fwnode_pcs_mutex); ++static BLOCKING_NOTIFIER_HEAD(fwnode_pcs_notify_list); ++ ++int register_fwnode_pcs_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&fwnode_pcs_notify_list, nb); ++} ++EXPORT_SYMBOL_GPL(register_fwnode_pcs_notifier); + + struct phylink_pcs *fwnode_pcs_simple_get(struct fwnode_reference_args *pcsspec, + void *data) +@@ -55,6 +62,10 @@ int fwnode_pcs_add_provider(struct fwnode_handle *fwnode, + + fwnode_dev_initialized(fwnode, true); + ++ blocking_notifier_call_chain(&fwnode_pcs_notify_list, ++ FWNODE_PCS_PROVIDER_ADD, ++ fwnode); ++ + return 0; + } + EXPORT_SYMBOL_GPL(fwnode_pcs_add_provider); +@@ -147,6 +158,29 @@ struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, int index) + } + EXPORT_SYMBOL_GPL(fwnode_pcs_get); + ++struct phylink_pcs * ++fwnode_phylink_pcs_get_from_fwnode(struct fwnode_handle *fwnode, ++ struct fwnode_handle *pcs_fwnode) ++{ ++ struct fwnode_reference_args pcsspec; ++ int i = 0; ++ int ret; ++ ++ while (true) { ++ ret = fwnode_parse_pcsspec(fwnode, i, NULL, &pcsspec); ++ if (ret) ++ break; ++ ++ if (pcsspec.fwnode == pcs_fwnode) ++ break; ++ ++ i++; ++ } ++ ++ return fwnode_pcs_get(fwnode, i); ++} ++EXPORT_SYMBOL_GPL(fwnode_phylink_pcs_get_from_fwnode); ++ + static int fwnode_phylink_pcs_count(struct fwnode_handle *fwnode, + unsigned int *num_pcs) + { +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index ef393e49a314..409a5dbb1cfc 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -61,6 +62,7 @@ struct phylink { + + /* List of available PCS */ + struct list_head pcs_list; ++ struct notifier_block fwnode_pcs_nb; + + /* What interface are supported by the current link. + * Can change on removal or addition of new PCS. +@@ -1924,6 +1926,51 @@ int phylink_set_fixed_link(struct phylink *pl, + } + EXPORT_SYMBOL_GPL(phylink_set_fixed_link); + ++static int pcs_provider_notify(struct notifier_block *self, ++ unsigned long val, void *data) ++{ ++ struct phylink *pl = container_of(self, struct phylink, fwnode_pcs_nb); ++ struct fwnode_handle *pcs_fwnode = data; ++ struct phylink_pcs *pcs; ++ ++ /* Check if the just added PCS provider is ++ * in the phylink instance phy-handle property ++ */ ++ pcs = fwnode_phylink_pcs_get_from_fwnode(dev_fwnode(pl->config->dev), ++ pcs_fwnode); ++ if (IS_ERR(pcs)) ++ return NOTIFY_DONE; ++ ++ /* Add the PCS */ ++ rtnl_lock(); ++ ++ list_add(&pcs->list, &pl->pcs_list); ++ ++ /* Link phylink if we are started */ ++ if (!pl->phylink_disable_state) ++ pcs->phylink = pl; ++ ++ /* Refresh supported interfaces */ ++ phy_interface_copy(pl->supported_interfaces, ++ pl->config->supported_interfaces); ++ list_for_each_entry(pcs, &pl->pcs_list, list) ++ phy_interface_or(pl->supported_interfaces, ++ pl->supported_interfaces, ++ pcs->supported_interfaces); ++ ++ mutex_lock(&pl->state_mutex); ++ /* Force an interface reconfig if major config fail */ ++ if (pl->major_config_failed) ++ pl->reconfig_interface = true; ++ mutex_unlock(&pl->state_mutex); ++ ++ rtnl_unlock(); ++ ++ phylink_run_resolve(pl); ++ ++ return NOTIFY_OK; ++} ++ + /** + * phylink_create() - create a phylink instance + * @config: a pointer to the target &struct phylink_config +@@ -1979,6 +2026,11 @@ struct phylink *phylink_create(struct phylink_config *config, + pl->supported_interfaces, + pcs->supported_interfaces); + ++ if (!phy_interface_empty(config->pcs_interfaces)) { ++ pl->fwnode_pcs_nb.notifier_call = pcs_provider_notify; ++ register_fwnode_pcs_notifier(&pl->fwnode_pcs_nb); ++ } ++ + pl->config = config; + if (config->type == PHYLINK_NETDEV) { + pl->netdev = to_net_dev(config->dev); +diff --git a/include/linux/pcs/pcs.h b/include/linux/pcs/pcs.h +index c7a4d63bcd6d..480c155a3f03 100644 +--- a/include/linux/pcs/pcs.h ++++ b/include/linux/pcs/pcs.h +@@ -4,7 +4,24 @@ + + #include + ++enum fwnode_pcs_notify_event { ++ FWNODE_PCS_PROVIDER_ADD, ++}; ++ + #if IS_ENABLED(CONFIG_FWNODE_PCS) ++/** ++ * register_fwnode_pcs_notifier - Register a notifier block for fwnode ++ * PCS events ++ * @nb: pointer to the notifier block ++ * ++ * Registers a notifier block to the fwnode_pcs_notify_list blocking ++ * notifier chain. This allows phylink instance to subscribe for ++ * PCS provider events. ++ * ++ * Returns 0 or a negative error. ++ */ ++int register_fwnode_pcs_notifier(struct notifier_block *nb); ++ + /** + * fwnode_pcs_get - Retrieves a PCS from a firmware node + * @fwnode: firmware node +@@ -20,6 +37,25 @@ + struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, + int index); + ++/** ++ * fwnode_phylink_pcs_get_from_fwnode - Retrieves the PCS provided ++ * by the firmware node from a ++ * firmware node ++ * @fwnode: firmware node ++ * @pcs_fwnode: PCS firmware node ++ * ++ * Parse 'pcs-handle' in 'fwnode' and get the PCS that match ++ * 'pcs_fwnode' firmware node. ++ * ++ * Returns a pointer to the phylink_pcs or a negative ++ * error pointer. Can return -EPROBE_DEFER if the PCS is not ++ * present in global providers list (either due to driver ++ * still needs to be probed or it failed to probe/removed) ++ */ ++struct phylink_pcs * ++fwnode_phylink_pcs_get_from_fwnode(struct fwnode_handle *fwnode, ++ struct fwnode_handle *pcs_fwnode); ++ + /** + * fwnode_phylink_pcs_parse - generic PCS parse for fwnode PCS provider + * @fwnode: firmware node +@@ -39,12 +75,24 @@ int fwnode_phylink_pcs_parse(struct fwnode_handle *fwnode, + struct phylink_pcs **available_pcs, + unsigned int *num_pcs); + #else ++static int register_fwnode_pcs_notifier(struct notifier_block *nb) ++{ ++ return -EOPNOTSUPP; ++} ++ + static inline struct phylink_pcs *fwnode_pcs_get(struct fwnode_handle *fwnode, + int index) + { + return ERR_PTR(-ENOENT); + } + ++static struct phylink_pcs * ++fwnode_phylink_pcs_get_from_fwnode(struct fwnode_handle *fwnode, ++ struct fwnode_handle *pcs_fwnode) ++{ ++ return ERR_PTR(-ENOENT); ++} ++ + static inline int fwnode_phylink_pcs_parse(struct fwnode_handle *fwnode, + struct phylink_pcs **available_pcs, + unsigned int *num_pcs) +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0058-dt-bindings-net-ethernet-controller-permit-to-define.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0058-dt-bindings-net-ethernet-controller-permit-to-define.patch new file mode 100644 index 000000000..124dfd718 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0058-dt-bindings-net-ethernet-controller-permit-to-define.patch @@ -0,0 +1,34 @@ +From 2f5f92f20fe06d54b826a446be6504063207f82b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:14:01 +0200 +Subject: [PATCH 58/84] dt-bindings: net: ethernet-controller: permit to define + multiple PCS + +Drop the limitation of a single PCS in pcs-handle property. Multiple PCS +can be defined for an ethrnet-controller node to support various PHY +interface mode type. + +It's very common for SoCs to have a dedicated PCS for SGMII mode and one +for USXGMII mode. + +Signed-off-by: Christian Marangi +--- + Documentation/devicetree/bindings/net/ethernet-controller.yaml | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml +index 7cbf11bbe99c..60605b34d242 100644 +--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml ++++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml +@@ -84,8 +84,6 @@ properties: + + pcs-handle: + $ref: /schemas/types.yaml#/definitions/phandle-array +- items: +- maxItems: 1 + description: + Specifies a reference to a node representing a PCS PHY device on a MDIO + bus to link with an external PHY (phy-handle) if exists. +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0059-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0059-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch new file mode 100644 index 000000000..8c696e7f2 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0059-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch @@ -0,0 +1,2938 @@ +From 0b4dee7b6010c4b2c45ade25a2063cc5e7e3e631 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:14:02 +0200 +Subject: [PATCH 59/84] net: pcs: airoha: add PCS driver for Airoha SoC + +Add PCS driver for Airoha SoC for Ethernet Serdes and PCS and permit +usage of external PHY or connected SFP cage. Supported modes are +USXGMII, 10-BASER, 2500BASE-X, 1000BASE-X and SGMII. + +The driver register as a PCS provider and supports poll mode to detect +PCS port state. While interrupt is supported by the HW, there are some +defect with the interrupt not fired on cable detach. + +The PCS require complex calibration to correctly work and might require +multiple try until the signal detection module "lock" on the signal +level to correct work with the attached PHY. + +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/Kconfig | 7 + + drivers/net/pcs/Makefile | 1 + + drivers/net/pcs/pcs-airoha.c | 2855 ++++++++++++++++++++++++++++++++ + include/linux/pcs/pcs-airoha.h | 11 + + 4 files changed, 2874 insertions(+) + create mode 100644 drivers/net/pcs/pcs-airoha.c + create mode 100644 include/linux/pcs/pcs-airoha.h + +diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig +index 2951aa2f4cda..69d28cd1e624 100644 +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -12,6 +12,13 @@ config FWNODE_PCS + help + Firmware node PCS accessors + ++config PCS_AIROHA ++ select FWNODE_PCS ++ tristate "Airoha PCS driver" ++ help ++ This module provides helper to phylink for managing the Airoha ++ PCS for SoC Ethernet Serdes and PCS. ++ + config PCS_XPCS + tristate "Synopsys DesignWare Ethernet XPCS" + select PHYLINK +diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile +index 3005cdd89ab7..c48450f08fb7 100644 +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -2,6 +2,7 @@ + # Makefile for Linux PCS drivers + + obj-$(CONFIG_FWNODE_PCS) += pcs.o ++obj-$(CONFIG_PCS_AIROHA) += pcs-airoha.o + pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ + pcs-xpcs-nxp.o pcs-xpcs-wx.o + +diff --git a/drivers/net/pcs/pcs-airoha.c b/drivers/net/pcs/pcs-airoha.c +new file mode 100644 +index 000000000000..945b959a4e26 +--- /dev/null ++++ b/drivers/net/pcs/pcs-airoha.c +@@ -0,0 +1,2855 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SCU*/ ++#define AIROHA_SCU_WAN_CONF 0x70 ++#define AIROHA_SCU_WAN_SEL GENMASK(7, 0) ++#define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10) ++#define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11) ++#define AIROHA_SCU_WAN_SEL_USXGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x12) ++#define AIROHA_SCU_SSR3 0x94 ++#define AIROHA_SCU_ETH_XSI_SEL GENMASK(14, 13) ++#define AIROHA_SCU_ETH_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x1) ++#define AIROHA_SCU_ETH_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x2) ++#define AIROHA_SCU_SSTR 0x9c ++#define AIROHA_SCU_PON_XSI_SEL GENMASK(10, 9) ++#define AIROHA_SCU_PON_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x1) ++#define AIROHA_SCU_PON_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x2) ++ ++/* HSGMII_AN */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0 0x0 ++#define AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE BIT(12) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART BIT(9) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1 0x4 /* BMSR */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_UNIDIR_ABILITY BIT(6) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE BIT(5) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT BIT(4) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY BIT(3) ++#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS BIT(2) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4 0x10 ++#define AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5 0x14 /* LPA */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11 0x2c ++#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER GENMASK(19, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13 0x34 ++#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS BIT(8) ++#define AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0 GENMASK(5, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN BIT(5) ++#define AIROHA_PCS_HSGMII_AN_DUPLEX_FORCE_MODE BIT(4) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE GENMASK(3, 2) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_AN_SIDEBAND_EN BIT(1) ++#define AIROHA_PCS_HSGMII_AN_SGMII_EN BIT(0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37 0x60 ++#define AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE BIT(0) ++ ++/* HSGMII_PCS */ ++#define AIROHA_PCS_HSGMII_PCS_CTROL_1 0x0 ++#define AIROHA_PCS_TBI_10B_MODE BIT(30) ++#define AIROHA_PCS_SGMII_SEND_AN_ERR_EN BIT(24) ++#define AIROHA_PCS_REMOTE_FAULT_DIS BIT(12) ++#define AIROHA_PCS_HSGMII_PCS_CTROL_3 0x8 ++#define AIROHA_PCS_HSGMII_PCS_LINK_STSTIME GENMASK(19, 0) ++#define AIROHA_PCS_HSGMII_PCS_CTROL_6 0x14 ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 BIT(14) ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 BIT(13) ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 BIT(12) ++#define AIROHA_PCS_HSGMII_PCS_MAC_MODE BIT(8) ++#define AIROHA_PCS_HSGMII_PCS_TX_ENABLE BIT(4) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL GENMASK(3, 2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x0) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x1) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT BIT(1) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_EN BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT 0x20 ++#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR BIT(11) ++#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT BIT(10) ++#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR BIT(9) ++#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT BIT(8) ++#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR BIT(5) ++#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT BIT(4) ++#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR BIT(3) ++#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR BIT(2) ++#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT BIT(1) ++#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE 0x24 ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE GENMASK(5, 4) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL BIT(0) ++#define ARIOHA_PCS_HSGMII_PCS_STATE_2 0x104 ++#define AIROHA_PCS_HSGMII_PCS_RX_SYNC BIT(5) ++#define AIROHA_PCS_HSGMII_PCS_AN_DONE BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_INT_STATE 0x15c ++#define AIROHA_PCS_HSGMII_PCS_MODE2_REMOTE_FAULT_OCCUR_INT BIT(4) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_MLS BIT(3) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_CL37_TIMERDONE_INT BIT(2) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_RX_SYNC BIT(1) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_DONE BIT(0) ++ ++/* MULTI_SGMII */ ++#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_EN_0 0x14 ++#define AIROHA_PCS_MULTI_SGMII_PCS_INT_EN_0 BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0 0x18 ++#define AIROHA_PCS_LINK_MODE_P0 GENMASK(5, 4) ++#define AIROHA_PCS_LINK_MODE_P0_2_5G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x3) ++#define AIROHA_PCS_LINK_MODE_P0_1G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x2) ++#define AIROHA_PCS_LINK_MODE_P0_100M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x1) ++#define AIROHA_PCS_LINK_MODE_P0_10M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x0) ++#define AIROHA_PCS_FORCE_SPD_MODE_P0 BIT(2) ++#define AIROHA_PCS_FORCE_LINKDOWN_P0 BIT(1) ++#define AIROHA_PCS_FORCE_LINKUP_P0 BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0 0x100 ++#define AIROHA_PCS_HSGMII_XFI_SEL BIT(28) ++#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_SEL 0x14c ++#define AIROHA_PCS_HSGMII_PCS_INT BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_15 0x43c ++#define AIROHA_PCS_LINK_STS_P0 BIT(3) ++#define AIROHA_PCS_SPEED_STS_P0 GENMASK(2, 0) ++#define AIROHA_PCS_SPEED_STS_P0_1G FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x2) ++#define AIROHA_PCS_SPEED_STS_P0_100M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x1) ++#define AIROHA_PCS_SPEED_STS_P0_10M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_18 0x448 ++#define AIROHA_PCS_P0_SGMII_IS_10 BIT(2) ++#define AIROHA_PCS_P0_SGMII_IS_100 BIT(1) ++#define AIROHA_PCS_P0_SGMII_IS_1000 BIT(0) ++ ++/* HSGMII_RATE_ADP */ ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0 0x0 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS BIT(27) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS BIT(26) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN BIT(4) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN BIT(0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1 0x4 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR GENMASK(20, 16) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR GENMASK(28, 24) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6 0x18 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L GENMASK(31, 0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8 0x20 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C GENMASK(7, 0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11 0x2c ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN BIT(8) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE GENMASK(15, 12) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x4) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x6) ++#define AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0 0x100 ++#define AIROHA_PCS_HSGMII_P0_DIS_MII_MODE BIT(31) ++ ++/* USXGMII */ ++#define AIROHA_PCS_USXGMII_PCS_CTROL_1 0x0 ++#define AIROHA_PCS_USXGMII_SPEED_SEL_H BIT(13) ++#define AIROHA_PCS_USXGMII_PCS_STUS_1 0x30 ++#define AIROHA_PCS_USXGMII_RX_LINK_STUS BIT(12) ++#define AIROHA_PCS_USXGMII_PRBS9_PATT_TST_ABILITY BIT(3) ++#define AIROHA_PCS_USXGMII_PRBS31_PATT_TST_ABILITY BIT(2) ++#define AIROHA_PCS_USXGMII_PCS_BLK_LK BIT(0) ++#define AIROHA_PCS_USGMII_VENDOR_DEFINE_116 0x22c ++#define AIROHA_PCS_USXGMII_PCS_CTRL_0 0x2c0 ++#define AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_1 0x2c4 ++#define AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_2 0x2c8 ++#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_3 0x2cc ++#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_2 0x2d8 ++#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_E_INT BIT(16) ++#define AIROHA_PCS_USXGMII_R_TYPE_T_INT BIT(8) ++#define AIROHA_PCS_USXGMII_R_TYPE_D_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_3 0x2dc ++#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT BIT(24) ++#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT BIT(16) ++#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT BIT(8) ++#define AIROHA_PCS_USXGMII_HI_BER_ST_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_4 0x2e0 ++#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_4 0x2e4 ++#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0 0x2f8 ++#define AIROHA_PCS_USXGMII_AN_RESTART BIT(8) ++#define AIROHA_PCS_USXGMII_AN_ENABLE BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_STATS_0 0x310 ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE GENMASK(30, 28) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x0) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x1) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x2) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_1G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x3) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_100M FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x4) ++#define AIROHA_PCS_USXGMII_PARTNER_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_USXGMII_PCS_AN_STATS_2 0x318 ++#define AIROHA_PCS_USXGMII_PCS_AN_COMPLETE BIT(24) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c ++#define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320 ++#define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12) ++#define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8) ++#define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x0) ++#define AIROHA_PCS_USXGMII_MODE_5000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x1) ++#define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x2) ++#define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x3) ++#define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x4) ++ ++/* PMA_PHYA */ ++#define AIROHA_PCS_ANA_PXP_CMN_EN 0x0 ++#define AIROHA_PCS_ANA_CMN_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4 ++#define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24) ++#define AIROHA_PCS_ANA_JCPLL_CHP_IBIAS GENMASK(21, 16) ++#define AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN BIT(8) ++#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR 0x8 ++#define AIROHA_PCS_ANA_JCPLL_LPF_BWR GENMASK(28, 24) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BP GENMASK(20, 16) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BC GENMASK(12, 8) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BR GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC 0xc ++#define AIROHA_PCS_ANA_JCPLL_KBAND_DIV GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_CODE GENMASK(23, 16) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_OPTION BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BWC GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC 0x10 ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KS GENMASK(17, 16) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KF GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KFC GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE 0x14 ++#define AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 BIT(24) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x3) ++#define AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY 0x1c ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS GENMASK(25, 24) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_PLL_RSTB BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY GENMASK(2, 0) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_20_25 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_40_50 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_80_100 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_300_400 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x5) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_600_800 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x6) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM 0x20 ++#define AIROHA_PCS_ANA_JCPLL_SDM_OUT BIT(24) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD GENMASK(17, 16) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_SDM_MODE GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_SDM_IFM BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN 0x24 ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF GENMASK(28, 24) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_10 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_SDM_HREN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN 0x28 ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x6) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24) ++#define AIROHA_PCS_ANA_PXP_JCPLL_VCODIV 0x2c ++#define AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_VCO_CFIX GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV GENMASK(1, 0) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x1) ++#define AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR 0x30 ++#define AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI BIT(17) ++#define AIROHA_PCS_ANA_JCPLL_SSC_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(10, 8) ++#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(5, 3) ++#define AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR GENMASK(2, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN 0x34 ++#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 GENMASK(23, 8) ++#define AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA 0x38 ++#define AIROHA_PCS_ANA_JCPLL_SSC_PERIOD GENMASK(31, 16) ++#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H 0x48 ++#define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16) ++#define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8) ++#define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5)) ++#define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50 ++#define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16) ++#define AIROHA_PCS_ANA_TXPLL_CHP_IOFST GENMASK(13, 8) ++#define AIROHA_PCS_ANA_TXPLL_CHP_IBIAS GENMASK(5, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP 0x54 ++#define AIROHA_PCS_ANA_TXPLL_KBAND_OPTION BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BWC GENMASK(20, 16) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BWR GENMASK(12, 8) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BP GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE 0x58 ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KF GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KFC GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_DIV GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_CODE GENMASK(7, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS 0x5c ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64 ++#define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV GENMASK(9, 8) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN 0x68 ++#define AIROHA_PCS_ANA_TXPLL_SDM_MODE GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_SDM_IFM BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS GENMASK(9, 8) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD 0x6c ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_SDM_HREN BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SDM_OUT BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD GENMASK(1, 0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x3) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN 0x70 ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF GENMASK(12, 8) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN GENMASK(2, 0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x4) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN 0x74 ++#define AIROHA_PCS_ANA_TXPLL_VCO_CFIX GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x4) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x6) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN 0x78 ++#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(29, 27) ++#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(26, 24) ++#define AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR GENMASK(18, 16) ++#define AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN 0x7c ++#define AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_SSC_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1 0x80 ++#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA GENMASK(31, 16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA1 GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD 0x84 ++#define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94 ++#define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4 ++#define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24) ++#define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24) ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) /* 0: from PR 1: from DES */ ++#define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4 ++#define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16) ++#define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) ++#define AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) ++#define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) ++#define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18) ++#define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16) ++#define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8 ++#define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24) ++#define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16) ++#define AIROHA_PCS_ANA_RX_PHYCK_SEL GENMASK(9, 8) ++#define AIROHA_PCS_ANA_RX_PHYCK_DIV GENMASK(7, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc ++#define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8) ++#define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0) ++#define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8 ++#define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8) ++#define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE 0xf4 ++#define AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF BIT(24) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC 0xf8 ++#define AIROHA_PCS_ANA_CDR_PR_KBAND_DIV GENMASK(26, 24) ++#define AIROHA_PCS_ANA_CDR_PR_BETA_SEL GENMASK(19, 16) ++#define AIROHA_PCS_ANA_CDR_PR_VCOADC_OS GENMASK(11, 8) ++#define AIROHA_PCS_ANA_CDR_PR_BETA_DAC GENMASK(6, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL 0xfc ++#define AIROHA_PCS_ANA_CDR_PR_FBKSEL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND GENMASK(20, 16) ++#define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8) ++#define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c ++#define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24) ++#define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19) ++#define AIROHA_PCS_ANA_CDR_BUF_IN_SR GENMASK(18, 16) ++#define AIROHA_PCS_ANA_CDR_PR_XFICK_EN BIT(2) ++#define AIROHA_PCS_ANA_CDR_PR_MONDPI_EN BIT(1) ++#define AIROHA_PCS_ANA_CDR_PR_MONDPR_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110 ++#define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114 ++#define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16) ++#define AIROHA_PCS_ANA_RX_SIGDET_PEAK GENMASK(9, 8) ++#define AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN 0x118 ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN BIT(24) ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN BIT(16) ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN BIT(8) ++#define AIROHA_PCS_ANA_RX_FE_EQ_HZEN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB 0x11c ++#define AIROHA_PCS_ANA_FE_VCM_GEN_PWDB BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW 0x120 ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE GENMASK(17, 8) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(0)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(1)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(2)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(3)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(4)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(5)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(6)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(7)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(8)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(9)) ++#define AIROHA_PCS_ANA_PXP_AEQ_CFORCE 0x13c ++#define AIROHA_PCS_ANA_AEQ_OFORCE GENMASK(19, 8) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_SAOS FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(0)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP1 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(1)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP2 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(2)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP3 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(3)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP4 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(4)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP5 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(5)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP6 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(6)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP7 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(7)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_VGA FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(8)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_CTLE FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(9)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_ATT FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(10)) ++#define AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB 0x144 ++#define AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ BIT(24) ++#define AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ 0x148 ++#define AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ BIT(24) ++#define AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ BIT(16) ++#define AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ BIT(8) ++#define AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ BIT(0) ++ ++/* PMA_PHYD */ ++#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0 ++#define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4 ++#define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88 ++#define AIROHA_PCS_PMA_DATA_SHIFT BIT(8) ++#define AIROHA_PCS_PMA_EYECNT_FAST BIT(0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0 0x8c ++#define AIROHA_PCS_PMA_RX_OS_START GENMASK(23, 8) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT GENMASK(2, 0) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_05 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x0) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x1) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x2) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x3) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x4) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_1_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x5) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_3_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x6) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_6_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x7) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1 0x90 ++#define AIROHA_PCS_PMA_RX_PICAL_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_PICAL_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2 0x94 ++#define AIROHA_PCS_PMA_RX_PDOS_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_PDOS_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3 0x98 ++#define AIROHA_PCS_PMA_RX_FEOS_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_FEOS_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4 0x9c ++#define AIROHA_PCS_PMA_RX_SDCAL_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_SDCAL_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5 0x100 ++#define AIROHA_PCS_PMA_RX_RDY GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104 ++#define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c ++#define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114 ++#define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_3 0x120 ++#define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16) ++#define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8) ++#define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c ++#define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_2 0x150 ++#define AIROHA_PCS_PMA_LOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_LOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_3 0x154 ++#define AIROHA_PCS_PMA_UNLOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_UNLOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_4 0x158 ++#define AIROHA_PCS_PMA_LOCK_UNLOCKTH GENMASK(15, 12) ++#define AIROHA_PCS_PMA_LOCK_LOCKTH GENMASK(11, 8) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN GENMASK(2, 0) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x0) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x1) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7) ++#define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c ++#define AIROHA_PCS_PMA_SIGDET_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_FLL_1 0x174 ++#define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_FLL_2 0x178 ++#define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16) ++#define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0) ++#define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1) ++#define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2) ++#define AIROHA_PCS_PMA_RX_FLL_5 0x184 ++#define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16) ++#define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_FLL_B 0x19c ++#define AIROHA_PCS_PMA_LOAD_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_RESET_1 0x208 ++#define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8) ++#define AIROHA_PCS_PMA_TX_RST_B 0x260 ++#define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8) ++#define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320 ++#define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330 ++#define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c ++#define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_RX_SYS_EN_SEL_0 0x38c ++#define AIROHA_PCS_PMA_RX_SYS_EN_SEL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_0 0x390 ++#define AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_1 0x394 ++#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c ++#define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8) ++#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c ++#define AIROHA_PCS_PMA_DISB_LEQ BIT(0) ++#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c ++#define AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB BIT(24) ++#define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16) ++#define AIROHA_PCS_PMA_XPON_CDR_PW_PWDB BIT(8) ++#define AIROHA_PCS_PMA_XPON_RX_FE_PWDB BIT(0) ++#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1 0x350 ++#define AIROHA_PCS_PMA_RX_SIDGET_PWDB BIT(0) ++#define AIROHA_PCS_PMA_DIG_RESERVE_0 0x360 ++#define AIROHA_PCS_PMA_DIG_RO_RESERVE_2 0x380 ++#define AIROHA_PCS_PMA_XPON_RX_RESERVED_1 0x374 ++#define AIROHA_PCS_PMA_XPON_RX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_SW_RST_SET 0x460 ++#define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11) ++#define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10) ++#define AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N BIT(9) ++#define AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N BIT(8) ++#define AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N BIT(7) ++#define AIROHA_PCS_PMA_SW_TX_FIFO_RST_N BIT(6) ++#define AIROHA_PCS_PMA_SW_REF_RST_N BIT(5) ++#define AIROHA_PCS_PMA_SW_ALLPCS_RST_N BIT(4) ++#define AIROHA_PCS_PMA_SW_PMA_RST_N BIT(3) ++#define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2) ++#define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1) ++#define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0) ++#define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474 ++#define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16) ++#define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c ++#define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16) ++#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c ++#define AIROHA_PCS_PMA_DISB_LEQ BIT(0) ++#define AIROHA_PCS_PMA_RX_FREQDET 0x530 ++#define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580 ++#define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PEAKING_CTRL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL GENMASK(19, 16) ++#define AIROHA_PCS_PMA_PXP_AEQ_SPEED 0x76c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_OSR_SEL GENMASK(17, 16) ++#define AIROHA_PCS_PMA_PXP_TX_FIR_C0B 0x778 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 GENMASK(20, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_TX_TERM_SEL 0x77c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR GENMASK(19, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL GENMASK(2, 0) ++#define AIROHA_PCS_PMA_PXP_TX_FIR_C1 0x780 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 GENMASK(20, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16) ++#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC GENMASK(10, 0) ++#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR GENMASK(10, 8) ++#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW 0x798 ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW GENMASK(30, 0) ++#define AIROHA_PCS_PMA_PXP_RX_FE_VOS 0x79c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_FE_VOS GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW 0x800 ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW GENMASK(30, 0) ++#define AIROHA_PCS_PMA_PXP_AEQ_BYPASS 0x80c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON BIT(16) ++#define AIROHA_PCS_PMA_PXP_AEQ_RSTB 0x814 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL BIT(16) ++#define AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA 0x818 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PD_PWDB 0x81c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN 0x820 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB 0x824 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB BIT(0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN 0x828 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B BIT(0) ++#define AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN 0x854 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16) ++#define AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL 0x88c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_RX_FE_PWDB 0x894 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0) ++ ++#define AIROHA_PCS_MAX_CALIBRATION_TRY 50 ++#define AIROHA_PCS_MAX_NUM_RSTS 2 ++ ++enum xfi_port_type { ++ AIROHA_PCS_ETH, ++ AIROHA_PCS_PON, ++}; ++ ++struct airoha_pcs_match_data { ++ enum xfi_port_type port_type; ++}; ++ ++struct airoha_pcs_priv { ++ struct device *dev; ++ const struct airoha_pcs_match_data *data; ++ phy_interface_t interface; ++ ++ struct regmap *scu; ++ ++ struct regmap *xfi_mac; ++ struct regmap *hsgmii_an; ++ struct regmap *hsgmii_pcs; ++ struct regmap *hsgmii_rate_adp; ++ struct regmap *multi_sgmii; ++ struct regmap *usxgmii_pcs; ++ ++ struct regmap *xfi_pma; ++ struct regmap *xfi_ana; ++ ++ struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; ++ ++ struct phylink_pcs pcs; ++}; ++ ++static struct airoha_pcs_priv *phylink_pcs_to_airoha_pcs_port(struct phylink_pcs *pcs) ++{ ++ return container_of(pcs, struct airoha_pcs_priv, pcs); ++} ++ ++static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 xsi_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ xsi_sel = AIROHA_SCU_ETH_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ default: ++ xsi_sel = AIROHA_SCU_ETH_XSI_USXGMII; ++ } ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_SSR3, ++ AIROHA_SCU_ETH_XSI_SEL, ++ xsi_sel); ++} ++ ++static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 xsi_sel, wan_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ wan_sel = AIROHA_SCU_WAN_SEL_SGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ wan_sel = AIROHA_SCU_WAN_SEL_HSGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ default: ++ wan_sel = AIROHA_SCU_WAN_SEL_USXGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_USXGMII; ++ } ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, ++ AIROHA_SCU_PON_XSI_SEL, ++ xsi_sel); ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF, ++ AIROHA_SCU_WAN_SEL, ++ wan_sel); ++} ++ ++static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ int ret; ++ ++ switch (priv->data->port_type) { ++ case AIROHA_PCS_ETH: ++ airoha_pcs_setup_scu_eth(priv, interface); ++ break; ++ case AIROHA_PCS_PON: ++ airoha_pcs_setup_scu_pon(priv, interface); ++ break; ++ } ++ ++ ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_bulk_deassert(ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ /* Disable Hibernation */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, ++ AIROHA_PCS_USXGMII_SPEED_SEL_H); ++ ++ /* FIXME: wait Airoha */ ++ /* Avoid PCS sending garbage to MAC in some HW revision (E0) */ ++ regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); ++} ++ ++static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_TBI_10B_MODE); ++} ++ ++static void airoha_pcs_init_sgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_TBI_10B_MODE); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, 0x07070707)); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, 0xff)); ++} ++ ++static void airoha_pcs_init(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ airoha_pcs_init_sgmii(priv); ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ airoha_pcs_init_hsgmii(priv); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ airoha_pcs_init_usxgmii(priv); ++ break; ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_interrupt_init_sgmii(struct airoha_pcs_priv *priv) ++{ ++ /* Disable every interrupt */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT); ++ ++ /* Clear interrupt */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); ++} ++ ++static void airoha_pcs_interrupt_init_usxgmii(struct airoha_pcs_priv *priv) ++{ ++ /* Disable every Interrupt */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_0, ++ AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_1, ++ AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN | ++ AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_2, ++ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_3, ++ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN | ++ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN | ++ AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN | ++ AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_4, ++ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN); ++ ++ /* Clear any pending interrupt */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_2, ++ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_E_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_T_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_D_INT); ++ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_3, ++ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT | ++ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT | ++ AIROHA_PCS_USXGMII_LINK_UP_ST_INT | ++ AIROHA_PCS_USXGMII_HI_BER_ST_INT); ++ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_4, ++ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT); ++ ++ /* Interrupt saddly seems to be not weel supported for Link Down. ++ * PCS Poll is a must to correctly read and react on Cable Deatch ++ * as only cable attach interrupt are fired and Link Down interrupt ++ * are fired only in special case like AN restart. ++ */ ++} ++ ++static void airoha_pcs_interrupt_init(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ return airoha_pcs_interrupt_init_sgmii(priv); ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ return airoha_pcs_interrupt_init_usxgmii(priv); ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_jcpll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 kband_vref; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ kband_vref = 0x10; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ kband_vref = 0xf; ++ break; ++ default: ++ return; ++ } ++ ++ /* Setup LDO */ ++ usleep_range(200, 300); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, ++ AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO); ++ ++ /* Setup RSTB */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_PLL_RSTB); ++ ++ /* Enable PLL force selection and Force Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN); ++ ++ /* Setup SDM */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_LS | ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_EN, ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, ++ AIROHA_PCS_ANA_JCPLL_SDM_OUT | ++ AIROHA_PCS_ANA_JCPLL_SDM_ORD | ++ AIROHA_PCS_ANA_JCPLL_SDM_MODE | ++ AIROHA_PCS_ANA_JCPLL_SDM_IFM, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0) | ++ AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_MODE, 0x0)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, ++ AIROHA_PCS_ANA_JCPLL_SDM_HREN); ++ ++ /* Setup SSC */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, ++ AIROHA_PCS_ANA_JCPLL_SSC_PERIOD | ++ AIROHA_PCS_ANA_JCPLL_SSC_DELTA, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_PERIOD, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, ++ AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 | ++ AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA1, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, ++ AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI | ++ AIROHA_PCS_ANA_JCPLL_SSC_EN | ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x0)); ++ ++ /* Setup LPF */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, ++ AIROHA_PCS_ANA_JCPLL_CHP_IOFST | ++ AIROHA_PCS_ANA_JCPLL_CHP_IBIAS | ++ AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IOFST, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IBIAS, 0x18)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, ++ AIROHA_PCS_ANA_JCPLL_LPF_BWR | ++ AIROHA_PCS_ANA_JCPLL_LPF_BP | ++ AIROHA_PCS_ANA_JCPLL_LPF_BC | ++ AIROHA_PCS_ANA_JCPLL_LPF_BR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWR, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BP, 0x10) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BC, 0x1f) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BR, BIT(3) | BIT(1))); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, ++ AIROHA_PCS_ANA_JCPLL_LPF_BWC, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWC, 0x0)); ++ ++ /* Setup VCO */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR | ++ AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN | ++ AIROHA_PCS_ANA_JCPLL_VCO_CFIX, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR, 0x4) | ++ AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_CFIX, 0x1)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H | ++ AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x3)); ++ ++ /* Setup PCW */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW, ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, 0x25800000)); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW); ++ ++ /* Setup DIV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, ++ AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 | ++ AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, ++ AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCODIV_1); ++ ++ /* Setup KBand */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, ++ AIROHA_PCS_ANA_JCPLL_KBAND_KS | ++ AIROHA_PCS_ANA_JCPLL_KBAND_KF | ++ AIROHA_PCS_ANA_JCPLL_KBAND_KFC, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KS, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KF, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KFC, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, ++ AIROHA_PCS_ANA_JCPLL_KBAND_DIV | ++ AIROHA_PCS_ANA_JCPLL_KBAND_CODE | ++ AIROHA_PCS_ANA_JCPLL_KBAND_OPTION, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_DIV, 0x2) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_CODE, 0xe4)); ++ ++ /* Setup TCL */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, ++ AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF, kband_vref)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF, 0x5) | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW | ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 | ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN); ++ ++ /* Enable PLL */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN); ++ ++ /* Enale PLL Output */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN | ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN); ++} ++ ++static void airoha_pcs_txpll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 lpf_chp_ibias, lpf_bp, lpf_bwr, lpf_bwc; ++ u32 vco_cfix; ++ u32 pcw; ++ u32 tcl_amp_vref; ++ bool sdm_hren; ++ bool vcodiv; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ lpf_chp_ibias = 0xf; ++ lpf_bp = BIT(1); ++ lpf_bwr = BIT(3) | BIT(1) | BIT(0); ++ lpf_bwc = BIT(4) | BIT(3); ++ vco_cfix = BIT(1) | BIT(0); ++ pcw = BIT(27); ++ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); ++ vcodiv = false; ++ sdm_hren = false; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ lpf_chp_ibias = 0xa; ++ lpf_bp = BIT(2) | BIT(0); ++ lpf_bwr = 0; ++ lpf_bwc = 0; ++ vco_cfix = 0; ++ pcw = BIT(27) | BIT(25); ++ tcl_amp_vref = BIT(3) | BIT(2) | BIT(0); ++ vcodiv = true; ++ sdm_hren = false; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ lpf_chp_ibias = 0xf; ++ lpf_bp = BIT(1); ++ lpf_bwr = BIT(3) | BIT(1) | BIT(0); ++ lpf_bwc = BIT(4) | BIT(3); ++ vco_cfix = BIT(0); ++ pcw = BIT(27) | BIT(22); ++ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); ++ vcodiv = false; ++ sdm_hren = true; ++ break; ++ default: ++ return; ++ } ++ ++ /* Setup VCO LDO Output */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT | ++ AIROHA_PCS_ANA_TXPLL_LDO_OUT, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1)); ++ ++ /* Setup RSTB */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ AIROHA_PCS_ANA_TXPLL_RST_DLY | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV | ++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 | ++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL); ++ ++ /* Enable PLL force selection and Force Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN); ++ ++ /* Setup SDM */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, ++ AIROHA_PCS_ANA_TXPLL_SDM_MODE | ++ AIROHA_PCS_ANA_TXPLL_SDM_IFM | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_SDM_HREN | ++ AIROHA_PCS_ANA_TXPLL_SDM_OUT | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD, ++ (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM); ++ ++ /* Setup SSC */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA | ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, ++ AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN | ++ AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI | ++ AIROHA_PCS_ANA_TXPLL_SSC_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0)); ++ ++ /* Setup LPF */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, ++ AIROHA_PCS_ANA_TXPLL_LPF_BC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BR | ++ AIROHA_PCS_ANA_TXPLL_CHP_IOFST | ++ AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, 0x5) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, lpf_chp_ibias)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_LPF_BWC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BWR | ++ AIROHA_PCS_ANA_TXPLL_LPF_BP, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, lpf_bwc) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, lpf_bp)); ++ ++ /* Setup VCO */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_CFIX, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H | ++ AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR | ++ AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN); ++ ++ /* Setup PCW */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); ++ ++ /* Setup KBand */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KF | ++ AIROHA_PCS_ANA_TXPLL_KBAND_KFC | ++ AIROHA_PCS_ANA_TXPLL_KBAND_DIV | ++ AIROHA_PCS_ANA_TXPLL_KBAND_CODE, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_KBAND_OPTION); ++ ++ /* Setup DIV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE | ++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCODIV, ++ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : ++ AIROHA_PCS_ANA_TXPLL_VCODIV_1); ++ ++ /* Setup TCL */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN); ++ ++ /* Enable PLL */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); ++ ++ /* Enale PLL Output */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN); ++} ++ ++static void airoha_pcs_pll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ airoha_pcs_jcpll_bringup(priv, interface); ++ ++ usleep_range(200, 300); ++ ++ airoha_pcs_txpll_bringup(priv, interface); ++ ++ usleep_range(200, 300); ++} ++ ++static void airoha_pcs_tx_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 tx_rate_ctrl; ++ u32 ckin_divisor; ++ u32 fir_cn1, fir_c0b, fir_c1; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ ckin_divisor = BIT(1); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 12; ++ fir_c1 = 0; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ ckin_divisor = BIT(2); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 11; ++ fir_c1 = 1; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ ckin_divisor = BIT(2) | BIT(0); ++ tx_rate_ctrl = BIT(1); ++ fir_cn1 = 1; ++ fir_c0b = 1; ++ fir_c1 = 11; ++ break; ++ default: ++ return; ++ } ++ ++ /* Set TX rate ctrl */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ /* Setup TX Config */ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, ++ AIROHA_PCS_ANA_TX_DMEDGEGEN_EN | ++ AIROHA_PCS_ANA_TX_CKLDO_EN); ++ ++ udelay(1); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL); ++ ++ /* FIXME: Ask Airoha TX term is OK to reset? */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, ++ ckin_divisor) | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ /* Setup TX FIR Load Parameters (Reference 660mV) */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1)); ++ ++ /* Reset TX Bar */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B, ++ AIROHA_PCS_PMA_TXCALIB_RST_B | AIROHA_PCS_PMA_TX_TOP_RST_B); ++} ++ ++static void airoha_pcs_rx_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 rx_rate_ctrl; ++ u32 osr; ++ u32 pr_cdr_beta_dac; ++ u32 cdr_pr_buf_in_sr; ++ bool cdr_pr_cap_en; ++ u32 sigdet_vth_sel; ++ u32 phyck_div, phyck_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ osr = BIT(1) | BIT(0); /* 1.25G */ ++ pr_cdr_beta_dac = BIT(3); ++ rx_rate_ctrl = 0; ++ cdr_pr_cap_en = false; ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); ++ sigdet_vth_sel = BIT(2) | BIT(1); ++ phyck_div = BIT(5) | BIT(3) | BIT(0); ++ phyck_sel = BIT(0); ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ osr = BIT(0); /* 2.5G */ ++ pr_cdr_beta_dac = BIT(2) | BIT(1); ++ rx_rate_ctrl = 0; ++ cdr_pr_cap_en = true; ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1); ++ sigdet_vth_sel = BIT(2) | BIT(1); ++ phyck_div = BIT(3) | BIT(1) | BIT(0); ++ phyck_sel = BIT(0); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ osr = 0; /* 10G */ ++ cdr_pr_cap_en = false; ++ pr_cdr_beta_dac = BIT(3); ++ rx_rate_ctrl = BIT(1); ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); ++ sigdet_vth_sel = BIT(1); ++ phyck_div = BIT(6) | BIT(1); ++ phyck_sel = BIT(1); ++ break; ++ default: ++ return; ++ } ++ ++ /* Set RX rate ctrl */ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_2, ++ AIROHA_PCS_PMA_CK_RATE, ++ AIROHA_PCS_PMA_CK_RATE_10); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1, ++ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl)); ++ ++ /* Setup RX Path */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_5, ++ AIROHA_PCS_PMA_FLL_IDAC_MIN | ++ AIROHA_PCS_PMA_FLL_IDAC_MAX, ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) | ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x3ff)); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, ++ AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB, ++ AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, ++ AIROHA_PCS_ANA_FE_VCM_GEN_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, ++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_AEQ_CFORCE, ++ AIROHA_PCS_ANA_AEQ_OFORCE, ++ AIROHA_PCS_ANA_AEQ_OFORCE_CTLE); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, ++ AIROHA_PCS_PMA_DISB_BLWC_OFFSET); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, ++ AIROHA_PCS_PMA_DISB_LEQ); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, ++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS | ++ AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_BYPASS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON | ++ AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_RX_DAC_MON | ++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN | ++ AIROHA_PCS_ANA_CDR_PR_MONDPI_EN | ++ AIROHA_PCS_ANA_CDR_PR_MONDPR_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_MON, 0x0) | ++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN); ++ ++ /* Setup FE Gain and FE Peacking */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PEAKING_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL, 0x0)); ++ ++ /* Setup FE VOS */ ++ if (interface != PHY_INTERFACE_MODE_USXGMII && ++ interface != PHY_INTERFACE_MODE_10GBASER) ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | ++ AIROHA_PCS_PMA_FORCE_DA_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_FE_VOS, 0x0)); ++ ++ /* Setup FLL PR FMeter (no bypass mode)*/ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_0, ++ AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, 0x1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_1, ++ AIROHA_PCS_PMA_PLL_LOCK_TARGET_END | ++ AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_END, 0xffff) | ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_3, ++ AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, 0x1)); ++ ++ /* FIXME: Warn and Ask Airoha about typo in air_eth_xsgmii.c line 1391 */ ++ /* AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL is set 0x0 in SDK but seems a typo */ ++ /* Setup REV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, ++ AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0)); ++ ++ /* Setup Rdy Timeout */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5, ++ AIROHA_PCS_PMA_RX_RDY | ++ AIROHA_PCS_PMA_RX_BLWC_RDY_EN, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5)); ++ ++ /* Setup CaBoundry Init */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, ++ AIROHA_PCS_PMA_RX_OS_START | ++ AIROHA_PCS_PMA_OSC_SPEED_OPT, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1) | ++ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6, ++ AIROHA_PCS_PMA_RX_OS_END, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1, ++ AIROHA_PCS_PMA_RX_PICAL_END | ++ AIROHA_PCS_PMA_RX_PICAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4, ++ AIROHA_PCS_PMA_RX_SDCAL_END | ++ AIROHA_PCS_PMA_RX_SDCAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2, ++ AIROHA_PCS_PMA_RX_PDOS_END | ++ AIROHA_PCS_PMA_RX_PDOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3, ++ AIROHA_PCS_PMA_RX_FEOS_END | ++ AIROHA_PCS_PMA_RX_FEOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2)); ++ ++ /* Setup By Serdes*/ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr)); ++ ++ /* Setup RX OSR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, ++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS, ++ osr ? AIROHA_PCS_ANA_CDR_PD_EDGE_DIS : 0); ++ ++ /* Setup CDR LPF Ratio */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, ++ AIROHA_PCS_ANA_CDR_LPF_TOP_LIM | ++ AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x20000) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, osr)); ++ ++ /* Setup CDR PR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, ++ AIROHA_PCS_ANA_CDR_PR_KBAND_DIV | ++ AIROHA_PCS_ANA_CDR_PR_BETA_SEL | ++ AIROHA_PCS_ANA_CDR_PR_VCOADC_OS | ++ AIROHA_PCS_ANA_CDR_PR_BETA_DAC, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_KBAND_DIV, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_SEL, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VCOADC_OS, 0x8) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC, pr_cdr_beta_dac)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, ++ AIROHA_PCS_ANA_CDR_PR_FBKSEL | ++ AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND | ++ AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL | ++ AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND, pr_cdr_beta_dac) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x6) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x6)); ++ ++ /* Setup Eye Mon */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_3, ++ AIROHA_PCS_PMA_EQ_DEBUG_SEL | ++ AIROHA_PCS_PMA_FOM_NUM_ORDER | ++ AIROHA_PCS_PMA_A_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_DEBUG_SEL, 0x0) | ++ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) | ++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, ++ AIROHA_PCS_PMA_DATA_SHIFT | ++ AIROHA_PCS_PMA_EYECNT_FAST, ++ AIROHA_PCS_PMA_EYECNT_FAST); ++ ++ /* Calibration Start */ ++ ++ /* Enable SYS */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0, ++ AIROHA_PCS_PMA_RX_SYS_EN_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1)); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0, ++ AIROHA_PCS_PMA_SW_LCPLL_EN); ++ ++ usleep_range(500, 600); ++ ++ /* Setup FLL PR FMeter (bypass mode)*/ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_FBCK_LOCK); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_FBCK_LOCK); ++ ++ /* Enable CMLEQ */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN | ++ AIROHA_PCS_ANA_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN); ++ ++ /* Setup CDR PR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_CDR_PR_CAP_EN | ++ AIROHA_PCS_ANA_CDR_BUF_IN_SR, ++ (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr)); ++ ++ /* Setup CDR xxx Pwdb, set force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, ++ AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | ++ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); ++ ++ /* FIXME: Ask Airoha WHY it's cleared? */ ++ /* regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ * AIROHA_PCS_ANA_RX_FE_50OHMS_SEL); ++ */ ++ ++ /* Setup SigDet */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL | ++ AIROHA_PCS_ANA_RX_SIGDET_PEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, sigdet_vth_sel) | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, BIT(1))); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, ++ AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, BIT(1) | BIT(0))); ++ ++ /* Disable SigDet Pwdb */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, ++ AIROHA_PCS_PMA_RX_SIDGET_PWDB); ++ ++ /* Setup PHYCK */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_TDC_CK_SEL | ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ AIROHA_PCS_ANA_RX_PHYCK_SEL | ++ AIROHA_PCS_ANA_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel) | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE | ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE); ++ ++ usleep_range(100, 200); ++ ++ /* Enable CDR xxx Pwdb */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, ++ AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | ++ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); ++ ++ /* Enable SigDet Pwdb */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, ++ AIROHA_PCS_PMA_RX_SIDGET_PWDB); ++} ++ ++static unsigned int airoha_pcs_apply_cdr_pr_idac(struct airoha_pcs_priv *priv, ++ u32 cdr_pr_idac) ++{ ++ u32 val; ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, ++ cdr_pr_idac)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL); ++ ++ usleep_range(5000, 7000); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); ++ ++ return FIELD_GET(AIROHA_PCS_PMA_FL_OUT, val); ++} ++ ++static void airoha_pcs_rx_prcal(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ unsigned int remaining_prcal_search_bits; ++ unsigned int fl_out_diff = UINT_MAX; ++ u32 best_prcal_search_bit; ++ unsigned int prcal_search; ++ int prcal_search_bit; ++ unsigned int fl_out; ++ int cdr_pr_idac = 0; ++ ++ u32 target_fl_out; ++ u32 cyclecnt; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: /* DS_1.25G / US_1.25G */ ++ case PHY_INTERFACE_MODE_1000BASEX: ++ target_fl_out = 0xa3d6; ++ cyclecnt = 32767; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: /* DS_9.95328G / US_9.95328G */ ++ target_fl_out = 0xa000; ++ cyclecnt = 20000; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: /* DS_10.3125G / US_1.25G */ ++ case PHY_INTERFACE_MODE_10GBASER: ++ target_fl_out = 0x9edf; ++ cyclecnt = 32767; ++ break; ++ default: ++ return; ++ } ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_2, ++ AIROHA_PCS_PMA_LOCK_TARGET_END | ++ AIROHA_PCS_PMA_LOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_END, target_fl_out + 100) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_BEG, target_fl_out - 100)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_1, ++ AIROHA_PCS_PMA_UNLOCK_CYCLECNT | ++ AIROHA_PCS_PMA_LOCK_CYCLECNT, ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_CYCLECNT, cyclecnt) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_CYCLECNT, cyclecnt)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_LOCK_UNLOCKTH | ++ AIROHA_PCS_PMA_LOCK_LOCKTH, ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_UNLOCKTH, 3) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_LOCKTH, 3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_3, ++ AIROHA_PCS_PMA_UNLOCK_TARGET_END | ++ AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_END, target_fl_out + 100) | ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, target_fl_out - 100)); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, ++ AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ /* Calibration logic: ++ * First check the major value by looping with every ++ * value in the last 3 bit of CDR_PR_IDAC. ++ * Get the signal level and save the value that is closer to ++ * the target. ++ * ++ * Then check each remaining 7 bits in search of the deadline ++ * where the signal gets farther than signal target. ++ * ++ * Finally fine tune for the remaining bits to find the one that ++ * produce the closest signal level. ++ */ ++ for (prcal_search = 0; prcal_search < 8 ; prcal_search++) { ++ unsigned int fl_out_diff_new; ++ u32 cdr_pr_idac_tmp; ++ ++ /* try to find the upper value by setting the last 3 bit */ ++ cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, ++ prcal_search); ++ fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ if (fl_out_diff_new < fl_out_diff) { ++ cdr_pr_idac = cdr_pr_idac_tmp; ++ fl_out_diff = fl_out_diff_new; ++ } ++ } ++ ++ /* Deadline search part. ++ * We start from top bits to bottom as we progressively decrease the ++ * signal. ++ */ ++ for (prcal_search_bit = 7; prcal_search_bit >= 0; prcal_search_bit--) { ++ unsigned int fl_out_diff_new; ++ u32 cdr_pr_idac_tmp; ++ ++ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); ++ fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ if (fl_out_diff_new < fl_out_diff) { ++ best_prcal_search_bit = prcal_search_bit; ++ fl_out_diff = fl_out_diff_new; ++ } ++ } ++ ++ /* Set the idac with the best value we found and ++ * reset the search bit to start from bottom to top. ++ */ ++ cdr_pr_idac |= BIT(best_prcal_search_bit); ++ remaining_prcal_search_bits = best_prcal_search_bit; ++ prcal_search_bit = 0; ++ ++ /* Fine tune part. ++ * Test remaining bits to find an even closer signal level to target ++ * by increasing the signal. ++ */ ++ while (remaining_prcal_search_bits) { ++ unsigned int fl_out_diff_new; ++ u32 cdr_pr_idac_tmp; ++ ++ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); ++ fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ /* Assume we found the deadline when the new absolue signal difference ++ * from target is greater than the previous and the difference is at ++ * least 10% greater between the old and new value. ++ * This is to account for signal detection level tollerance making ++ * sure we are actually over a deadline (AKA we are getting farther ++ * from target) ++ */ ++ if (fl_out_diff_new > fl_out_diff && ++ (abs(fl_out_diff_new - fl_out_diff) * 100) / fl_out_diff > 10) { ++ /* Exit early if we are already at the deadline */ ++ if (prcal_search_bit == 0) ++ break; ++ ++ /* We found the deadline, set the value to the previous ++ * bit, and reset the loop to fine tune with the ++ * remaining values. ++ */ ++ cdr_pr_idac |= BIT(prcal_search_bit - 1); ++ remaining_prcal_search_bits = prcal_search_bit - 1; ++ prcal_search_bit = 0; ++ } else { ++ /* Update the signal level diff and try the next bit */ ++ fl_out_diff = fl_out_diff_new; ++ ++ /* If we didn't found the deadline, set the last bit ++ * and reset the loop to fine tune with the remainig ++ * values. ++ */ ++ if (prcal_search_bit == remaining_prcal_search_bits - 1) { ++ cdr_pr_idac |= BIT(prcal_search_bit); ++ remaining_prcal_search_bits = prcal_search_bit; ++ prcal_search_bit = 0; ++ } else { ++ prcal_search_bit++; ++ } ++ } ++ } ++ ++ fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac); ++ dev_dbg(priv->dev, "Selected CDR Pr Idac: %x Fl Out: %x\n", cdr_pr_idac, fl_out); ++ if (abs(fl_out - target_fl_out) > 100) ++ dev_dbg(priv->dev, "Fl Out is %d far from target %d on intermediate calibration.\n", ++ abs(fl_out - target_fl_out), target_fl_out); ++ ++ /* Setup Load Band */ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, ++ AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF); ++ ++ /* Disable force of LPF C previously enabled */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_B, ++ AIROHA_PCS_PMA_LOAD_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_1, ++ AIROHA_PCS_PMA_LPATH_IDAC, ++ FIELD_PREP(AIROHA_PCS_PMA_LPATH_IDAC, cdr_pr_idac)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++} ++ ++/* This is used to both calibrate and lock to signal (after a previous ++ * calibration) after a global reset. ++ */ ++static void airoha_pcs_cdr_reset(struct airoha_pcs_priv *priv, ++ phy_interface_t interface, bool calibrate) ++{ ++ /* Setup LPF L2D force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++ ++ /* Calibrate IDAC and setup Load Band */ ++ if (calibrate) ++ airoha_pcs_rx_prcal(priv, interface); ++ ++ /* Setup LPF RSTB force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ usleep_range(700, 1000); ++ ++ /* Force Enable LPF RSTB */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++ ++ usleep_range(100, 200); ++ ++ /* Force Enable LPF L2D */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); ++ ++ /* Disable LPF RSTB force bit */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ /* Disable LPF L2D force bit */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++} ++ ++static int airoha_pcs_phya_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ int calibration_try = 0; ++ u32 val; ++ ++ airoha_pcs_tx_bringup(priv, interface); ++ airoha_pcs_rx_bringup(priv, interface); ++ ++ usleep_range(100, 200); ++ ++retry_calibration: ++ airoha_pcs_cdr_reset(priv, interface, true); ++ ++ /* Global reset clear */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_REF_RST_N | ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | ++ AIROHA_PCS_PMA_SW_PMA_RST_N | ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++ ++ /* Global reset */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_REF_RST_N | ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | ++ AIROHA_PCS_PMA_SW_PMA_RST_N | ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); ++ ++ usleep_range(5000, 7000); ++ ++ airoha_pcs_cdr_reset(priv, interface, false); ++ ++ /* It was discovered that after a global reset and auto mode gets ++ * actually enabled, the fl_out from calibration might change and ++ * might deviates a lot from the expected value it was calibrated for. ++ * To correctly work, the PCS FreqDet module needs to Lock to the fl_out ++ * (frequency level output) or no signal can correctly be transmitted. ++ * This is detected by checking the FreqDet module Lock bit. ++ * ++ * If it's detected that the FreqDet module is not locked, retry ++ * calibration. From observation on real hardware with a 10g SFP module, ++ * it required a maximum of an additional calibration to actually make ++ * the FreqDet module to lock. Try 10 times before failing to handle ++ * really strange case. ++ */ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); ++ if (!(val & AIROHA_PCS_PMA_FBCK_LOCK)) { ++ if (calibration_try > AIROHA_PCS_MAX_CALIBRATION_TRY) { ++ dev_err(priv->dev, "No FBCK Lock from FreqDet module after %d calibration try. PCS won't work.\n", ++ AIROHA_PCS_MAX_CALIBRATION_TRY); ++ return -EIO; ++ } ++ ++ calibration_try++; ++ ++ dev_dbg(priv->dev, "No FBCK Lock from FreqDet module, retry calibration.\n"); ++ goto retry_calibration; ++ } ++ ++ return 0; ++} ++ ++static void airoha_pcs_get_state_sgmii(struct airoha_pcs_priv *priv, ++ unsigned int neg_mode, ++ struct phylink_link_state *state) ++{ ++ u32 bmsr, lpa; ++ ++ regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, ++ &bmsr); ++ regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5, ++ &lpa); ++ ++ bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE | ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT | ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY | ++ AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr; ++ lpa = AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY & lpa; ++ ++ phylink_mii_c22_pcs_decode_state(state, neg_mode, bmsr, lpa); ++} ++ ++static void airoha_pcs_get_state_usxgmii(struct airoha_pcs_priv *priv, ++ struct phylink_link_state *state) ++{ ++ u32 lpa; ++ ++ /* Toggle AN Status */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &lpa); ++ ++ state->link = !!(lpa & MDIO_USXGMII_LINK); ++ state->an_complete = state->link; ++ ++ phylink_decode_usxgmii_word(state, lpa); ++} ++ ++static void airoha_pcs_get_state(struct phylink_pcs *pcs, ++ unsigned int neg_mode, ++ struct phylink_link_state *state) ++{ ++ struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs); ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ airoha_pcs_get_state_sgmii(priv, neg_mode, state); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ airoha_pcs_get_state_usxgmii(priv, state); ++ break; ++ default: ++ return; ++ } ++} ++ ++static int airoha_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs); ++ u32 rate_adapt; ++ int ret; ++ ++ priv->interface = interface; ++ ++ /* Select HSGMII or USXGMII in SCU regs */ ++ airoha_pcs_setup_scu(priv, interface); ++ ++ /* Enable Analog Common Lane */ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CMN_EN, ++ AIROHA_PCS_ANA_CMN_EN); ++ ++ /* Setup PLL */ ++ airoha_pcs_pll_bringup(priv, interface); ++ ++ /* Setup PHYA */ ++ ret = airoha_pcs_phya_bringup(priv, interface); ++ if (ret) ++ return ret; ++ ++ /* Set final configuration for various modes */ ++ airoha_pcs_init(priv, interface); ++ ++ /* Configure Interrupt for various modes */ ++ airoha_pcs_interrupt_init(priv, interface); ++ ++ /* FIXME: With an attached Aeonsemi PHY, rate adaption is needed ++ * even with no inband. ++ */ ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN; ++ ++ /* AN Auto Settings (Rate Adaptation) */ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN, rate_adapt); ++ ++ /* FIXME: With an attached Aeonsemi PHY, AN is needed ++ * even with no inband. ++ */ ++ if (interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER) { ++ regmap_set_bits(priv->usxgmii_pcs, ++ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_ENABLE); ++ } ++ ++ /* Clear any force bit that my be set by bootloader */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, ++ AIROHA_PCS_LINK_MODE_P0 | ++ AIROHA_PCS_FORCE_SPD_MODE_P0 | ++ AIROHA_PCS_FORCE_LINKDOWN_P0 | ++ AIROHA_PCS_FORCE_LINKUP_P0); ++ } ++ ++ /* Toggle Rate Adaption for SGMII/HSGMII mode */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) ++ regmap_clear_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, ++ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); ++ else ++ regmap_set_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, ++ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); ++ } ++ ++ /* Setup AN Link Timer */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ u32 an_timer; ++ ++ an_timer = phylink_get_link_timer_ns(interface); ++ ++ /* Value needs to be shifted by 4, seems value is internally * 16 */ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11, ++ AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, ++ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, ++ an_timer >> 4)); ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_3, ++ AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, ++ FIELD_PREP(AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, ++ an_timer >> 4)); ++ } ++ ++ /* Setup SGMII AN and advertisement in DEV_ABILITY */ ++ if (interface == PHY_INTERFACE_MODE_SGMII && ++ neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ int advertise = phylink_mii_c22_pcs_encode_advertisement(interface, ++ advertising); ++ if (advertise < 0) ++ return advertise; ++ ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); ++ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4, ++ AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, ++ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, ++ advertise)); ++ } else { ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX) { ++ u32 if_mode = AIROHA_PCS_HSGMII_AN_SGMII_EN | ++ AIROHA_PCS_HSGMII_AN_SIDEBAND_EN; ++ ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); ++ ++ /* Clear force speed bits and MAC mode */ ++ regmap_clear_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | ++ AIROHA_PCS_HSGMII_PCS_MAC_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); ++ } else { ++ if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN; ++ ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); ++ ++ /* AN off force rate adaption, speed is set later in Link Up */ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_MAC_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT, ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); ++ } ++ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0, if_mode); ++ ++ /* FIXME: Airoha apply a different configuration here */ ++ /* They force rate adaption */ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_TX_ENABLE | ++ AIROHA_PCS_HSGMII_PCS_MODE2_EN); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_1000BASEX && ++ neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_SGMII_SEND_AN_ERR_EN); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37, ++ AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE); ++ } ++ ++ /* Configure Flow Control on XFI */ ++ regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN, ++ permit_pause_to_mac ? ++ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN : ++ 0); ++ ++ return 0; ++} ++ ++static void airoha_pcs_an_restart(struct phylink_pcs *pcs) ++{ ++ struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs); ++ ++ switch (priv->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); ++ udelay(3); ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_RESTART); ++ udelay(3); ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_RESTART); ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, int speed, int duplex) ++{ ++ struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs); ++ ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ regmap_update_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0x0) | ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x0)); ++ udelay(1); ++ regmap_update_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0xf) | ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x5)); ++ } ++ } else { ++ if (interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER) { ++ u32 mode; ++ u32 rate_adapt; ++ ++ switch (speed) { ++ case SPEED_10000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000; ++ mode = AIROHA_PCS_USXGMII_MODE_10000; ++ break; ++ case SPEED_5000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000; ++ mode = AIROHA_PCS_USXGMII_MODE_5000; ++ break; ++ case SPEED_2500: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500; ++ mode = AIROHA_PCS_USXGMII_MODE_2500; ++ break; ++ case SPEED_1000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000; ++ mode = AIROHA_PCS_USXGMII_MODE_1000; ++ break; ++ case SPEED_100: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100; ++ mode = AIROHA_PCS_USXGMII_MODE_100; ++ break; ++ } ++ ++ /* Trigger USXGMII change mode and force selected speed */ ++ regmap_update_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, ++ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE | ++ AIROHA_PCS_USXGMII_MODE, ++ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE | mode); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11, ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | ++ rate_adapt); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX) { ++ u32 force_speed; ++ u32 rate_adapt; ++ ++ switch (speed) { ++ case SPEED_1000: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000; ++ break; ++ case SPEED_100: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100; ++ break; ++ case SPEED_10: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10; ++ break; ++ } ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, ++ force_speed | rate_adapt); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ u32 ck_gen_mode; ++ u32 speed_reg; ++ u32 if_mode; ++ ++ switch (speed) { ++ case SPEED_2500: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_2_5G; ++ break; ++ case SPEED_1000: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_1G; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000; ++ break; ++ case SPEED_100: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100; ++ break; ++ case SPEED_10: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10; ++ break; ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, ++ if_mode); ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE, ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL, ++ ck_gen_mode | ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL); ++ } ++ ++ regmap_update_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, ++ AIROHA_PCS_LINK_MODE_P0 | ++ AIROHA_PCS_FORCE_SPD_MODE_P0, ++ speed_reg | ++ AIROHA_PCS_FORCE_SPD_MODE_P0); ++ } ++ } ++ ++ /* Reset TXPCS on link up */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); ++ ++ usleep_range(100, 200); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); ++} ++ ++static const struct phylink_pcs_ops airoha_pcs_ops = { ++ .pcs_get_state = airoha_pcs_get_state, ++ .pcs_config = airoha_pcs_config, ++ .pcs_an_restart = airoha_pcs_an_restart, ++ .pcs_link_up = airoha_pcs_link_up, ++}; ++ ++static const struct regmap_config airoha_pcs_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ ++static int airoha_pcs_probe(struct platform_device *pdev) ++{ ++ struct regmap_config syscon_config = airoha_pcs_regmap_config; ++ struct device *dev = &pdev->dev; ++ struct airoha_pcs_priv *priv; ++ void __iomem *base; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->dev = dev; ++ priv->data = of_device_get_match_data(dev); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_mac"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_mac"; ++ priv->xfi_mac = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_mac)) ++ return PTR_ERR(priv->xfi_mac); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_an"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_an"; ++ priv->hsgmii_an = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_an)) ++ return PTR_ERR(priv->hsgmii_an); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_pcs"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_pcs"; ++ priv->hsgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_pcs)) ++ return PTR_ERR(priv->hsgmii_pcs); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_rate_adp"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_rate_adp"; ++ priv->hsgmii_rate_adp = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_rate_adp)) ++ return PTR_ERR(priv->hsgmii_rate_adp); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "multi_sgmii"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "multi_sgmii"; ++ priv->multi_sgmii = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->multi_sgmii)) ++ return PTR_ERR(priv->multi_sgmii); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "usxgmii"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "usxgmii"; ++ priv->usxgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->usxgmii_pcs)) ++ return PTR_ERR(priv->usxgmii_pcs); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_pma"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_pma"; ++ priv->xfi_pma = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_pma)) ++ return PTR_ERR(priv->xfi_pma); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_ana"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_ana"; ++ priv->xfi_ana = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_ana)) ++ return PTR_ERR(priv->xfi_ana); ++ ++ /* SCU is used to toggle XFI or HSGMII in global SoC registers */ ++ priv->scu = syscon_regmap_lookup_by_compatible("airoha,en7581-scu"); ++ if (IS_ERR(priv->scu)) ++ return PTR_ERR(priv->scu); ++ ++ priv->rsts[0].id = "mac"; ++ priv->rsts[1].id = "phy"; ++ ret = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); ++ ++ platform_set_drvdata(pdev, priv); ++ ++ priv->pcs.ops = &airoha_pcs_ops; ++ priv->pcs.poll = true; ++ ++ __set_bit(PHY_INTERFACE_MODE_SGMII, priv->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_1000BASEX, priv->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_2500BASEX, priv->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, priv->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, priv->pcs.supported_interfaces); ++ ++ return fwnode_pcs_add_provider(dev_fwnode(dev), fwnode_pcs_simple_get, ++ &priv->pcs); ++} ++ ++static void airoha_pcs_remove(struct platform_device *pdev) ++{ ++ struct airoha_pcs_priv *priv = platform_get_drvdata(pdev); ++ ++ fwnode_pcs_del_provider(dev_fwnode(&pdev->dev)); ++ ++ rtnl_lock(); ++ phylink_release_pcs(&priv->pcs); ++ rtnl_unlock(); ++} ++ ++static const struct airoha_pcs_match_data an7581_pcs_eth = { ++ .port_type = AIROHA_PCS_ETH, ++}; ++ ++static const struct airoha_pcs_match_data an7581_pcs_pon = { ++ .port_type = AIROHA_PCS_PON, ++}; ++ ++static const struct of_device_id airoha_pcs_of_table[] = { ++ { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth }, ++ { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(of, airoha_pcs_of_table); ++ ++static struct platform_driver airoha_pcs_driver = { ++ .driver = { ++ .name = "airoha-pcs", ++ .of_match_table = airoha_pcs_of_table, ++ }, ++ .probe = airoha_pcs_probe, ++ .remove = airoha_pcs_remove, ++}; ++module_platform_driver(airoha_pcs_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Airoha PCS driver"); ++MODULE_AUTHOR("Christian Marangi "); +diff --git a/include/linux/pcs/pcs-airoha.h b/include/linux/pcs/pcs-airoha.h +new file mode 100644 +index 000000000000..07797645ff15 +--- /dev/null ++++ b/include/linux/pcs/pcs-airoha.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef __LINUX_PCS_AIROHA_H ++#define __LINUX_PCS_AIROHA_H ++ ++/* XFI_MAC */ ++#define AIROHA_PCS_XFI_MAC_XFI_GIB_CFG 0x0 ++#define AIROHA_PCS_XFI_TX_FC_EN BIT(5) ++#define AIROHA_PCS_XFI_RX_FC_EN BIT(4) ++ ++#endif /* __LINUX_PCS_AIROHA_H */ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0060-dt-bindings-net-pcs-Document-support-for-Airoha-Ethe.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0060-dt-bindings-net-pcs-Document-support-for-Airoha-Ethe.patch new file mode 100644 index 000000000..1052cea2e --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0060-dt-bindings-net-pcs-Document-support-for-Airoha-Ethe.patch @@ -0,0 +1,141 @@ +From 867bdc4af013a1f530133b01c7d4494a99d88b2b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 7 Apr 2025 00:14:03 +0200 +Subject: [PATCH 60/84] dt-bindings: net: pcs: Document support for Airoha + Ethernet PCS + +Document support for Airoha Ethernet PCS for AN7581 SoC. + +Airoha AN7581 SoC expose multiple Physical Coding Sublayer (PCS) for +the various Serdes port supporting different Media Independent Interface +(10BASE-R, USXGMII, 2500BASE-X, 1000BASE-X, SGMII). + +This follow the new PCS provider with the use of #pcs-cells property. + +Signed-off-by: Christian Marangi +--- + .../bindings/net/pcs/airoha,pcs.yaml | 112 ++++++++++++++++++ + 1 file changed, 112 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml + +diff --git a/Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml b/Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml +new file mode 100644 +index 000000000000..8bcf7757c728 +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml +@@ -0,0 +1,112 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/pcs/airoha,pcs.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Airoha Ethernet PCS and Serdes ++ ++maintainers: ++ - Christian Marangi ++ ++description: ++ Airoha AN7581 SoC expose multiple Physical Coding Sublayer (PCS) for ++ the various Serdes port supporting different Media Independent Interface ++ (10BASE-R, USXGMII, 2500BASE-X, 1000BASE-X, SGMII). ++ ++properties: ++ compatible: ++ enum: ++ - airoha,an7581-pcs-eth ++ - airoha,an7581-pcs-pon ++ ++ reg: ++ items: ++ - description: XFI MAC reg ++ - description: HSGMII AN reg ++ - description: HSGMII PCS reg ++ - description: MULTI SGMII reg ++ - description: USXGMII reg ++ - description: HSGMII rate adaption reg ++ - description: XFI Analog register ++ - description: XFI PMA (Physical Medium Attachment) register ++ ++ reg-names: ++ items: ++ - const: xfi_mac ++ - const: hsgmii_an ++ - const: hsgmii_pcs ++ - const: multi_sgmii ++ - const: usxgmii ++ - const: hsgmii_rate_adp ++ - const: xfi_ana ++ - const: xfi_pma ++ ++ resets: ++ items: ++ - description: MAC reset ++ - description: PHY reset ++ ++ reset-names: ++ items: ++ - const: mac ++ - const: phy ++ ++ "#pcs-cells": ++ const: 0 ++ ++required: ++ - compatible ++ - reg ++ - reg-names ++ - resets ++ - reset-names ++ - "#pcs-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ pcs@1fa08000 { ++ compatible = "airoha,an7581-pcs-pon"; ++ reg = <0x1fa08000 0x1000>, ++ <0x1fa80000 0x60>, ++ <0x1fa80a00 0x164>, ++ <0x1fa84000 0x450>, ++ <0x1fa85900 0x338>, ++ <0x1fa86000 0x300>, ++ <0x1fa8a000 0x1000>, ++ <0x1fa8b000 0x1000>; ++ reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", ++ "multi_sgmii", "usxgmii", ++ "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; ++ ++ resets = <&scuclk EN7581_XPON_MAC_RST>, ++ <&scuclk EN7581_XPON_PHY_RST>; ++ reset-names = "mac", "phy"; ++ ++ #pcs-cells = <0>; ++ }; ++ ++ pcs@1fa09000 { ++ compatible = "airoha,an7581-pcs-eth"; ++ reg = <0x1fa09000 0x1000>, ++ <0x1fa70000 0x60>, ++ <0x1fa70a00 0x164>, ++ <0x1fa74000 0x450>, ++ <0x1fa75900 0x338>, ++ <0x1fa76000 0x300>, ++ <0x1fa7a000 0x1000>, ++ <0x1fa7b000 0x1000>; ++ reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", ++ "multi_sgmii", "usxgmii", ++ "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; ++ ++ resets = <&scuclk EN7581_XSI_MAC_RST>, ++ <&scuclk EN7581_XSI_PHY_RST>; ++ reset-names = "mac", "phy"; ++ ++ #pcs-cells = <0>; ++ }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0061-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0061-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch new file mode 100644 index 000000000..39809896c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0061-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch @@ -0,0 +1,367 @@ +From df68e3182801a4c6c4a7e3b3f68cefb8f58f52d3 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 12 Dec 2023 03:47:18 +0000 +Subject: [PATCH 61/84] net: pcs: pcs-mtk-lynxi: add platform driver for MT7988 + +Introduce a full platform MFD driver for the LynxI (H)SGMII PCS which +is going to initially be used for the MT7988 SoC. + +Signed-off-by: Daniel Golle +--- + drivers/net/pcs/pcs-mtk-lynxi.c | 206 +++++++++++++++++++++++++++++--- + 1 file changed, 189 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c +index 149ddf51d785..19c1b29beeac 100644 +--- a/drivers/net/pcs/pcs-mtk-lynxi.c ++++ b/drivers/net/pcs/pcs-mtk-lynxi.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + // Copyright (c) 2018-2019 MediaTek Inc. +-/* A library for MediaTek SGMII circuit ++/* A library and platform driver for the MediaTek LynxI SGMII circuit + * + * Author: Sean Wang + * Author: Alexander Couzens +@@ -8,11 +8,20 @@ + * + */ + ++#include + #include ++#include ++#include + #include ++#include + #include ++#include ++#include + #include ++#include + #include ++#include ++#include + + /* SGMII subsystem config registers */ + /* BMCR (low 16) BMSR (high 16) */ +@@ -65,6 +74,8 @@ + #define SGMII_PN_SWAP_MASK GENMASK(1, 0) + #define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) + ++#define MTK_NETSYS_V3_AMA_RGC3 0x128 ++ + /* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated + * data + * @regmap: The register map pointing at the range used to setup +@@ -74,13 +85,26 @@ + * @interface: Currently configured interface mode + * @pcs: Phylink PCS structure + * @flags: Flags indicating hardware properties ++ * @rstc: Reset controller ++ * @sgmii_sel: SGMII Register Clock ++ * @sgmii_rx: SGMII RX Clock ++ * @sgmii_tx: SGMII TX Clock ++ * @node: List node + */ + struct mtk_pcs_lynxi { + struct regmap *regmap; ++ struct device *dev; + u32 ana_rgc3; + phy_interface_t interface; + struct phylink_pcs pcs; + u32 flags; ++ int advertise; ++ struct reset_control *rstc; ++ struct clk *sgmii_sel; ++ struct clk *sgmii_rx; ++ struct clk *sgmii_tx; ++ struct phy *xfi_tphy; ++ struct list_head node; + }; + + static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) +@@ -120,6 +144,17 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, + FIELD_GET(SGMII_LPA, adv)); + } + ++static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs) ++{ ++ if (!mpcs->rstc) ++ return; ++ ++ reset_control_assert(mpcs->rstc); ++ udelay(100); ++ reset_control_deassert(mpcs->rstc); ++ mdelay(1); ++} ++ + static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, +@@ -128,12 +163,14 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, + struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); + bool mode_changed = false, changed; + unsigned int rgc3, sgm_mode, bmcr; +- int advertise, link_timer; ++ int link_timer; + +- advertise = phylink_mii_c22_pcs_encode_advertisement(interface, +- advertising); +- if (advertise < 0) +- return advertise; ++ if (advertising) { ++ mpcs->advertise = phylink_mii_c22_pcs_encode_advertisement(interface, ++ advertising); ++ if (mpcs->advertise < 0) ++ return mpcs->advertise; ++ } + + /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and + * we assume that fixes it's speed at bitrate = line rate (in +@@ -165,6 +202,10 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, + SGMII_PHYA_PWD); + + /* Reset SGMII PCS state */ ++ if (mpcs->xfi_tphy) ++ phy_reset(mpcs->xfi_tphy); ++ ++ mtk_sgmii_reset(mpcs); + regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, + SGMII_SW_RESET); + +@@ -192,7 +233,7 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, + + /* Update the advertisement, noting whether it has changed */ + regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, +- SGMII_ADVERTISE, advertise, &changed); ++ SGMII_ADVERTISE, mpcs->advertise, &changed); + + /* Update the sgmsys mode register */ + regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +@@ -215,6 +256,10 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, + usleep_range(50, 100); + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); + ++ /* Setup PMA/PMD */ ++ if (mpcs->xfi_tphy) ++ phy_set_mode_ext(mpcs->xfi_tphy, PHY_MODE_ETHERNET, interface); ++ + return changed || mode_changed; + } + +@@ -233,6 +278,11 @@ static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, + struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); + unsigned int sgm_mode; + ++ if (mpcs->xfi_tphy) { ++ phy_reset(mpcs->xfi_tphy); ++ phy_set_mode_ext(mpcs->xfi_tphy, PHY_MODE_ETHERNET, interface); ++ } ++ + if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { + /* Force the speed and duplex setting */ + if (speed == SPEED_10) +@@ -249,13 +299,39 @@ static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, + SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, + sgm_mode); + } ++ ++ mtk_pcs_lynxi_config(pcs, neg_mode, interface, NULL, false); ++} ++ ++static int mtk_pcs_lynxi_enable(struct phylink_pcs *pcs) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ ++ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { ++ clk_prepare_enable(mpcs->sgmii_rx); ++ clk_prepare_enable(mpcs->sgmii_tx); ++ } ++ ++ if (mpcs->xfi_tphy) ++ phy_power_on(mpcs->xfi_tphy); ++ ++ return 0; + } + + static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) + { + struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); + ++ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); ++ ++ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { ++ clk_disable_unprepare(mpcs->sgmii_tx); ++ clk_disable_unprepare(mpcs->sgmii_rx); ++ } ++ + mpcs->interface = PHY_INTERFACE_MODE_NA; ++ if (mpcs->xfi_tphy) ++ phy_power_off(mpcs->xfi_tphy); + } + + static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { +@@ -265,11 +341,12 @@ static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { + .pcs_an_restart = mtk_pcs_lynxi_restart_an, + .pcs_link_up = mtk_pcs_lynxi_link_up, + .pcs_disable = mtk_pcs_lynxi_disable, ++ .pcs_enable = mtk_pcs_lynxi_enable, + }; + +-struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, +- struct regmap *regmap, u32 ana_rgc3, +- u32 flags) ++static struct phylink_pcs *mtk_pcs_lynxi_init(struct device *dev, struct regmap *regmap, ++ u32 ana_rgc3, u32 flags, ++ struct mtk_pcs_lynxi *prealloc) + { + struct mtk_pcs_lynxi *mpcs; + u32 id, ver; +@@ -277,29 +354,33 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, + + ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); + if (ret < 0) +- return NULL; ++ return ERR_PTR(ret); + + if (id != SGMII_LYNXI_DEV_ID) { + dev_err(dev, "unknown PCS device id %08x\n", id); +- return NULL; ++ return ERR_PTR(-ENODEV); + } + + ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); + if (ret < 0) +- return NULL; ++ return ERR_PTR(ret); + + ver = FIELD_GET(SGMII_DEV_VERSION, ver); + if (ver != 0x1) { + dev_err(dev, "unknown PCS device version %04x\n", ver); +- return NULL; ++ return ERR_PTR(-ENODEV); + } + + dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, + ver); + +- mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); +- if (!mpcs) +- return NULL; ++ if (prealloc) { ++ mpcs = prealloc; ++ } else { ++ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); ++ if (!mpcs) ++ return ERR_PTR(-ENOMEM); ++ }; + + mpcs->ana_rgc3 = ana_rgc3; + mpcs->regmap = regmap; +@@ -313,6 +394,13 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, + __set_bit(PHY_INTERFACE_MODE_2500BASEX, mpcs->pcs.supported_interfaces); + + return &mpcs->pcs; ++}; ++ ++struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, ++ struct regmap *regmap, u32 ana_rgc3, ++ u32 flags) ++{ ++ return mtk_pcs_lynxi_init(dev, regmap, ana_rgc3, flags, NULL); + } + EXPORT_SYMBOL(mtk_pcs_lynxi_create); + +@@ -325,5 +413,89 @@ void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) + } + EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); + ++#ifdef CONFIG_FWNODE_PCS ++static int mtk_pcs_lynxi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct mtk_pcs_lynxi *mpcs; ++ struct phylink_pcs *pcs; ++ struct regmap *regmap; ++ u32 flags = 0; ++ ++ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); ++ if (!mpcs) ++ return -ENOMEM; ++ ++ mpcs->dev = dev; ++ regmap = syscon_node_to_regmap(np->parent); ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ ++ if (of_property_read_bool(np->parent, "mediatek,pnswap")) ++ flags |= MTK_SGMII_FLAG_PN_SWAP; ++ ++ mpcs->rstc = of_reset_control_get_shared(np->parent, NULL); ++ if (IS_ERR(mpcs->rstc)) ++ return PTR_ERR(mpcs->rstc); ++ ++ reset_control_deassert(mpcs->rstc); ++ mpcs->sgmii_sel = devm_clk_get_enabled(dev, "sgmii_sel"); ++ if (IS_ERR(mpcs->sgmii_sel)) ++ return PTR_ERR(mpcs->sgmii_sel); ++ ++ mpcs->sgmii_rx = devm_clk_get(dev, "sgmii_rx"); ++ if (IS_ERR(mpcs->sgmii_rx)) ++ return PTR_ERR(mpcs->sgmii_rx); ++ ++ mpcs->sgmii_tx = devm_clk_get(dev, "sgmii_tx"); ++ if (IS_ERR(mpcs->sgmii_tx)) ++ return PTR_ERR(mpcs->sgmii_tx); ++ ++ mpcs->xfi_tphy = devm_of_phy_get(mpcs->dev, np, NULL); ++ if (IS_ERR(mpcs->xfi_tphy)) ++ return PTR_ERR(mpcs->xfi_tphy); ++ ++ pcs = mtk_pcs_lynxi_init(dev, regmap, (uintptr_t)of_device_get_match_data(dev), ++ flags, mpcs); ++ if (IS_ERR(pcs)) ++ return PTR_ERR(pcs); ++ ++ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); ++ ++ platform_set_drvdata(pdev, mpcs); ++ ++ return fwnode_pcs_add_provider(of_fwnode_handle(np), fwnode_pcs_simple_get, &mpcs->pcs); ++} ++ ++static void mtk_pcs_lynxi_remove(struct platform_device *pdev) ++{ ++ struct mtk_pcs_lynxi *mpcs = platform_get_drvdata(pdev); ++ ++ fwnode_pcs_del_provider(dev_fwnode(&pdev->dev)); ++ ++ rtnl_lock(); ++ phylink_release_pcs(&mpcs->pcs); ++ rtnl_unlock(); ++}; ++ ++static const struct of_device_id mtk_pcs_lynxi_of_match[] = { ++ { .compatible = "mediatek,mt7988-sgmii", .data = (void *)MTK_NETSYS_V3_AMA_RGC3 }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(of, mtk_pcs_lynxi_of_match); ++ ++static struct platform_driver mtk_pcs_lynxi_driver = { ++ .driver = { ++ .name = "mtk-pcs-lynxi", ++ .of_match_table = mtk_pcs_lynxi_of_match, ++ }, ++ .probe = mtk_pcs_lynxi_probe, ++ .remove = mtk_pcs_lynxi_remove, ++}; ++module_platform_driver(mtk_pcs_lynxi_driver); ++#endif ++ ++MODULE_AUTHOR("Daniel Golle "); + MODULE_DESCRIPTION("MediaTek SGMII library for LynxI"); + MODULE_LICENSE("GPL"); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0062-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0062-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch new file mode 100644 index 000000000..dd2b70b96 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0062-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch @@ -0,0 +1,87 @@ +From 7a515019768258fa8183fd1784745197a5bc45d3 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 12 Dec 2023 03:47:31 +0000 +Subject: [PATCH 62/84] dt-bindings: net: pcs: add bindings for MediaTek + USXGMII PCS + +MediaTek's USXGMII can be found in the MT7988 SoC. We need to access +it in order to configure and monitor the Ethernet SerDes link in +USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped +legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those +interface modes are also available. + +Signed-off-by: Daniel Golle +--- + .../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++ + 1 file changed, 60 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml + +diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml +new file mode 100644 +index 000000000000..0cdaa3545edb +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml +@@ -0,0 +1,60 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: MediaTek USXGMII PCS ++ ++maintainers: ++ - Daniel Golle ++ ++description: ++ The MediaTek USXGMII PCS provides physical link control and status ++ for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces ++ provided by the PEXTP PHY. ++ In order to also support legacy 2500Base-X, 1000Base-X and Cisco ++ SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to ++ provide those interfaces modes on the same SerDes interfaces shared ++ with the USXGMII PCS. ++ ++properties: ++ $nodename: ++ pattern: "^pcs@[0-9a-f]+$" ++ ++ compatible: ++ const: mediatek,mt7988-usxgmiisys ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: USXGMII top-level clock ++ ++ resets: ++ items: ++ - description: XFI reset ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - resets ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #define MT7988_TOPRGU_XFI0_GRST 12 ++ soc { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ usxgmiisys0: pcs@10080000 { ++ compatible = "mediatek,mt7988-usxgmiisys"; ++ reg = <0 0x10080000 0 0x1000>; ++ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>; ++ resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>; ++ }; ++ }; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0063-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0063-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch new file mode 100644 index 000000000..28bcc53d5 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0063-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch @@ -0,0 +1,576 @@ +From 00c9b2059de66096114b0a566ffcb4481aa83f81 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 12 Dec 2023 03:47:47 +0000 +Subject: [PATCH 63/84] net: pcs: add driver for MediaTek USXGMII PCS + +Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting +USXGMII, 10GBase-R and 5GBase-R interface modes. + +Signed-off-by: Daniel Golle +--- + MAINTAINERS | 2 + + drivers/net/pcs/Kconfig | 12 + + drivers/net/pcs/Kconfig.orig | 55 ++++ + drivers/net/pcs/Makefile | 1 + + drivers/net/pcs/pcs-mtk-usxgmii.c | 440 ++++++++++++++++++++++++++++++ + 5 files changed, 510 insertions(+) + create mode 100644 drivers/net/pcs/Kconfig.orig + create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index c0b444e5fd5a..ad3b057e1c43 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -15275,7 +15275,9 @@ M: Daniel Golle + L: netdev@vger.kernel.org + S: Maintained + F: drivers/net/pcs/pcs-mtk-lynxi.c ++F: drivers/net/pcs/pcs-mtk-usxgmii.c + F: include/linux/pcs/pcs-mtk-lynxi.h ++F: include/linux/pcs/pcs-mtk-usxgmii.h + + MEDIATEK ETHERNET PHY DRIVERS + M: Daniel Golle +diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig +index 69d28cd1e624..a63c910da105 100644 +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -39,6 +39,18 @@ config PCS_MTK_LYNXI + This module provides helpers to phylink for managing the LynxI PCS + which is part of MediaTek's SoC and Ethernet switch ICs. + ++config PCS_MTK_USXGMII ++ tristate "MediaTek USXGMII PCS" ++ select FWNODE_PCS ++ select PCS_MTK_LYNXI ++ select PHYLINK ++ imply PHY_MTK_PEXTP ++ help ++ This module provides a driver for MediaTek's USXGMII PCS supporting ++ 10GBase-R, 5GBase-R and USXGMII interface modes. ++ 1000Base-X, 2500Base-X and Cisco SGMII are supported on the same ++ differential pairs via an embedded LynxI PCS. ++ + config PCS_RZN1_MIIC + tristate "Renesas RZ/N1 MII converter" + depends on OF && (ARCH_RZN1 || COMPILE_TEST) +diff --git a/drivers/net/pcs/Kconfig.orig b/drivers/net/pcs/Kconfig.orig +new file mode 100644 +index 000000000000..4f26acc7d47a +--- /dev/null ++++ b/drivers/net/pcs/Kconfig.orig +@@ -0,0 +1,55 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# PCS Layer Configuration ++# ++ ++menu "PCS device drivers" ++ ++config OF_PCS ++ tristate ++ depends on OF ++ depends on PHYLINK ++ help ++ OpenFirmware PCS accessors ++ ++config PCS_XPCS ++ tristate "Synopsys DesignWare Ethernet XPCS" ++ select PHYLINK ++ help ++ This module provides a driver and helper functions for Synopsys ++ DesignWare XPCS controllers. ++ ++config PCS_LYNX ++ tristate ++ help ++ This module provides helpers to phylink for managing the Lynx PCS ++ which is part of the Layerscape and QorIQ Ethernet SERDES. ++ ++config PCS_MTK_LYNXI ++ tristate ++ select REGMAP ++ help ++ This module provides helpers to phylink for managing the LynxI PCS ++ which is part of MediaTek's SoC and Ethernet switch ICs. ++ ++config PCS_MTK_USXGMII ++ tristate "MediaTek USXGMII PCS" ++ select OF_PCS ++ select PCS_MTK_LYNXI ++ select PHY_MTK_PEXTP ++ select PHYLINK ++ help ++ This module provides a driver for MediaTek's USXGMII PCS supporting ++ 10GBase-R, 5GBase-R and USXGMII interface modes. ++ 1000Base-X, 2500Base-X and Cisco SGMII are supported on the same ++ differential pairs via an embedded LynxI PHY. ++ ++config PCS_RZN1_MIIC ++ tristate "Renesas RZ/N1 MII converter" ++ depends on OF && (ARCH_RZN1 || COMPILE_TEST) ++ help ++ This module provides a driver for the MII converter that is available ++ on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in ++ pass-through mode for MII. ++ ++endmenu +diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile +index c48450f08fb7..8492324b84e5 100644 +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -9,4 +9,5 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ + obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o + obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o + obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o ++obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o + obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o +diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c +new file mode 100644 +index 000000000000..c2fa0ba8fcc7 +--- /dev/null ++++ b/drivers/net/pcs/pcs-mtk-usxgmii.c +@@ -0,0 +1,440 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2023 MediaTek Inc. ++ * Author: Henry Yen ++ * Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* USXGMII subsystem config registers */ ++/* Register to control speed */ ++#define RG_PHY_TOP_SPEED_CTRL1 0x80c ++#define USXGMII_RATE_UPDATE_MODE BIT(31) ++#define USXGMII_MAC_CK_GATED BIT(29) ++#define USXGMII_IF_FORCE_EN BIT(28) ++#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) ++#define USXGMII_RATE_ADAPT_MODE_X1 0 ++#define USXGMII_RATE_ADAPT_MODE_X2 1 ++#define USXGMII_RATE_ADAPT_MODE_X4 2 ++#define USXGMII_RATE_ADAPT_MODE_X10 3 ++#define USXGMII_RATE_ADAPT_MODE_X100 4 ++#define USXGMII_RATE_ADAPT_MODE_X5 5 ++#define USXGMII_RATE_ADAPT_MODE_X50 6 ++#define USXGMII_XFI_RX_MODE GENMASK(6, 4) ++#define USXGMII_XFI_TX_MODE GENMASK(2, 0) ++#define USXGMII_XFI_MODE_10G 0 ++#define USXGMII_XFI_MODE_5G 1 ++#define USXGMII_XFI_MODE_2P5G 3 ++ ++/* Register to control PCS AN */ ++#define RG_PCS_AN_CTRL0 0x810 ++#define USXGMII_AN_RESTART BIT(31) ++#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) ++#define USXGMII_AN_ENABLE BIT(0) ++ ++#define RG_PCS_AN_CTRL2 0x818 ++#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) ++#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) ++#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) ++ ++/* Register to read PCS AN status */ ++#define RG_PCS_AN_STS0 0x81c ++#define USXGMII_LPA GENMASK(15, 0) ++#define USXGMII_LPA_LATCH BIT(31) ++ ++/* Register to read PCS link status */ ++#define RG_PCS_RX_STATUS0 0x904 ++#define RG_PCS_RX_STATUS_UPDATE BIT(16) ++#define RG_PCS_RX_LINK_STATUS BIT(2) ++ ++/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS ++ * @pcs: Phylink PCS structure ++ * @dev: Pointer to device structure ++ * @base: IO memory to access PCS hardware ++ * @clk: Pointer to USXGMII clk ++ * @reset: Pointer to USXGMII reset control ++ * @interface: Currently selected interface mode ++ * @neg_mode: Currently used phylink neg_mode ++ * @node: List node ++ */ ++struct mtk_usxgmii_pcs { ++ struct phylink_pcs pcs; ++ struct device *dev; ++ void __iomem *base; ++ struct clk *clk; ++ struct reset_control *reset; ++ struct phy *xfi_tphy; ++ phy_interface_t interface; ++ unsigned int neg_mode; ++ struct list_head node; ++}; ++ ++static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg) ++{ ++ return ioread32(mpcs->base + reg); ++} ++ ++static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set) ++{ ++ u32 val; ++ ++ val = ioread32(mpcs->base + reg); ++ val &= ~mask; ++ val |= set; ++ iowrite32(val, mpcs->base + reg); ++} ++ ++static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) ++{ ++ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); ++} ++ ++static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs) ++{ ++ reset_control_assert(mpcs->reset); ++ udelay(100); ++ reset_control_deassert(mpcs->reset); ++ ++ mdelay(10); ++} ++ ++static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; ++ bool mode_changed = false; ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); ++ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else { ++ return -EINVAL; ++ } ++ ++ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); ++ ++ if (mpcs->interface != interface) { ++ mpcs->interface = interface; ++ mode_changed = true; ++ } ++ ++ phy_reset(mpcs->xfi_tphy); ++ mtk_usxgmii_reset(mpcs); ++ ++ /* Setup USXGMII AN ctrl */ ++ mtk_m32(mpcs, RG_PCS_AN_CTRL0, ++ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, ++ an_ctrl); ++ ++ mtk_m32(mpcs, RG_PCS_AN_CTRL2, ++ USXGMII_LINK_TIMER_IDLE_DETECT | ++ USXGMII_LINK_TIMER_COMP_ACK_DETECT | ++ USXGMII_LINK_TIMER_AN_RESTART, ++ link_timer); ++ ++ mpcs->neg_mode = neg_mode; ++ ++ /* Gated MAC CK */ ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); ++ ++ /* Enable interface force mode */ ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); ++ ++ /* Setup USXGMII adapt mode */ ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, ++ adapt_mode); ++ ++ /* Setup USXGMII speed */ ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, ++ xfi_mode); ++ ++ usleep_range(1, 10); ++ ++ /* Un-gated MAC CK */ ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0); ++ ++ usleep_range(1, 10); ++ ++ /* Disable interface force mode for the AN mode */ ++ if (an_ctrl & USXGMII_AN_ENABLE) ++ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0); ++ ++ /* Setup PMA/PMD */ ++ phy_set_mode_ext(mpcs->xfi_tphy, PHY_MODE_ETHERNET, interface); ++ ++ return mode_changed; ++} ++ ++static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs, ++ struct phylink_link_state *state) ++{ ++ u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1); ++ int speed; ++ ++ /* Calculate speed from interface speed and rate adapt mode */ ++ switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) { ++ case USXGMII_XFI_MODE_10G: ++ speed = 10000; ++ break; ++ case USXGMII_XFI_MODE_5G: ++ speed = 5000; ++ break; ++ case USXGMII_XFI_MODE_2P5G: ++ speed = 2500; ++ break; ++ default: ++ state->speed = SPEED_UNKNOWN; ++ return; ++ } ++ ++ switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) { ++ case USXGMII_RATE_ADAPT_MODE_X100: ++ speed /= 100; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X50: ++ speed /= 50; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X10: ++ speed /= 10; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X5: ++ speed /= 5; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X4: ++ speed /= 4; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X2: ++ speed /= 2; ++ break; ++ case USXGMII_RATE_ADAPT_MODE_X1: ++ break; ++ default: ++ state->speed = SPEED_UNKNOWN; ++ return; ++ } ++ ++ state->speed = speed; ++ state->duplex = DUPLEX_FULL; ++} ++ ++static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs, ++ struct phylink_link_state *state) ++{ ++ u16 lpa; ++ ++ /* Refresh LPA by toggling LPA_LATCH */ ++ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH); ++ ndelay(1020); ++ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0); ++ ndelay(1020); ++ lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0)); ++ ++ phylink_decode_usxgmii_word(state, lpa); ++} ++ ++static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, ++ unsigned int neg_mode, ++ struct phylink_link_state *state) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ ++ /* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */ ++ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, ++ RG_PCS_RX_STATUS_UPDATE); ++ ndelay(1020); ++ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0); ++ ndelay(1020); ++ ++ /* Read USXGMII link status */ ++ state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS, ++ mtk_r32(mpcs, RG_PCS_RX_STATUS0)); ++ ++ /* Continuously repeat re-configuration sequence until link comes up */ ++ if (!state->link) { ++ mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode, ++ state->interface, NULL, false); ++ return; ++ } ++ ++ if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0))) ++ mtk_usxgmii_pcs_get_an_state(mpcs, state); ++ else ++ mtk_usxgmii_pcs_get_fixed_speed(mpcs, state); ++} ++ ++static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ ++ mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART); ++} ++ ++static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, ++ int speed, int duplex) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ ++ /* Reconfiguring USXGMII to ensure the quality of the RX signal ++ * after the line side link up. ++ */ ++ mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false); ++ phy_reset(mpcs->xfi_tphy); ++ phy_set_mode_ext(mpcs->xfi_tphy, PHY_MODE_ETHERNET, interface); ++} ++ ++static int mtk_usxgmii_pcs_enable(struct phylink_pcs *pcs) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ ++ phy_power_on(mpcs->xfi_tphy); ++ ++ return 0; ++} ++ ++static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ ++ mpcs->interface = PHY_INTERFACE_MODE_NA; ++ mpcs->neg_mode = -1; ++ ++ phy_power_off(mpcs->xfi_tphy); ++} ++ ++static unsigned int mtk_usxgmii_pcs_inband_caps(struct phylink_pcs *pcs, ++ phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_5GBASER: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_USXGMII: ++ return LINK_INBAND_ENABLE; ++ ++ default: ++ return 0; ++ } ++} ++ ++static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { ++ .pcs_inband_caps = mtk_usxgmii_pcs_inband_caps, ++ .pcs_config = mtk_usxgmii_pcs_config, ++ .pcs_get_state = mtk_usxgmii_pcs_get_state, ++ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, ++ .pcs_link_up = mtk_usxgmii_pcs_link_up, ++ .pcs_enable = mtk_usxgmii_pcs_enable, ++ .pcs_disable = mtk_usxgmii_pcs_disable, ++}; ++ ++static int mtk_usxgmii_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mtk_usxgmii_pcs *mpcs; ++ ++ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); ++ if (!mpcs) ++ return -ENOMEM; ++ ++ mpcs->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(mpcs->base)) ++ return PTR_ERR(mpcs->base); ++ ++ mpcs->dev = dev; ++ mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; ++ mpcs->pcs.poll = true; ++ mpcs->interface = PHY_INTERFACE_MODE_NA; ++ mpcs->neg_mode = -1; ++ ++ __set_bit(PHY_INTERFACE_MODE_5GBASER, mpcs->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, mpcs->pcs.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, mpcs->pcs.supported_interfaces); ++ ++ mpcs->clk = devm_clk_get_enabled(mpcs->dev, NULL); ++ if (IS_ERR(mpcs->clk)) ++ return PTR_ERR(mpcs->clk); ++ ++ mpcs->xfi_tphy = devm_of_phy_get(mpcs->dev, dev->of_node, NULL); ++ if (IS_ERR(mpcs->xfi_tphy)) ++ return PTR_ERR(mpcs->xfi_tphy); ++ ++ mpcs->reset = devm_reset_control_get_shared(dev, NULL); ++ if (IS_ERR(mpcs->reset)) ++ return PTR_ERR(mpcs->reset); ++ ++ reset_control_deassert(mpcs->reset); ++ ++ platform_set_drvdata(pdev, mpcs); ++ ++ return fwnode_pcs_add_provider(dev_fwnode(dev), fwnode_pcs_simple_get, &mpcs->pcs); ++} ++ ++static void mtk_usxgmii_remove(struct platform_device *pdev) ++{ ++ struct mtk_usxgmii_pcs *mpcs = platform_get_drvdata(pdev); ++ ++ fwnode_pcs_del_provider(dev_fwnode(&pdev->dev)); ++ ++ rtnl_lock(); ++ phylink_release_pcs(&mpcs->pcs); ++ rtnl_unlock(); ++}; ++ ++static const struct of_device_id mtk_usxgmii_of_mtable[] = { ++ { .compatible = "mediatek,mt7988-usxgmiisys" }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable); ++ ++static struct platform_driver mtk_usxgmii_driver = { ++ .driver = { ++ .name = "mtk-pcs-usxgmii", ++ .of_match_table = mtk_usxgmii_of_mtable, ++ }, ++ .probe = mtk_usxgmii_probe, ++ .remove = mtk_usxgmii_remove, ++}; ++module_platform_driver(mtk_usxgmii_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MediaTek USXGMII PCS driver"); ++MODULE_AUTHOR("Daniel Golle "); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0064-net-ethernet-mtk_eth_soc-add-more-DMA-monitor-for-MT.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0064-net-ethernet-mtk_eth_soc-add-more-DMA-monitor-for-MT.patch new file mode 100644 index 000000000..f10f72f9b --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0064-net-ethernet-mtk_eth_soc-add-more-DMA-monitor-for-MT.patch @@ -0,0 +1,141 @@ +From 67b86aed2e5cad973b8616f685228c03f94ef9b9 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 1 Sep 2023 12:31:38 +0100 +Subject: [PATCH 64/84] net: ethernet: mtk_eth_soc: add more DMA monitor for + MT7988 + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++++ + 2 files changed, 61 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index ac7250003b1d..e5f0b9220aa1 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4022,10 +4022,13 @@ static void mtk_hw_warm_reset(struct mtk_eth *eth) + static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; +- bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; ++ bool gmac1_tx, gmac2_tx, gmac3_tx = false, gdm1_tx, gdm2_tx, gdm3_tx = false; + bool oq_hang, cdm1_busy, adma_busy; + bool wtx_busy, cdm_full, oq_free; +- u32 wdidx, val, gdm1_fc, gdm2_fc; ++ u32 wdidx, val, gdm1_fc, gdm2_fc, gdm3_fc; ++ u32 tdma_glo_cfg, cur_fsm, ipq10; ++ bool rx_busy, tx_busy, cur_fsm_tx, cur_fsm_rx; ++ + bool qfsm_hang, qfwd_hang; + bool ret = false; + +@@ -4061,12 +4064,19 @@ static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) + gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; + gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; + gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; +- gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); +- gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); ++ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + MTK_GDM_RX_FC_OFFSET(eth, 0)); ++ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + MTK_GDM_RX_FC_OFFSET(eth, 1)); ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ gdm3_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM3_FSM)) > 0; ++ gmac3_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(2))) != 1; ++ gdm3_fc = mtk_r32(eth, reg_map->gdm1_cnt + MTK_GDM_RX_FC_OFFSET(eth, 2)); ++ } + + if (qfsm_hang && qfwd_hang && + ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || +- (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { ++ (gdm2_tx && gmac2_tx && gdm2_fc < 1) || ++ (mtk_is_netsys_v3_or_greater(eth) && gdm3_tx && gmac3_tx && gdm3_fc < 1))) { + if (++eth->reset.qdma_hang_count > 2) { + eth->reset.qdma_hang_count = 0; + ret = true; +@@ -4088,12 +4098,47 @@ static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) + goto out; + } + ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ ipq10 = mtk_r32(eth, reg_map->pse_iq_sta + 24) & GENMASK(23, 0); ++ cur_fsm = mtk_r32(eth, MTK_FE_CDM6_FSM); ++ tdma_glo_cfg = mtk_r32(eth, MTK_TDMA_GLO_CFG); ++ cur_fsm_rx = !(cur_fsm & GENMASK(27, 16)); ++ cur_fsm_tx = !(cur_fsm & GENMASK(24, 0)); ++ tx_busy = !(tdma_glo_cfg & BIT(1)); ++ rx_busy = !(tdma_glo_cfg & BIT(3)); ++ ++ if (ipq10 && cur_fsm_tx && tx_busy && ++ cur_fsm_tx == !!(eth->reset.pre_fsm & GENMASK(24, 0)) && ++ ipq10 == eth->reset.pre_ipq10) { ++ if (++eth->reset.tdma_tx_hang_count > 2) { ++ eth->reset.tdma_tx_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ if (cur_fsm_rx && rx_busy && ++ cur_fsm_rx == (eth->reset.pre_fsm & GENMASK(27, 16))) { ++ if (++eth->reset.tdma_rx_hang_count > 2) { ++ eth->reset.tdma_rx_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ } ++ + eth->reset.wdma_hang_count = 0; + eth->reset.qdma_hang_count = 0; + eth->reset.adma_hang_count = 0; ++ eth->reset.tdma_tx_hang_count = 0; ++ eth->reset.tdma_rx_hang_count = 0; + out: + eth->reset.wdidx = wdidx; + ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ eth->reset.pre_fsm = cur_fsm; ++ eth->reset.pre_ipq10 = ipq10; ++ } + return ret; + } + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 88406e80dfec..91b2375f9405 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -401,6 +401,8 @@ + #define RX_DMA_VTAG_V2 BIT(0) + #define RX_DMA_L4_VALID_V2 BIT(2) + ++#define MTK_TDMA_GLO_CFG 0x6204 ++ + /* PHY Polling and SMI Master Control registers */ + #define MTK_PPSC 0x10000 + #define PPSC_MDC_CFG GENMASK(29, 24) +@@ -659,6 +661,11 @@ + #define MTK_FE_IRQ_RX 1 + #define MTK_FE_IRQ_NUM (MTK_FE_IRQ_RX + 1) + ++#define MTK_STAT_OFFSET 0x40 ++#define MTK_STAT_OFFSET_V3 0x80 ++#define MTK_GDM_RX_FC 0x24 ++#define MTK_GDM_RX_FC_OFFSET(eth, i) (i * (mtk_is_netsys_v3_or_greater(eth) ? MTK_STAT_OFFSET_V3 : MTK_STAT_OFFSET) + MTK_GDM_RX_FC) ++ + struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; +@@ -1392,6 +1399,10 @@ struct mtk_eth { + u8 wdma_hang_count; + u8 qdma_hang_count; + u8 adma_hang_count; ++ u8 tdma_rx_hang_count; ++ u8 tdma_tx_hang_count; ++ u32 pre_ipq10; ++ u32 pre_fsm; + } reset; + }; + +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0065-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0065-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch new file mode 100644 index 000000000..32ae098e5 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0065-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch @@ -0,0 +1,140 @@ +From 2d33fddfcc8e36b50910e92bb965a75c4685fb98 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 25 Jan 2023 00:27:49 +0000 +Subject: [PATCH 65/84] hwrng: add driver for MediaTek TRNG SMC + +Add driver providing kernel-side support for the Random Number +Generator hardware found on Mediatek SoCs which have a driver in ARM +TrustedFirmware-A allowing Linux to read random numbers using a +non-standard vendor-defined Secure Monitor Call. + +Signed-off-by: Daniel Golle +--- + drivers/char/hw_random/Kconfig | 16 +++++++ + drivers/char/hw_random/Makefile | 1 + + drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++ + 3 files changed, 91 insertions(+) + create mode 100644 drivers/char/hw_random/mtk-rng-v2.c + +diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig +index c85827843447..1a5fd4a966bd 100644 +--- a/drivers/char/hw_random/Kconfig ++++ b/drivers/char/hw_random/Kconfig +@@ -477,6 +477,22 @@ config HW_RANDOM_MTK + + If unsure, say Y. + ++config HW_RANDOM_MTK_V2 ++ tristate "Mediatek Random Number Generator support (v2/SMC)" ++ depends on HW_RANDOM ++ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST ++ default y ++ help ++ This driver provides kernel-side support for the Random Number ++ Generator hardware found on Mediatek SoCs which have a driver ++ in ARM TrustedFirmware-A allowing Linux to read using a non- ++ standard vendor-defined Secure Monitor Call. ++ ++ To compile this driver as a module, choose M here. the ++ module will be called mtk-rng-v2. ++ ++ If unsure, say Y. ++ + config HW_RANDOM_S390 + tristate "S390 True Random Number Generator support" + depends on S390 +diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile +index b9132b3f5d21..1e7ad556e784 100644 +--- a/drivers/char/hw_random/Makefile ++++ b/drivers/char/hw_random/Makefile +@@ -41,6 +41,7 @@ obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o + obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o + obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o + obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o ++obj-$(CONFIG_HW_RANDOM_MTK_V2) += mtk-rng-v2.o + obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o + obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o + obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o +diff --git a/drivers/char/hw_random/mtk-rng-v2.c b/drivers/char/hw_random/mtk-rng-v2.c +new file mode 100644 +index 000000000000..6e61f4361d9e +--- /dev/null ++++ b/drivers/char/hw_random/mtk-rng-v2.c +@@ -0,0 +1,74 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Driver for Mediatek Hardware Random Number Generator (v2/SMCC) ++ * ++ * Copyright (C) 2023 Daniel Golle ++ * based on patch from Mingming Su ++ */ ++#define MTK_RNG_DEV KBUILD_MODNAME ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550) ++ ++static int mtk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) ++{ ++ struct arm_smccc_res res; ++ int retval = 0; ++ ++ while (max >= sizeof(u32)) { ++ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0, ++ &res); ++ if (res.a0) ++ break; ++ ++ *(u32 *)buf = res.a1; ++ retval += sizeof(u32); ++ buf += sizeof(u32); ++ max -= sizeof(u32); ++ } ++ ++ return retval || !wait ? retval : -EIO; ++} ++ ++static int mtk_rng_v2_probe(struct platform_device *pdev) ++{ ++ struct hwrng *trng; ++ ++ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); ++ if (!trng) ++ return -ENOMEM; ++ ++ trng->name = pdev->name; ++ trng->read = mtk_rng_v2_read; ++ trng->quality = 900; ++ ++ return devm_hwrng_register(&pdev->dev, trng); ++} ++ ++static const struct of_device_id mtk_rng_v2_match[] = { ++ { .compatible = "mediatek,mt7981-rng" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mtk_rng_v2_match); ++ ++static struct platform_driver mtk_rng_v2_driver = { ++ .probe = mtk_rng_v2_probe, ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .of_match_table = mtk_rng_v2_match, ++ }, ++}; ++module_platform_driver(mtk_rng_v2_driver); ++ ++MODULE_DESCRIPTION("Mediatek Random Number Generator Driver (v2/SMC)"); ++MODULE_AUTHOR("Daniel Golle "); ++MODULE_LICENSE("GPL"); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0066-dts64-enable-sata-and-disable-pcie-slot-CN8-shared.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0066-dts64-enable-sata-and-disable-pcie-slot-CN8-shared.patch new file mode 100644 index 000000000..820bd7feb --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0066-dts64-enable-sata-and-disable-pcie-slot-CN8-shared.patch @@ -0,0 +1,39 @@ +From 2bb35754b2c9f707d1921952dbc6314ea285f360 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 27 Nov 2019 17:19:07 +0100 +Subject: [PATCH 66/84] dts64: enable sata and disable pcie-slot CN8 (shared) + +--- + arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +index 9f100b18a676..7e6c5c25cfa1 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -323,7 +323,7 @@ &pio { + asm-sel-hog { + gpio-hog; + gpios = <90 GPIO_ACTIVE_HIGH>; +- output-high; ++ output-low; + }; + + /* eMMC is shared pin with parallel NAND */ +@@ -597,11 +597,11 @@ &pwrap { + }; + + &sata { +- status = "disabled"; ++ status = "okay"; + }; + + &sata_phy { +- status = "disabled"; ++ status = "okay"; + }; + + &spi0 { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0067-arm64-dts-mt7622-fix-sata.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0067-arm64-dts-mt7622-fix-sata.patch new file mode 100644 index 000000000..ca6dfd093 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0067-arm64-dts-mt7622-fix-sata.patch @@ -0,0 +1,29 @@ +From 951a242f5e95fc590e383ba9c9f0a91f3313b49d Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 27 Jun 2024 22:48:27 +0200 +Subject: [PATCH 67/84] arm64: dts: mt7622: fix sata + +[ 2.480551] ahci-mtk 1a200000.sata: missing phy-mode phandle +[ 2.486249] ahci-mtk 1a200000.sata: probe with driver ahci-mtk failed with error -22 + +Fixes: 3ba5a6159434 ("arm64: dts: mediatek: mt7622: fix clock controllers") +--- + arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +index 917fa39a74f8..f22983c33365 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -790,7 +790,7 @@ u2port1: usb-phy@1a0c5000 { + }; + + pciesys: clock-controller@1a100800 { +- compatible = "mediatek,mt7622-pciesys"; ++ compatible = "mediatek,mt7622-pciesys","syscon"; + reg = <0 0x1a100800 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0068-kdeb-try-to-add-kernels-for-bpi-boards-to-deb-packag.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0068-kdeb-try-to-add-kernels-for-bpi-boards-to-deb-packag.patch new file mode 100644 index 000000000..b7a37e819 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0068-kdeb-try-to-add-kernels-for-bpi-boards-to-deb-packag.patch @@ -0,0 +1,65 @@ +From b8a589bd3322f55d7642e2c32f5aceb33c792e6e Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 14 Jan 2024 14:47:21 +0100 +Subject: [PATCH 68/84] kdeb: try to add kernels for bpi-boards to deb-packages + +--- + scripts/package/builddeb | 41 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 2 deletions(-) + +diff --git a/scripts/package/builddeb b/scripts/package/builddeb +index 3627ca227e5a..4c2142959768 100755 +--- a/scripts/package/builddeb ++++ b/scripts/package/builddeb +@@ -61,9 +61,46 @@ install_linux_image () { + parisc|mips|powerpc) + installed_image_path="boot/vmlinux-${KERNELRELEASE}";; + *) +- installed_image_path="boot/vmlinuz-${KERNELRELEASE}";; ++ source_image_path="./$board.itb" ++ installed_image_path=boot/$board-${KERNELRELEASE}.itb ++ case $board in ++ bpi-r2) ++ mkdir -p "${pdir}/boot/bananapi/$board/linux/dtb" ++ DTBFILE=arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dtb ++ cp ${srctree}/uImage_nodt "${pdir}/boot/bananapi/$board/linux/uImage-${KERNELRELEASE}_nodt" ++ source_image_path="${srctree}/uImage" ++ installed_image_path="boot/bananapi/$board/linux/uImage-${KERNELRELEASE}" ++ ;; ++ bpi-r64) ++ mkdir -p "${pdir}/boot/bananapi/$board/linux/dtb" ++ DTBFILE=arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dtb ++ cp ${srctree}/uImage_nodt "${pdir}/boot/bananapi/$board/linux/uImage-${KERNELRELEASE}_nodt" ++ ;; ++ bpi-r2pro) ++ DTBFILE=arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dtb ++ mkdir -p ${pdir}/boot/extlinux/ ++ cp arch/arm64/boot/Image.gz "${pdir}/boot/extlinux/Image-${KERNELRELEASE}.gz" ++ ;; ++ bpi-r3|bpi-r4) ++ #R3/R4 only use FIT and no standalone kernel/dtbs ++ ;; ++ *) ++ installed_image_path="boot/vmlinuz-${KERNELRELEASE}" ++ source_image_path="$($MAKE -s -f ${srctree}/Makefile image_name)" ++ ;; ++ esac ++ ;; + esac +- cp "$(${MAKE} -s -f ${srctree}/Makefile image_name)" "${pdir}/${installed_image_path}" ++ ++ if [ -n "$DTBFILE" ];then ++ if [ $board != "bpi-r2pro" ];then ++ cp $DTBFILE "${pdir}/boot/bananapi/$board/linux/dtb/$board-${KERNELRELEASE}.dtb" ++ else ++ cp $DTBFILE "${pdir}/boot/extlinux/$board-${KERNELRELEASE}.dtb" ++ fi ++ fi ++ ++ cp "${source_image_path}" "${pdir}/${installed_image_path}" + + if [ "${ARCH}" != um ]; then + install_maint_scripts "${pdir}" +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0069-kdeb-fix-deb-build-for-R3-R4.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0069-kdeb-fix-deb-build-for-R3-R4.patch new file mode 100644 index 000000000..d8efd079a --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0069-kdeb-fix-deb-build-for-R3-R4.patch @@ -0,0 +1,26 @@ +From 7483e1ad82099905e2f462be333074c8f8942f13 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 22 Apr 2025 19:45:32 +0200 +Subject: [PATCH 69/84] kdeb: fix deb build for R3+R4 + +due to the set +u unassigned variables will be handled as error +and so build fails. +--- + scripts/package/builddeb | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/scripts/package/builddeb b/scripts/package/builddeb +index 4c2142959768..11429129e044 100755 +--- a/scripts/package/builddeb ++++ b/scripts/package/builddeb +@@ -63,6 +63,7 @@ install_linux_image () { + *) + source_image_path="./$board.itb" + installed_image_path=boot/$board-${KERNELRELEASE}.itb ++ DTBFILE="" + case $board in + bpi-r2) + mkdir -p "${pdir}/boot/bananapi/$board/linux/dtb" +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0070-build.conf-change-to-r4.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0070-build.conf-change-to-r4.patch new file mode 100644 index 000000000..b21a4a72d --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0070-build.conf-change-to-r4.patch @@ -0,0 +1,25 @@ +From 0df363d725b08ae1b2d848415ce2384da6556d20 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 21 Jun 2025 15:00:03 +0200 +Subject: [PATCH 70/84] build.conf: change to r4 + +--- + build.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/build.conf b/build.conf +index c6521172e2da..0dc98280f6fa 100644 +--- a/build.conf ++++ b/build.conf +@@ -13,7 +13,7 @@ board=bpi-r2 + #board=bpi-r64 + #board=bpi-r2pro + #board=bpi-r3 +-#board=bpi-r4 ++board=bpi-r4 + + #r64 with rtl8367 + #boardversion=v0.1 +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0071-defconfig-r4-disable-STRICT_DEVMEM-to-allow-register.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0071-defconfig-r4-disable-STRICT_DEVMEM-to-allow-register.patch new file mode 100644 index 000000000..01108d5f2 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0071-defconfig-r4-disable-STRICT_DEVMEM-to-allow-register.patch @@ -0,0 +1,22 @@ +From cc587f5c5de71d50be7d030529e381e1f7c5028a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 12 Jun 2025 20:38:59 +0200 +Subject: [PATCH 71/84] defconfig: r4: disable STRICT_DEVMEM to allow + register-reads + +--- + arch/arm64/configs/mt7988a_bpi-r4_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/mt7988a_bpi-r4_defconfig b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +index 29bc60ce564f..8447280fcd8b 100644 +--- a/arch/arm64/configs/mt7988a_bpi-r4_defconfig ++++ b/arch/arm64/configs/mt7988a_bpi-r4_defconfig +@@ -1308,3 +1308,4 @@ CONFIG_MEDIATEK_2P5GE_PHY=m + #CONFIG_FB_MODE_HELPERS=y + #CONFIG_DRM_PANEL_MIPI_DBI=m + #CONFIG_BACKLIGHT_PWM=m ++CONFIG_STRICT_DEVMEM=n +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0072-net-ethernet-mtk_eth_soc-add-register-definitions-fo.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0072-net-ethernet-mtk_eth_soc-add-register-definitions-fo.patch new file mode 100644 index 000000000..82ae42ee6 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0072-net-ethernet-mtk_eth_soc-add-register-definitions-fo.patch @@ -0,0 +1,125 @@ +From 3dd0307c7129a0b1cc7616eec7500d12f1955f2c Mon Sep 17 00:00:00 2001 +From: Mason Chang +Date: Tue, 18 Mar 2025 14:09:26 +0800 +Subject: [PATCH 72/84] net: ethernet: mtk_eth_soc: add register definitions + for rss and lro + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 25 +++++++++++++++- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 32 +++++++++++++++------ + 2 files changed, 47 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index e5f0b9220aa1..98d700c55d73 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -52,13 +52,18 @@ static const struct mtk_reg_map mtk_reg_map = { + .rx_ptr = 0x0900, + .rx_cnt_cfg = 0x0904, + .pcrx_ptr = 0x0908, ++ .lro_ctrl_dw0 = 0x0980, + .glo_cfg = 0x0a04, + .rst_idx = 0x0a08, + .delay_irq = 0x0a0c, + .irq_status = 0x0a20, + .irq_mask = 0x0a28, + .adma_rx_dbg0 = 0x0a38, +- .int_grp = 0x0a50, ++ .lro_alt_score_delta = 0x0a4c, ++ .int_grp = 0x0a50, ++ .lro_rx1_dly_int = 0x0a70, ++ .lro_ring_dip_dw0 = 0x0b04, ++ .lro_ring_ctrl_dw1 = 0x0b28, + }, + .qdma = { + .qtx_cfg = 0x1800, +@@ -115,6 +120,7 @@ static const struct mtk_reg_map mt7986_reg_map = { + .tx_irq_mask = 0x461c, + .tx_irq_status = 0x4618, + .pdma = { ++ .rss_glo_cfg = 0x2800, + .rx_ptr = 0x4100, + .rx_cnt_cfg = 0x4104, + .pcrx_ptr = 0x4108, +@@ -125,6 +131,12 @@ static const struct mtk_reg_map mt7986_reg_map = { + .irq_mask = 0x4228, + .adma_rx_dbg0 = 0x4238, + .int_grp = 0x4250, ++ .int_grp3 = 0x422c, ++ .lro_ctrl_dw0 = 0x4180, ++ .lro_alt_score_delta = 0x424c, ++ .lro_rx1_dly_int = 0x4270, ++ .lro_ring_dip_dw0 = 0x4304, ++ .lro_ring_ctrl_dw1 = 0x4328, + }, + .qdma = { + .qtx_cfg = 0x4400, +@@ -172,10 +184,21 @@ static const struct mtk_reg_map mt7988_reg_map = { + .glo_cfg = 0x6a04, + .rst_idx = 0x6a08, + .delay_irq = 0x6a0c, ++ .rx_cfg = 0x6a10, + .irq_status = 0x6a20, + .irq_mask = 0x6a28, + .adma_rx_dbg0 = 0x6a38, + .int_grp = 0x6a50, ++ .int_grp3 = 0x6a58, ++ .tx_delay_irq = 0x6ab0, ++ .rx_delay_irq = 0x6ac0, ++ .lro_ctrl_dw0 = 0x6c08, ++ .lro_alt_score_delta = 0x6c1c, ++ .lro_ring_dip_dw0 = 0x6c14, ++ .lro_ring_ctrl_dw1 = 0x6c38, ++ .lro_alt_dbg = 0x6c40, ++ .lro_alt_dbg_data = 0x6c44, ++ .rss_glo_cfg = 0x7000, + }, + .qdma = { + .qtx_cfg = 0x4400, +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 91b2375f9405..eb2328596c8b 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1189,16 +1189,30 @@ struct mtk_reg_map { + u32 tx_irq_mask; + u32 tx_irq_status; + struct { +- u32 rx_ptr; /* rx base pointer */ +- u32 rx_cnt_cfg; /* rx max count configuration */ +- u32 pcrx_ptr; /* rx cpu pointer */ +- u32 glo_cfg; /* global configuration */ +- u32 rst_idx; /* reset index */ +- u32 delay_irq; /* delay interrupt */ +- u32 irq_status; /* interrupt status */ +- u32 irq_mask; /* interrupt mask */ ++ u32 rx_ptr; /* rx base pointer */ ++ u32 rx_cnt_cfg; /* rx max count configuration */ ++ u32 pcrx_ptr; /* rx cpu pointer */ ++ u32 pdrx_ptr; /* rx dma pointer */ ++ u32 glo_cfg; /* global configuration */ ++ u32 rst_idx; /* reset index */ ++ u32 rx_cfg; /* rx dma configuration */ ++ u32 delay_irq; /* delay interrupt */ ++ u32 irq_status; /* interrupt status */ ++ u32 irq_mask; /* interrupt mask */ + u32 adma_rx_dbg0; +- u32 int_grp; ++ u32 int_grp; /* interrupt group1 */ ++ u32 int_grp3; /* interrupt group3 */ ++ u32 tx_delay_irq; /* tx delay interrupt */ ++ u32 rx_delay_irq; /* rx delay interrupt */ ++ u32 lro_ctrl_dw0; /* lro ctrl dword0 */ ++ u32 lro_alt_score_delta; /* lro auto-learn score delta */ ++ u32 lro_rx1_dly_int; /* lro rx ring1 delay interrupt */ ++ u32 lro_ring_dip_dw0; /* lro ring dip dword0 */ ++ u32 lro_ring_ctrl_dw1; /* lro ring ctrl dword1 */ ++ u32 lro_alt_dbg; /* lro auto-learn debug */ ++ u32 lro_alt_dbg_data; /* lro auto-learn debug data */ ++ u32 rss_glo_cfg; /* rss global configuration */ ++ + } pdma; + struct { + u32 qtx_cfg; /* tx queue configuration */ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0073-net-ethernet-mtk_eth_soc-add-rss-support.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0073-net-ethernet-mtk_eth_soc-add-rss-support.patch new file mode 100644 index 000000000..f52635836 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0073-net-ethernet-mtk_eth_soc-add-rss-support.patch @@ -0,0 +1,1300 @@ +From 75b7467317d1b9b3f7d92d8940182407ceb58fa5 Mon Sep 17 00:00:00 2001 +From: Mason Chang +Date: Wed, 19 Mar 2025 11:20:39 +0800 +Subject: [PATCH 73/84] net: ethernet: mtk_eth_soc: add rss support + +Add RSS support. + +We can adjust SMP affinity with the following command: +echo [CPU bitmap num] > /proc/irq/[virtual IRQ ID]/smp_affinity, +with interrupts evenly assigned to 4 CPUs, we were able to measure +an RX throughput of 7.3Gbps using iperf3 on the MT7988. Further +optimizations will be carried out in the future. + +The experimental command is as follows: +PC: iperf3 -c [IP] -P 10 +DUT: iperf3 -s + +The entire indirection table can be imagined as 128 buckets, we +can use the ethtool command to mark which RX ring we want to send +the packets in these buckets to. + +Show RSS RX ring parameters in indirection table and RSS hash key: +ethtool -x [interface] +Change RSS RX rings weight under uniform distribution: +ethtool --set-rxfh-indir [interface] equal [ring num] +Change RSS RX rings weight under non-uniform distribution: +ethtool --set-rxfh-indir [interface] weight [ring0 weight] +[ring1 weight] [ring2 weight] [ring3 weight] + +Signed-off-by: Mason Chang +Signed-off-by: Frank Wunderlich +--- +based on mtk-feed: +https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/autobuild/unified/filogic/24.10/files/target/linux/mediatek/patches-6.6/999-2710-net-ethernet-mtk_eth_soc-add-rss-support.patch + +changes not yet: +- dropped MTK_PDMA_INT | MTK_RSS from mt798[16] capability +- fix mtk_{get,set}_rxfh callback header +- add missing mtk_mac_assign_address +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 536 +++++++++++++++----- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++- + 2 files changed, 495 insertions(+), 137 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 98d700c55d73..18895e307824 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1308,6 +1308,7 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd, + if (mtk_is_netsys_v3_or_greater(eth)) { + rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); + rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); ++ rxd->rxd7 = READ_ONCE(dma_rxd->rxd7); + } + + return true; +@@ -1875,47 +1876,9 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + } + +-static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth) ++static void mtk_update_rx_cpu_idx(struct mtk_eth *eth, struct mtk_rx_ring *ring) + { +- int i; +- struct mtk_rx_ring *ring; +- int idx; +- +- if (!eth->hwlro) +- return ð->rx_ring[0]; +- +- for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) { +- struct mtk_rx_dma *rxd; +- +- ring = ð->rx_ring[i]; +- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); +- rxd = ring->dma + idx * eth->soc->rx.desc_size; +- if (rxd->rxd2 & RX_DMA_DONE) { +- ring->calc_idx_update = true; +- return ring; +- } +- } +- +- return NULL; +-} +- +-static void mtk_update_rx_cpu_idx(struct mtk_eth *eth) +-{ +- struct mtk_rx_ring *ring; +- int i; +- +- if (!eth->hwlro) { +- ring = ð->rx_ring[0]; +- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); +- } else { +- for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) { +- ring = ð->rx_ring[i]; +- if (ring->calc_idx_update) { +- ring->calc_idx_update = false; +- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); +- } +- } +- } ++ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); + } + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) +@@ -1946,7 +1909,7 @@ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, + return pp; + + err = __xdp_rxq_info_reg(xdp_q, eth->dummy_dev, id, +- eth->rx_napi.napi_id, PAGE_SIZE); ++ eth->rx_napi[id].napi.napi_id, PAGE_SIZE); + if (err < 0) + goto err_free_pp; + +@@ -2235,7 +2198,8 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + struct mtk_eth *eth) + { + struct dim_sample dim_sample = {}; +- struct mtk_rx_ring *ring; ++ struct mtk_napi *rx_napi = container_of(napi, struct mtk_napi, napi); ++ struct mtk_rx_ring *ring = rx_napi->rx_ring; + bool xdp_flush = false; + int idx; + struct sk_buff *skb; +@@ -2246,16 +2210,15 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + dma_addr_t dma_addr = DMA_MAPPING_ERROR; + int ppe_idx = 0; + ++ if (unlikely(!ring)) ++ goto rx_done; ++ + while (done < budget) { + unsigned int pktlen, *rxdcsum; + struct net_device *netdev; + u32 hash, reason; + int mac = 0; + +- ring = mtk_get_rx_ring(eth); +- if (unlikely(!ring)) +- goto rx_done; +- + idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); + rxd = ring->dma + idx * eth->soc->rx.desc_size; + data = ring->data[idx]; +@@ -2447,7 +2410,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + * we continue + */ + wmb(); +- mtk_update_rx_cpu_idx(eth); ++ mtk_update_rx_cpu_idx(eth, ring); + } + + eth->rx_packets += done; +@@ -2657,7 +2620,9 @@ static int mtk_napi_tx(struct napi_struct *napi, int budget) + + static int mtk_napi_rx(struct napi_struct *napi, int budget) + { +- struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); ++ struct mtk_napi *rx_napi = container_of(napi, struct mtk_napi, napi); ++ struct mtk_eth *eth = rx_napi->eth; ++ struct mtk_rx_ring *ring = rx_napi->rx_ring; + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int rx_done_total = 0; + +@@ -2666,7 +2631,7 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget) + do { + int rx_done; + +- mtk_w32(eth, eth->soc->rx.irq_done_mask, ++ mtk_w32(eth, MTK_RX_DONE_INT(ring->ring_no), + reg_map->pdma.irq_status); + rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth); + rx_done_total += rx_done; +@@ -2682,10 +2647,10 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget) + return budget; + + } while (mtk_r32(eth, reg_map->pdma.irq_status) & +- eth->soc->rx.irq_done_mask); ++ MTK_RX_DONE_INT(ring->ring_no)); + + if (napi_complete_done(napi, rx_done_total)) +- mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask); ++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(ring->ring_no)); + + return rx_done_total; + } +@@ -2931,6 +2896,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) + else + ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + + ring_no * MTK_QRX_OFFSET; ++ ring->ring_no = ring_no; + /* make sure that all changes to the dma ring are flushed before we + * continue + */ +@@ -2999,6 +2965,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_ + + static int mtk_hwlro_rx_init(struct mtk_eth *eth) + { ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int i; + u32 ring_ctrl_dw1 = 0, ring_ctrl_dw2 = 0, ring_ctrl_dw3 = 0; + u32 lro_ctrl_dw0 = 0, lro_ctrl_dw3 = 0; +@@ -3059,6 +3026,7 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + + static void mtk_hwlro_rx_uninit(struct mtk_eth *eth) + { ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int i; + u32 val; + +@@ -3085,6 +3053,7 @@ static void mtk_hwlro_rx_uninit(struct mtk_eth *eth) + + static void mtk_hwlro_val_ipaddr(struct mtk_eth *eth, int idx, __be32 ip) + { ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; + u32 reg_val; + + reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx)); +@@ -3100,6 +3069,7 @@ static void mtk_hwlro_val_ipaddr(struct mtk_eth *eth, int idx, __be32 ip) + + static void mtk_hwlro_inval_ipaddr(struct mtk_eth *eth, int idx) + { ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; + u32 reg_val; + + reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx)); +@@ -3235,6 +3205,111 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev, + return 0; + } + ++static u32 mtk_rss_indr_table(struct mtk_rss_params *rss_params, int index) ++{ ++ u32 val = 0; ++ int i; ++ ++ for (i = 16 * index; i < 16 * index + 16; i++) ++ val |= (rss_params->indirection_table[i] << (2 * (i % 16))); ++ ++ return val; ++} ++ ++static int mtk_rss_init(struct mtk_eth *eth) ++{ ++ const struct mtk_soc_data *soc = eth->soc; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ struct mtk_rss_params *rss_params = ð->rss_params; ++ static u8 hash_key[MTK_RSS_HASH_KEYSIZE] = { ++ 0xfa, 0x01, 0xac, 0xbe, 0x3b, 0xb7, 0x42, 0x6a, ++ 0x0c, 0xf2, 0x30, 0x80, 0xa3, 0x2d, 0xcb, 0x77, ++ 0xb4, 0x30, 0x7b, 0xae, 0xcb, 0x2b, 0xca, 0xd0, ++ 0xb0, 0x8f, 0xa3, 0x43, 0x3d, 0x25, 0x67, 0x41, ++ 0xc2, 0x0e, 0x5b, 0x25, 0xda, 0x56, 0x5a, 0x6d}; ++ u32 val; ++ int i; ++ ++ memcpy(rss_params->hash_key, hash_key, MTK_RSS_HASH_KEYSIZE); ++ ++ for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE; i++) ++ rss_params->indirection_table[i] = i % eth->soc->rss_num; ++ ++ if (soc->rx.desc_size == sizeof(struct mtk_rx_dma)) { ++ /* Set RSS rings to PSE modes */ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) { ++ val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(i)); ++ val |= MTK_RING_PSE_MODE; ++ mtk_w32(eth, val, MTK_LRO_CTRL_DW2_CFG(i)); ++ } ++ ++ /* Enable non-lro multiple rx */ ++ val = mtk_r32(eth, reg_map->pdma.lro_ctrl_dw0); ++ val |= MTK_NON_LRO_MULTI_EN; ++ mtk_w32(eth, val, reg_map->pdma.lro_ctrl_dw0); ++ ++ /* Enable RSS dly int supoort */ ++ val |= MTK_LRO_DLY_INT_EN; ++ mtk_w32(eth, val, reg_map->pdma.lro_ctrl_dw0); ++ } ++ ++ /* Hash Type */ ++ val = mtk_r32(eth, reg_map->pdma.rss_glo_cfg); ++ val |= MTK_RSS_IPV4_STATIC_HASH; ++ val |= MTK_RSS_IPV6_STATIC_HASH; ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Hash Key */ ++ for (i = 0; i < MTK_RSS_HASH_KEYSIZE / sizeof(u32); i++) ++ mtk_w32(eth, rss_params->hash_key[i], MTK_RSS_HASH_KEY_DW(i)); ++ ++ /* Select the size of indirection table */ ++ for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++) ++ mtk_w32(eth, mtk_rss_indr_table(rss_params, i), ++ MTK_RSS_INDR_TABLE_DW(i)); ++ ++ /* Pause */ ++ val |= MTK_RSS_CFG_REQ; ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Enable RSS */ ++ val |= MTK_RSS_EN; ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Release pause */ ++ val &= ~(MTK_RSS_CFG_REQ); ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Set perRSS GRP INT */ ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(1)), ++ MTK_RX_DONE_INT(MTK_RSS_RING(1)), reg_map->pdma.int_grp); ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(2)), ++ MTK_RX_DONE_INT(MTK_RSS_RING(2)), reg_map->pdma.int_grp + 0x4); ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(3)), ++ MTK_RX_DONE_INT(MTK_RSS_RING(3)), reg_map->pdma.int_grp3); ++ ++ return 0; ++} ++ ++static void mtk_rss_uninit(struct mtk_eth *eth) ++{ ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ u32 val; ++ ++ /* Pause */ ++ val = mtk_r32(eth, reg_map->pdma.rss_glo_cfg); ++ val |= MTK_RSS_CFG_REQ; ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Disable RSS */ ++ val &= ~(MTK_RSS_EN); ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++ ++ /* Release pause */ ++ val &= ~(MTK_RSS_CFG_REQ); ++ mtk_w32(eth, val, reg_map->pdma.rss_glo_cfg); ++} ++ + static netdev_features_t mtk_fix_features(struct net_device *dev, + netdev_features_t features) + { +@@ -3325,6 +3400,17 @@ static int mtk_dma_init(struct mtk_eth *eth) + return err; + } + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) { ++ err = mtk_rx_alloc(eth, MTK_RSS_RING(i), MTK_RX_FLAGS_NORMAL); ++ if (err) ++ return err; ++ } ++ err = mtk_rss_init(eth); ++ if (err) ++ return err; ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { + /* Enable random early drop and set drop threshold + * automatically +@@ -3371,6 +3457,12 @@ static void mtk_dma_free(struct mtk_eth *eth) + mtk_rx_clean(eth, ð->rx_ring[i], false); + } + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ mtk_rss_uninit(eth); ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) ++ mtk_rx_clean(eth, ð->rx_ring[MTK_RSS_RING(i)], true); ++ } ++ + for (i = 0; i < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); i++) { + kfree(eth->scratch_head[i]); + eth->scratch_head[i] = NULL; +@@ -3403,23 +3495,23 @@ static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) + schedule_work(ð->pending_work); + } + +-static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) ++static int mtk_get_irqs_fe(struct platform_device *pdev, struct mtk_eth *eth) + { + int i; + + /* future SoCs beginning with MT7988 should use named IRQs in dts */ +- eth->irq[MTK_FE_IRQ_TX] = platform_get_irq_byname_optional(pdev, "fe1"); +- eth->irq[MTK_FE_IRQ_RX] = platform_get_irq_byname_optional(pdev, "fe2"); +- if (eth->irq[MTK_FE_IRQ_TX] >= 0 && eth->irq[MTK_FE_IRQ_RX] >= 0) ++ eth->irq_fe[MTK_FE_IRQ_TX] = platform_get_irq_byname_optional(pdev, "fe1"); ++ eth->irq_fe[MTK_FE_IRQ_RX] = platform_get_irq_byname_optional(pdev, "fe2"); ++ if (eth->irq_fe[MTK_FE_IRQ_TX] >= 0 && eth->irq_fe[MTK_FE_IRQ_RX] >= 0) + return 0; + + /* only use legacy mode if platform_get_irq_byname_optional returned -ENXIO */ +- if (eth->irq[MTK_FE_IRQ_TX] != -ENXIO) +- return dev_err_probe(&pdev->dev, eth->irq[MTK_FE_IRQ_TX], ++ if (eth->irq_fe[MTK_FE_IRQ_TX] != -ENXIO) ++ return dev_err_probe(&pdev->dev, eth->irq_fe[MTK_FE_IRQ_TX], + "Error requesting FE TX IRQ\n"); + +- if (eth->irq[MTK_FE_IRQ_RX] != -ENXIO) +- return dev_err_probe(&pdev->dev, eth->irq[MTK_FE_IRQ_RX], ++ if (eth->irq_fe[MTK_FE_IRQ_RX] != -ENXIO) ++ return dev_err_probe(&pdev->dev, eth->irq_fe[MTK_FE_IRQ_RX], + "Error requesting FE RX IRQ\n"); + + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) +@@ -3434,14 +3526,14 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + for (i = 0; i < MTK_FE_IRQ_NUM; i++) { + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { + if (i == MTK_FE_IRQ_SHARED) +- eth->irq[MTK_FE_IRQ_SHARED] = platform_get_irq(pdev, i); ++ eth->irq_fe[MTK_FE_IRQ_SHARED] = platform_get_irq(pdev, i); + else +- eth->irq[i] = eth->irq[MTK_FE_IRQ_SHARED]; ++ eth->irq_fe[i] = eth->irq_fe[MTK_FE_IRQ_SHARED]; + } else { +- eth->irq[i] = platform_get_irq(pdev, i + 1); ++ eth->irq_fe[i] = platform_get_irq(pdev, i + 1); + } + +- if (eth->irq[i] < 0) { ++ if (eth->irq_fe[i] < 0) { + dev_err(&pdev->dev, "no IRQ%d resource found\n", i); + return -ENXIO; + } +@@ -3450,14 +3542,37 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) + return 0; + } + +-static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) ++static int mtk_get_irqs_pdma(struct platform_device *pdev, struct mtk_eth *eth) + { +- struct mtk_eth *eth = _eth; ++ char *rxring = "pdma0"; ++ int i; ++ ++ for (i = 0; i < MTK_PDMA_IRQ_NUM; i++) { ++ rxring[4] = '0' + i; ++ eth->irq_pdma[i] = platform_get_irq_byname(pdev, rxring); ++ if (eth->irq_pdma[i] < 0) ++ return eth->irq_pdma[i]; ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t mtk_handle_irq_rx(int irq, void *priv) ++{ ++ struct mtk_napi *rx_napi = priv; ++ struct mtk_eth *eth = rx_napi->eth; ++ struct mtk_rx_ring *ring = rx_napi->rx_ring; + + eth->rx_events++; +- if (likely(napi_schedule_prep(ð->rx_napi))) { +- mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask); +- __napi_schedule(ð->rx_napi); ++ if (unlikely(!(mtk_r32(eth, eth->soc->reg_map->pdma.irq_status) & ++ mtk_r32(eth, eth->soc->reg_map->pdma.irq_mask) & ++ MTK_RX_DONE_INT(ring->ring_no)))) ++ return IRQ_NONE; ++ ++ ++ if (likely(napi_schedule_prep(&rx_napi->napi))) { ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(ring->ring_no)); ++ __napi_schedule(&rx_napi->napi); + } + + return IRQ_HANDLED; +@@ -3482,10 +3597,10 @@ static irqreturn_t mtk_handle_irq(int irq, void *_eth) + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + + if (mtk_r32(eth, reg_map->pdma.irq_mask) & +- eth->soc->rx.irq_done_mask) { ++ MTK_RX_DONE_INT(0)) { + if (mtk_r32(eth, reg_map->pdma.irq_status) & +- eth->soc->rx.irq_done_mask) +- mtk_handle_irq_rx(irq, _eth); ++ MTK_RX_DONE_INT(0)) ++ mtk_handle_irq_rx(irq, ð->rx_napi[0]); + } + if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) { + if (mtk_r32(eth, reg_map->tx_irq_status) & MTK_TX_DONE_INT) +@@ -3502,10 +3617,10 @@ static void mtk_poll_controller(struct net_device *dev) + struct mtk_eth *eth = mac->hw; + + mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); +- mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask); +- mtk_handle_irq_rx(eth->irq[MTK_FE_IRQ_RX], dev); ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(0)); ++ mtk_handle_irq_rx(eth->irq_fe[MTK_FE_IRQ_RX], ð->rx_napi[0]); + mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); +- mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask); ++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(0)); + } + #endif + +@@ -3677,9 +3792,17 @@ static int mtk_open(struct net_device *dev) + } + + napi_enable(ð->tx_napi); +- napi_enable(ð->rx_napi); ++ napi_enable(ð->rx_napi[0].napi); + mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); +- mtk_rx_irq_enable(eth, soc->rx.irq_done_mask); ++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(0)); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) { ++ napi_enable(ð->rx_napi[MTK_RSS_RING(i)].napi); ++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(MTK_RSS_RING(i))); ++ } ++ } ++ + refcount_set(ð->dma_refcnt, 1); + } else { + refcount_inc(ð->dma_refcnt); +@@ -3764,9 +3887,16 @@ static int mtk_stop(struct net_device *dev) + mtk_gdm_config(eth, i, MTK_GDMA_DROP_ALL); + + mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); +- mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask); ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(0)); + napi_disable(ð->tx_napi); +- napi_disable(ð->rx_napi); ++ napi_disable(ð->rx_napi[0].napi); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) { ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(MTK_RSS_RING(i))); ++ napi_disable(ð->rx_napi[MTK_RSS_RING(i)].napi); ++ } ++ } + + cancel_work_sync(ð->rx_dim.work); + cancel_work_sync(ð->tx_dim.work); +@@ -3877,9 +4007,7 @@ static void mtk_dim_rx(struct work_struct *work) + dim->profile_ix); + spin_lock_bh(ð->dim_lock); + +- val = mtk_r32(eth, reg_map->pdma.delay_irq); +- val &= MTK_PDMA_DELAY_TX_MASK; +- val |= MTK_PDMA_DELAY_RX_EN; ++ val = MTK_PDMA_DELAY_RX_EN; + + cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK); + val |= cur << MTK_PDMA_DELAY_RX_PTIME_SHIFT; +@@ -3887,9 +4015,19 @@ static void mtk_dim_rx(struct work_struct *work) + cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); + val |= cur << MTK_PDMA_DELAY_RX_PINT_SHIFT; + +- mtk_w32(eth, val, reg_map->pdma.delay_irq); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) +- mtk_w32(eth, val, reg_map->qdma.delay_irq); ++ mtk_m32(eth, MTK_PDMA_DELAY_TX_MASK, ++ val << MTK_PDMA_DELAY_TX_PTIME_SHIFT, reg_map->qdma.delay_irq); ++ ++ if (eth->soc->rx.desc_size == sizeof(struct mtk_rx_dma)) { ++ mtk_m32(eth, MTK_PDMA_DELAY_RX_MASK, val, reg_map->pdma.delay_irq); ++ mtk_w32(eth, val, reg_map->pdma.lro_rx1_dly_int); ++ mtk_w32(eth, val, reg_map->pdma.lro_rx1_dly_int + 0x4); ++ mtk_w32(eth, val, reg_map->pdma.lro_rx1_dly_int + 0x8); ++ } else { ++ val = val | (val << MTK_PDMA_DELAY_RX_RING_SHIFT); ++ mtk_w32(eth, val, reg_map->pdma.rx_delay_irq); ++ } + + spin_unlock_bh(ð->dim_lock); + +@@ -3908,9 +4046,7 @@ static void mtk_dim_tx(struct work_struct *work) + dim->profile_ix); + spin_lock_bh(ð->dim_lock); + +- val = mtk_r32(eth, reg_map->pdma.delay_irq); +- val &= MTK_PDMA_DELAY_RX_MASK; +- val |= MTK_PDMA_DELAY_TX_EN; ++ val = MTK_PDMA_DELAY_TX_EN; + + cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK); + val |= cur << MTK_PDMA_DELAY_TX_PTIME_SHIFT; +@@ -3918,9 +4054,16 @@ static void mtk_dim_tx(struct work_struct *work) + cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); + val |= cur << MTK_PDMA_DELAY_TX_PINT_SHIFT; + +- mtk_w32(eth, val, reg_map->pdma.delay_irq); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) +- mtk_w32(eth, val, reg_map->qdma.delay_irq); ++ mtk_m32(eth, MTK_PDMA_DELAY_RX_MASK, ++ val >> MTK_PDMA_DELAY_TX_PTIME_SHIFT, reg_map->qdma.delay_irq); ++ ++ if (eth->soc->rx.desc_size == sizeof(struct mtk_rx_dma)) { ++ mtk_m32(eth, MTK_PDMA_DELAY_TX_MASK, val, reg_map->pdma.delay_irq); ++ } else { ++ mtk_w32(eth, val >> MTK_PDMA_DELAY_TX_PTIME_SHIFT, ++ reg_map->pdma.tx_delay_irq); ++ } + + spin_unlock_bh(ð->dim_lock); + +@@ -4183,6 +4326,25 @@ static void mtk_hw_reset_monitor_work(struct work_struct *work) + MTK_DMA_MONITOR_TIMEOUT); + } + ++static int mtk_napi_init(struct mtk_eth *eth) ++{ ++ struct mtk_napi *rx_napi = ð->rx_napi[0]; ++ int i; ++ ++ rx_napi->eth = eth; ++ rx_napi->rx_ring = ð->rx_ring[0]; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) { ++ rx_napi = ð->rx_napi[MTK_RSS_RING(i)]; ++ rx_napi->eth = eth; ++ rx_napi->rx_ring = ð->rx_ring[MTK_RSS_RING(i)]; ++ } ++ } ++ ++ return 0; ++} ++ + static int mtk_hw_init(struct mtk_eth *eth, bool reset) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -4272,12 +4434,12 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) + */ + val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); + mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); +- if (mtk_is_netsys_v1(eth)) { +- val = mtk_r32(eth, MTK_CDMP_IG_CTRL); +- mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); + ++ val = mtk_r32(eth, MTK_CDMP_IG_CTRL); ++ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); ++ ++ if (mtk_is_netsys_v1(eth)) + mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); +- } + + /* set interrupt delays based on current Net DIM sample */ + mtk_dim_rx(ð->rx_dim.work); +@@ -4288,11 +4450,17 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) + mtk_rx_irq_disable(eth, ~0); + + /* FE int grouping */ +- mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); +- mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4); ++ + mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp); +- mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4); +- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); ++ mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->qdma.int_grp + 4); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) { ++ mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP); ++ } else { ++ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); ++ mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->pdma.int_grp + 4); ++ mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); ++ } + + if (mtk_is_netsys_v3_or_greater(eth)) { + /* PSE dummy page mechanism */ +@@ -4730,6 +4898,8 @@ static void mtk_get_ethtool_stats(struct net_device *dev, + static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs) + { ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { +@@ -4737,6 +4907,9 @@ static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + if (dev->hw_features & NETIF_F_LRO) { + cmd->data = MTK_MAX_RX_RING_NUM; + ret = 0; ++ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ cmd->data = MTK_RX_RSS_NUM; ++ ret = 0; + } + break; + case ETHTOOL_GRXCLSRLCNT: +@@ -4811,6 +4984,72 @@ static int mtk_set_eee(struct net_device *dev, struct ethtool_keee *eee) + return phylink_ethtool_set_eee(mac->phylink, eee); + } + ++static u32 mtk_get_rxfh_key_size(struct net_device *dev) ++{ ++ return MTK_RSS_HASH_KEYSIZE; ++} ++ ++static u32 mtk_get_rxfh_indir_size(struct net_device *dev) ++{ ++ return MTK_RSS_MAX_INDIRECTION_TABLE; ++} ++ ++static int mtk_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, ++ u8 *hfunc) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ struct mtk_rss_params *rss_params = ð->rss_params; ++ int i; ++ ++ if (hfunc) ++ *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ ++ ++ if (key) { ++ memcpy(key, rss_params->hash_key, ++ sizeof(rss_params->hash_key)); ++ } ++ ++ if (indir) { ++ for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE; i++) ++ indir[i] = rss_params->indirection_table[i]; ++ } ++ ++ return 0; ++} ++ ++static int mtk_set_rxfh(struct net_device *dev, const u32 *indir, ++ const u8 *key, const u8 hfunc) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ struct mtk_rss_params *rss_params = ð->rss_params; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ int i; ++ ++ if (hfunc != ETH_RSS_HASH_NO_CHANGE && ++ hfunc != ETH_RSS_HASH_TOP) ++ return -EOPNOTSUPP; ++ ++ if (key) { ++ memcpy(rss_params->hash_key, key, ++ sizeof(rss_params->hash_key)); ++ for (i = 0; i < MTK_RSS_HASH_KEYSIZE / sizeof(u32); i++) ++ mtk_w32(eth, rss_params->hash_key[i], ++ MTK_RSS_HASH_KEY_DW(i)); ++ } ++ ++ if (indir) { ++ for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE; i++) ++ rss_params->indirection_table[i] = indir[i]; ++ for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++) ++ mtk_w32(eth, mtk_rss_indr_table(rss_params, i), ++ MTK_RSS_INDR_TABLE_DW(i)); ++ } ++ ++ return 0; ++} ++ + static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) + { +@@ -4845,6 +5084,10 @@ static const struct ethtool_ops mtk_ethtool_ops = { + .set_rxnfc = mtk_set_rxnfc, + .get_eee = mtk_get_eee, + .set_eee = mtk_set_eee, ++ .get_rxfh_key_size = mtk_get_rxfh_key_size, ++ .get_rxfh_indir_size = mtk_get_rxfh_indir_size, ++ .get_rxfh = mtk_get_rxfh, ++ .set_rxfh = mtk_set_rxfh, + }; + + static const struct net_device_ops mtk_netdev_ops = { +@@ -5073,7 +5316,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + eth->netdev[id]->features |= eth->soc->hw_features; + eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; + +- eth->netdev[id]->irq = eth->irq[MTK_FE_IRQ_SHARED]; ++ eth->netdev[id]->irq = eth->irq_fe[MTK_FE_IRQ_SHARED]; + eth->netdev[id]->dev.of_node = np; + + phylink = phylink_create(&mac->phylink_config, +@@ -5194,6 +5437,7 @@ static int mtk_probe(struct platform_device *pdev) + struct resource *res = NULL; + struct device_node *mac_np; + struct mtk_eth *eth; ++ char *irqname; + int err, i; + + eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); +@@ -5326,10 +5570,16 @@ static int mtk_probe(struct platform_device *pdev) + } + } + +- err = mtk_get_irqs(pdev, eth); ++ err = mtk_get_irqs_fe(pdev, eth); + if (err) + goto err_wed_exit; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) { ++ err = mtk_get_irqs_pdma(pdev, eth); ++ if (err) ++ goto err_wed_exit; ++ } ++ + for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { + eth->clks[i] = devm_clk_get(eth->dev, + mtk_clks_source_name[i]); +@@ -5372,23 +5622,56 @@ static int mtk_probe(struct platform_device *pdev) + } + } + ++ err = mtk_napi_init(eth); ++ if (err) ++ goto err_free_dev; ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { +- err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_SHARED], ++ err = devm_request_irq(eth->dev, eth->irq_fe[MTK_FE_IRQ_SHARED], + mtk_handle_irq, 0, + dev_name(eth->dev), eth); + } else { +- err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_TX], ++ irqname = devm_kasprintf(eth->dev, GFP_KERNEL, "%s TX", ++ dev_name(eth->dev)); ++ err = devm_request_irq(eth->dev, eth->irq_fe[MTK_FE_IRQ_TX], + mtk_handle_irq_tx, 0, +- dev_name(eth->dev), eth); ++ irqname, eth); + if (err) + goto err_free_dev; + +- err = devm_request_irq(eth->dev, eth->irq[MTK_FE_IRQ_RX], +- mtk_handle_irq_rx, 0, +- dev_name(eth->dev), eth); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) { ++ irqname = devm_kasprintf(eth->dev, GFP_KERNEL, "%s PDMA RX %d", ++ dev_name(eth->dev), 0); ++ err = devm_request_irq(eth->dev, eth->irq_pdma[0], ++ mtk_handle_irq_rx, IRQF_SHARED, ++ irqname, ð->rx_napi[0]); ++ if (err) ++ goto err_free_dev; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) { ++ irqname = devm_kasprintf(eth->dev, GFP_KERNEL, ++ "%s RSS RX %d", ++ dev_name(eth->dev), i); ++ err = devm_request_irq(eth->dev, ++ eth->irq_pdma[MTK_RSS_RING(i)], ++ mtk_handle_irq_rx, IRQF_SHARED, ++ irqname, ++ ð->rx_napi[MTK_RSS_RING(i)]); ++ if (err) ++ goto err_free_dev; ++ } ++ } ++ } else { ++ irqname = devm_kasprintf(eth->dev, GFP_KERNEL, "%s RX", ++ dev_name(eth->dev)); ++ err = devm_request_irq(eth->dev, eth->irq_fe[MTK_FE_IRQ_RX], ++ mtk_handle_irq_rx, 0, ++ irqname, ð->rx_napi[0]); ++ if (err) ++ goto err_free_dev; ++ } + } +- if (err) +- goto err_free_dev; + + /* No MT7628/88 support yet */ + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { +@@ -5429,7 +5712,7 @@ static int mtk_probe(struct platform_device *pdev) + } else + netif_info(eth, probe, eth->netdev[i], + "mediatek frame engine at 0x%08lx, irq %d\n", +- eth->netdev[i]->base_addr, eth->irq[MTK_FE_IRQ_SHARED]); ++ eth->netdev[i]->base_addr, eth->irq_fe[MTK_FE_IRQ_SHARED]); + } + + /* we run 2 devices on the same DMA ring so we need a dummy device +@@ -5442,7 +5725,13 @@ static int mtk_probe(struct platform_device *pdev) + goto err_unreg_netdev; + } + netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx); +- netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx); ++ netif_napi_add(eth->dummy_dev, ð->rx_napi[0].napi, mtk_napi_rx); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) ++ netif_napi_add(eth->dummy_dev, ð->rx_napi[MTK_RSS_RING(i)].napi, ++ mtk_napi_rx); ++ } + + platform_set_drvdata(pdev, eth); + schedule_delayed_work(ð->reset.monitor_work, +@@ -5486,7 +5775,12 @@ static void mtk_remove(struct platform_device *pdev) + mtk_hw_deinit(eth); + + netif_napi_del(ð->tx_napi); +- netif_napi_del(ð->rx_napi); ++ netif_napi_del(ð->rx_napi[0].napi); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { ++ for (i = 1; i < MTK_RX_RSS_NUM; i++) ++ netif_napi_del(ð->rx_napi[MTK_RSS_RING(i)].napi); ++ } + mtk_cleanup(eth); + free_netdev(eth->dummy_dev); + mtk_mdio_cleanup(eth); +@@ -5499,6 +5793,7 @@ static const struct mtk_soc_data mt2701_data = { + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, + .version = 1, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5508,7 +5803,6 @@ static const struct mtk_soc_data mt2701_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID, + .dma_size = MTK_DMA_SIZE(2K), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5527,6 +5821,7 @@ static const struct mtk_soc_data mt7621_data = { + .ppe_num = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5536,7 +5831,6 @@ static const struct mtk_soc_data mt7621_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID, + .dma_size = MTK_DMA_SIZE(2K), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5557,6 +5851,7 @@ static const struct mtk_soc_data mt7622_data = { + .hash_offset = 2, + .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5566,7 +5861,6 @@ static const struct mtk_soc_data mt7622_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID, + .dma_size = MTK_DMA_SIZE(2K), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5586,6 +5880,7 @@ static const struct mtk_soc_data mt7623_data = { + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .disable_pll_modes = true, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5595,7 +5890,6 @@ static const struct mtk_soc_data mt7623_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID, + .dma_size = MTK_DMA_SIZE(2K), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5612,6 +5906,7 @@ static const struct mtk_soc_data mt7629_data = { + .required_pctl = false, + .has_accounting = true, + .version = 1, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5621,7 +5916,6 @@ static const struct mtk_soc_data mt7629_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID, + .dma_size = MTK_DMA_SIZE(2K), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5642,16 +5936,16 @@ static const struct mtk_soc_data mt7981_data = { + .hash_offset = 4, + .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, ++ .rss_num = 4, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma_v2), + .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, + .dma_len_offset = 8, +- .dma_size = MTK_DMA_SIZE(2K), ++ .dma_size = MTK_DMA_SIZE(4K), + .fq_dma_size = MTK_DMA_SIZE(2K), + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID_V2, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, +@@ -5672,6 +5966,7 @@ static const struct mtk_soc_data mt7986_data = { + .hash_offset = 4, + .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, ++ .rss_num = 4, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma_v2), + .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, +@@ -5681,7 +5976,6 @@ static const struct mtk_soc_data mt7986_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID_V2, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, +@@ -5702,20 +5996,20 @@ static const struct mtk_soc_data mt7988_data = { + .hash_offset = 4, + .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, ++ .rss_num = 4, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma_v2), + .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, + .dma_len_offset = 8, +- .dma_size = MTK_DMA_SIZE(2K), ++ .dma_size = MTK_DMA_SIZE(4K), + .fq_dma_size = MTK_DMA_SIZE(4K), + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma_v2), +- .irq_done_mask = MTK_RX_DONE_INT_V2, + .dma_l4_valid = RX_DMA_L4_VALID_V2, + .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, + .dma_len_offset = 8, +- .dma_size = MTK_DMA_SIZE(2K), ++ .dma_size = MTK_DMA_SIZE(1K), + }, + }; + +@@ -5726,6 +6020,7 @@ static const struct mtk_soc_data rt5350_data = { + .required_clks = MT7628_CLKS_BITMAP, + .required_pctl = false, + .version = 1, ++ .rss_num = 0, + .tx = { + .desc_size = sizeof(struct mtk_tx_dma), + .dma_max_len = MTK_TX_DMA_BUF_LEN, +@@ -5734,7 +6029,6 @@ static const struct mtk_soc_data rt5350_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .irq_done_mask = MTK_RX_DONE_INT, + .dma_l4_valid = RX_DMA_L4_VALID_PDMA, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index eb2328596c8b..a163a04bb927 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -77,6 +77,8 @@ + #define MTK_HW_LRO_BW_THRE 3000 + #define MTK_HW_LRO_REPLACE_DELTA 1000 + #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 ++#define MTK_RSS_HASH_KEYSIZE 40 ++#define MTK_RSS_MAX_INDIRECTION_TABLE 128 + + /* Frame Engine Global Configuration */ + #define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00) +@@ -98,6 +100,8 @@ + #define MTK_GDM1_AF BIT(28) + #define MTK_GDM2_AF BIT(29) + ++#define MTK_PDMA_IRQ_NUM (4) ++ + /* PDMA HW LRO Alter Flow Timer Register */ + #define MTK_PDMA_LRO_ALT_REFRESH_TIMER 0x1c + +@@ -180,7 +184,10 @@ + + /* PDMA HW LRO Control Registers */ + #define MTK_PDMA_LRO_CTRL_DW0 0x980 ++#define MTK_HW_LRO_RING_NUM (mtk_is_netsys_v3_or_greater(eth) ? 4 : 3) + #define MTK_LRO_EN BIT(0) ++#define MTK_NON_LRO_MULTI_EN BIT(2) ++#define MTK_LRO_DLY_INT_EN BIT(5) + #define MTK_L3_CKS_UPD_EN BIT(7) + #define MTK_L3_CKS_UPD_EN_V2 BIT(19) + #define MTK_LRO_ALT_PKT_CNT_MODE BIT(21) +@@ -199,6 +206,19 @@ + #define MTK_MULTI_EN BIT(10) + #define MTK_PDMA_SIZE_8DWORDS (1 << 4) + ++/* PDMA RSS Control Registers */ ++#define MTK_RX_NAPI_NUM (4) ++#define MTK_RX_RSS_NUM (eth->soc->rss_num) ++#define MTK_RSS_RING(x) (x) ++#define MTK_RSS_EN BIT(0) ++#define MTK_RSS_CFG_REQ BIT(2) ++#define MTK_RSS_IPV6_STATIC_HASH (0x7 << 8) ++#define MTK_RSS_IPV4_STATIC_HASH (0x7 << 12) ++#define MTK_RSS_HASH_KEY_DW(x) (reg_map->pdma.rss_glo_cfg + 0x20 + \ ++ ((x) * 0x4)) ++#define MTK_RSS_INDR_TABLE_DW(x) (reg_map->pdma.rss_glo_cfg + 0x50 + \ ++ ((x) * 0x4)) ++ + /* PDMA Global Configuration Register */ + #define MTK_PDMA_LRO_SDL 0x3000 + #define MTK_RX_CFG_SDL_OFFSET 16 +@@ -210,6 +230,7 @@ + /* PDMA Delay Interrupt Register */ + #define MTK_PDMA_DELAY_RX_MASK GENMASK(15, 0) + #define MTK_PDMA_DELAY_RX_EN BIT(15) ++#define MTK_PDMA_DELAY_RX_RING_SHIFT 16 + #define MTK_PDMA_DELAY_RX_PINT_SHIFT 8 + #define MTK_PDMA_DELAY_RX_PTIME_SHIFT 0 + +@@ -230,14 +251,12 @@ + #define MTK_RING_MYIP_VLD BIT(9) + + /* PDMA HW LRO Ring Control Registers */ +-#define MTK_LRO_RX_RING0_CTRL_DW1 0xb28 +-#define MTK_LRO_RX_RING0_CTRL_DW2 0xb2c +-#define MTK_LRO_RX_RING0_CTRL_DW3 0xb30 +-#define MTK_LRO_CTRL_DW1_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW1 + (x * 0x40)) +-#define MTK_LRO_CTRL_DW2_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW2 + (x * 0x40)) +-#define MTK_LRO_CTRL_DW3_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW3 + (x * 0x40)) ++#define MTK_LRO_CTRL_DW1_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + (x * 0x40)) ++#define MTK_LRO_CTRL_DW2_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x4 + (x * 0x40)) ++#define MTK_LRO_CTRL_DW3_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x8 + (x * 0x40)) + #define MTK_RING_AGE_TIME_L ((MTK_HW_LRO_AGE_TIME & 0x3ff) << 22) + #define MTK_RING_AGE_TIME_H ((MTK_HW_LRO_AGE_TIME >> 10) & 0x3f) ++#define MTK_RING_PSE_MODE (1 << 6) + #define MTK_RING_AUTO_LERAN_MODE (3 << 6) + #define MTK_RING_VLD BIT(8) + #define MTK_RING_MAX_AGG_TIME ((MTK_HW_LRO_AGG_TIME & 0xffff) << 10) +@@ -291,7 +310,20 @@ + #define FC_THRES_MIN 0x4444 + + /* QDMA Interrupt Status Register */ +-#define MTK_RX_DONE_DLY BIT(30) ++#define MTK_RX_DONE_INT_V1(ring_no) \ ++ ( \ ++ (ring_no) ? \ ++ BIT(24 + (ring_no)) : \ ++ BIT(30) \ ++ ) ++ ++#define MTK_RX_DONE_INT_V2(ring_no) BIT(24 + (ring_no)) ++ ++#define MTK_RX_DONE_INT(ring_no) \ ++ (mtk_is_netsys_v3_or_greater(eth) ? \ ++ MTK_RX_DONE_INT_V2(ring_no) : \ ++ MTK_RX_DONE_INT_V1(ring_no)) ++ + #define MTK_TX_DONE_DLY BIT(28) + #define MTK_RX_DONE_INT3 BIT(19) + #define MTK_RX_DONE_INT2 BIT(18) +@@ -301,11 +333,8 @@ + #define MTK_TX_DONE_INT2 BIT(2) + #define MTK_TX_DONE_INT1 BIT(1) + #define MTK_TX_DONE_INT0 BIT(0) +-#define MTK_RX_DONE_INT MTK_RX_DONE_DLY + #define MTK_TX_DONE_INT MTK_TX_DONE_DLY + +-#define MTK_RX_DONE_INT_V2 BIT(14) +- + #define MTK_CDM_TXFIFO_RDY BIT(7) + + /* QDMA Interrupt grouping registers */ +@@ -959,6 +988,7 @@ struct mtk_tx_ring { + struct mtk_tx_dma *dma_pdma; /* For MT7628/88 PDMA handling */ + dma_addr_t phys_pdma; + int cpu_idx; ++ bool in_sram; + }; + + /* PDMA rx ring mode */ +@@ -984,13 +1014,38 @@ struct mtk_rx_ring { + u16 buf_size; + u16 dma_size; + bool calc_idx_update; ++ bool in_sram; + u16 calc_idx; + u32 crx_idx_reg; ++ u32 ring_no; + /* page_pool */ + struct page_pool *page_pool; + struct xdp_rxq_info xdp_q; + }; + ++/* struct mtk_rss_params - This is the structure holding parameters ++ for the RSS ring ++ * @hash_key The element is used to record the ++ secret key for the RSS ring ++ * indirection_table The element is used to record the ++ indirection table for the RSS ring ++ */ ++struct mtk_rss_params { ++ u32 hash_key[MTK_RSS_HASH_KEYSIZE / sizeof(u32)]; ++ u8 indirection_table[MTK_RSS_MAX_INDIRECTION_TABLE]; ++}; ++ ++/* struct mtk_napi - This is the structure holding NAPI-related information, ++ * and a mtk_napi struct is binding to one interrupt group ++ * @napi: The NAPI struct ++ * @rx_ring: Pointer to the memory holding info about the RX ring ++ */ ++struct mtk_napi { ++ struct napi_struct napi; ++ struct mtk_eth *eth; ++ struct mtk_rx_ring *rx_ring; ++}; ++ + enum mkt_eth_capabilities { + MTK_RGMII_BIT = 0, + MTK_TRGMII_BIT, +@@ -1003,7 +1058,9 @@ enum mkt_eth_capabilities { + MTK_INFRA_BIT, + MTK_SHARED_SGMII_BIT, + MTK_HWLRO_BIT, ++ MTK_RSS_BIT, + MTK_SHARED_INT_BIT, ++ MTK_PDMA_INT_BIT, + MTK_TRGMII_MT7621_CLK_BIT, + MTK_QDMA_BIT, + MTK_SOC_MT7628_BIT, +@@ -1050,7 +1107,9 @@ enum mkt_eth_capabilities { + #define MTK_INFRA BIT_ULL(MTK_INFRA_BIT) + #define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT) + #define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT) ++#define MTK_RSS BIT_ULL(MTK_RSS_BIT) + #define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT) ++#define MTK_PDMA_INT BIT_ULL(MTK_PDMA_INT_BIT) + #define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT) + #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) + #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) +@@ -1160,18 +1219,19 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) + + #define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ + MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ + MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ + MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ + MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ +- MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) ++ MTK_QDMA | MTK_SRAM | MTK_PDMA_INT | MTK_RSS | \ ++ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1269,6 +1329,7 @@ struct mtk_reg_map { + struct mtk_soc_data { + const struct mtk_reg_map *reg_map; + u32 ana_rgc3; ++ u32 rss_num; + u64 caps; + u64 required_clks; + bool required_pctl; +@@ -1316,7 +1377,8 @@ struct mtk_soc_data { + * dummy for NAPI to work + * @netdev: The netdev instances + * @mac: Each netdev is linked to a physical MAC +- * @irq: The IRQ that we are using ++ * @irq_fe: Array of IRQs of the frame engine ++ * @irq_pdma: Array of IRQs of the PDMA used for RSS + * @msg_enable: Ethtool msg level + * @ethsys: The register map pointing at the range used to setup + * MII modes +@@ -1360,7 +1422,8 @@ struct mtk_eth { + struct net_device *dummy_dev; + struct net_device *netdev[MTK_MAX_DEVS]; + struct mtk_mac *mac[MTK_MAX_DEVS]; +- int irq[MTK_FE_IRQ_NUM]; ++ int irq_fe[MTK_FE_IRQ_NUM]; ++ int irq_pdma[MTK_PDMA_IRQ_NUM]; + u32 msg_enable; + unsigned long sysclk; + struct regmap *ethsys; +@@ -1373,7 +1436,8 @@ struct mtk_eth { + struct mtk_rx_ring rx_ring[MTK_MAX_RX_RING_NUM]; + struct mtk_rx_ring rx_ring_qdma; + struct napi_struct tx_napi; +- struct napi_struct rx_napi; ++ struct mtk_napi rx_napi[MTK_RX_NAPI_NUM]; ++ struct mtk_rss_params rss_params; + void *scratch_ring; + dma_addr_t phy_scratch_ring; + void *scratch_head[MTK_FQ_DMA_HEAD]; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0074-net-mediatek-mtk_eth_soc-drop-RSS-capabilty-for-mt79.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0074-net-mediatek-mtk_eth_soc-drop-RSS-capabilty-for-mt79.patch new file mode 100644 index 000000000..9c8422e2e --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0074-net-mediatek-mtk_eth_soc-drop-RSS-capabilty-for-mt79.patch @@ -0,0 +1,31 @@ +From 4a4061dcab5bf9a5b35bd51f7538cac720c9719d Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 12 Jul 2025 14:58:39 +0200 +Subject: [PATCH 74/84] net: mediatek: mtk_eth_soc: drop RSS capabilty for + mt798[16] + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index a163a04bb927..025f4a8119f7 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1219,11 +1219,11 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT) + + #define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ + MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0075-net-mtk_eth_soc-fix-mtk_-get-set-_rxfh-callback-head.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0075-net-mtk_eth_soc-fix-mtk_-get-set-_rxfh-callback-head.patch new file mode 100644 index 000000000..3231ba3e9 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0075-net-mtk_eth_soc-fix-mtk_-get-set-_rxfh-callback-head.patch @@ -0,0 +1,87 @@ +From c28e7f6075c7bd6e0dcf29cddd285ce4ec8ada85 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 20 Dec 2024 14:40:39 +0100 +Subject: [PATCH 75/84] net: mtk_eth_soc: fix mtk_{get,set}_rxfh callback + header + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 31 ++++++++++----------- + 1 file changed, 15 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 18895e307824..5d2cfd026935 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4994,32 +4994,31 @@ static u32 mtk_get_rxfh_indir_size(struct net_device *dev) + return MTK_RSS_MAX_INDIRECTION_TABLE; + } + +-static int mtk_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, +- u8 *hfunc) ++static int mtk_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + struct mtk_rss_params *rss_params = ð->rss_params; + int i; + +- if (hfunc) +- *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ ++ if (rxfh->hfunc) ++ rxfh->hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ + +- if (key) { +- memcpy(key, rss_params->hash_key, ++ if (rxfh->key) { ++ memcpy(rxfh->key, rss_params->hash_key, + sizeof(rss_params->hash_key)); + } + +- if (indir) { ++ if (rxfh->indir) { + for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE; i++) +- indir[i] = rss_params->indirection_table[i]; ++ rxfh->indir[i] = rss_params->indirection_table[i]; + } + + return 0; + } + +-static int mtk_set_rxfh(struct net_device *dev, const u32 *indir, +- const u8 *key, const u8 hfunc) ++static int mtk_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, ++ struct netlink_ext_ack *extack) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; +@@ -5027,21 +5026,21 @@ static int mtk_set_rxfh(struct net_device *dev, const u32 *indir, + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int i; + +- if (hfunc != ETH_RSS_HASH_NO_CHANGE && +- hfunc != ETH_RSS_HASH_TOP) ++ if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && ++ rxfh->hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + +- if (key) { +- memcpy(rss_params->hash_key, key, ++ if (rxfh->key) { ++ memcpy(rss_params->hash_key, rxfh->key, + sizeof(rss_params->hash_key)); + for (i = 0; i < MTK_RSS_HASH_KEYSIZE / sizeof(u32); i++) + mtk_w32(eth, rss_params->hash_key[i], + MTK_RSS_HASH_KEY_DW(i)); + } + +- if (indir) { ++ if (rxfh->indir) { + for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE; i++) +- rss_params->indirection_table[i] = indir[i]; ++ rss_params->indirection_table[i] = rxfh->indir[i]; + for (i = 0; i < MTK_RSS_MAX_INDIRECTION_TABLE / 16; i++) + mtk_w32(eth, mtk_rss_indr_table(rss_params, i), + MTK_RSS_INDR_TABLE_DW(i)); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0076-net-ethernet-mtk_eth_soc-Add-LRO-support.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0076-net-ethernet-mtk_eth_soc-Add-LRO-support.patch new file mode 100644 index 000000000..15d23f4fa --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0076-net-ethernet-mtk_eth_soc-Add-LRO-support.patch @@ -0,0 +1,514 @@ +From d1b69872d8379a4860bfd0eebcb9bcbb85c3686c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 21 Mar 2025 11:22:43 +0100 +Subject: [PATCH 76/84] net: ethernet: mtk_eth_soc: Add LRO support + +based on +https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/e5b6f723b733f1ddc613e9d9e8db7a82e0b42e5c +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 213 ++++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 47 +++-- + 2 files changed, 220 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 5d2cfd026935..799dc58e2581 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2819,7 +2819,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) + if (!ring->data) + return -ENOMEM; + +- if (mtk_page_pool_enabled(eth)) { ++ if (mtk_page_pool_enabled(eth) && rcu_access_pointer(eth->prog)) { + struct page_pool *pp; + + pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no, +@@ -2966,7 +2966,8 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_ + static int mtk_hwlro_rx_init(struct mtk_eth *eth) + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; +- int i; ++ const struct mtk_soc_data *soc = eth->soc; ++ int i, val; + u32 ring_ctrl_dw1 = 0, ring_ctrl_dw2 = 0, ring_ctrl_dw3 = 0; + u32 lro_ctrl_dw0 = 0, lro_ctrl_dw3 = 0; + +@@ -2987,7 +2988,7 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + ring_ctrl_dw2 |= MTK_RING_MAX_AGG_CNT_L; + ring_ctrl_dw3 |= MTK_RING_MAX_AGG_CNT_H; + +- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) { ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) { + mtk_w32(eth, ring_ctrl_dw1, MTK_LRO_CTRL_DW1_CFG(i)); + mtk_w32(eth, ring_ctrl_dw2, MTK_LRO_CTRL_DW2_CFG(i)); + mtk_w32(eth, ring_ctrl_dw3, MTK_LRO_CTRL_DW3_CFG(i)); +@@ -3009,8 +3010,22 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + mtk_w32(eth, (MTK_HW_LRO_TIMER_UNIT << 16) | MTK_HW_LRO_REFRESH_TIME, + MTK_PDMA_LRO_ALT_REFRESH_TIMER); + +- /* set HW LRO mode & the max aggregation count for rx packets */ +- lro_ctrl_dw3 |= MTK_ADMA_MODE | (MTK_HW_LRO_MAX_AGG_CNT & 0xff); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ val = mtk_r32(eth, reg_map->pdma.rx_cfg); ++ mtk_w32(eth, val | ((MTK_PDMA_LRO_SDL + MTK_MAX_RX_LENGTH) << ++ MTK_RX_CFG_SDL_OFFSET), reg_map->pdma.rx_cfg); ++ ++ lro_ctrl_dw0 |= MTK_PDMA_LRO_SDL << MTK_CTRL_DW0_SDL_OFFSET; ++ ++ /* enable cpu reason black list */ ++ lro_ctrl_dw0 |= MTK_LRO_CRSN_BNW; ++ ++ /* no use PPE cpu reason */ ++ mtk_w32(eth, 0xffffffff, MTK_PDMA_LRO_CTRL_DW1); ++ } else { ++ /* set HW LRO mode & the max aggregation count for rx packets */ ++ lro_ctrl_dw3 |= MTK_ADMA_MODE | (MTK_HW_LRO_MAX_AGG_CNT & 0xff); ++ } + + /* the minimal remaining room of SDL0 in RXD for lro aggregation */ + lro_ctrl_dw3 |= MTK_LRO_MIN_RXD_SDL; +@@ -3021,6 +3036,16 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + mtk_w32(eth, lro_ctrl_dw3, MTK_PDMA_LRO_CTRL_DW3); + mtk_w32(eth, lro_ctrl_dw0, MTK_PDMA_LRO_CTRL_DW0); + ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ i = (soc->rx.desc_size == sizeof(struct mtk_rx_dma_v2)) ? 1 : 0; ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)), ++ MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)), reg_map->pdma.int_grp); ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 1)), ++ MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 1)), reg_map->pdma.int_grp + 0x4); ++ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 2)), ++ MTK_RX_DONE_INT(MTK_HW_LRO_RING(i + 2)), reg_map->pdma.int_grp3); ++ } ++ + return 0; + } + +@@ -3044,7 +3069,7 @@ static void mtk_hwlro_rx_uninit(struct mtk_eth *eth) + } + + /* invalidate lro rings */ +- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) + mtk_w32(eth, 0, MTK_LRO_CTRL_DW2_CFG(i)); + + /* disable HW LRO */ +@@ -3093,6 +3118,64 @@ static int mtk_hwlro_get_ip_cnt(struct mtk_mac *mac) + return cnt; + } + ++static int mtk_hwlro_add_ipaddr_idx(struct net_device *dev, u32 ip4dst) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ u32 reg_val; ++ int i; ++ ++ /* check for duplicate IP address in the current DIP list */ ++ for (i = 1; i <= MTK_HW_LRO_DIP_NUM; i++) { ++ reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i)); ++ if (reg_val == ip4dst) ++ break; ++ } ++ ++ if (i < MTK_HW_LRO_DIP_NUM + 1) { ++ netdev_warn(dev, "Duplicate IP address at DIP(%d)!\n", i); ++ return -EEXIST; ++ } ++ ++ /* find out available DIP index */ ++ for (i = 1; i <= MTK_HW_LRO_DIP_NUM; i++) { ++ reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i)); ++ if (reg_val == 0UL) ++ break; ++ } ++ ++ if (i >= MTK_HW_LRO_DIP_NUM + 1) { ++ netdev_warn(dev, "DIP index is currently out of resource!\n"); ++ return -EBUSY; ++ } ++ ++ return i; ++} ++ ++static int mtk_hwlro_get_ipaddr_idx(struct net_device *dev, u32 ip4dst) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ u32 reg_val; ++ int i; ++ ++ /* find out DIP index that matches the given IP address */ ++ for (i = 1; i <= MTK_HW_LRO_DIP_NUM; i++) { ++ reg_val = mtk_r32(eth, MTK_LRO_DIP_DW0_CFG(i)); ++ if (reg_val == ip4dst) ++ break; ++ } ++ ++ if (i >= MTK_HW_LRO_DIP_NUM + 1) { ++ netdev_warn(dev, "DIP address is not exist!\n"); ++ return -ENOENT; ++ } ++ ++ return i; ++} ++ + static int mtk_hwlro_add_ipaddr(struct net_device *dev, + struct ethtool_rxnfc *cmd) + { +@@ -3101,15 +3184,19 @@ static int mtk_hwlro_add_ipaddr(struct net_device *dev, + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + int hwlro_idx; ++ u32 ip4dst; + + if ((fsp->flow_type != TCP_V4_FLOW) || + (!fsp->h_u.tcp_ip4_spec.ip4dst) || + (fsp->location > 1)) + return -EINVAL; + +- mac->hwlro_ip[fsp->location] = htonl(fsp->h_u.tcp_ip4_spec.ip4dst); +- hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + fsp->location; ++ ip4dst = htonl(fsp->h_u.tcp_ip4_spec.ip4dst); ++ hwlro_idx = mtk_hwlro_add_ipaddr_idx(dev, ip4dst); ++ if (hwlro_idx < 0) ++ return hwlro_idx; + ++ mac->hwlro_ip[fsp->location] = ip4dst; + mac->hwlro_ip_cnt = mtk_hwlro_get_ip_cnt(mac); + + mtk_hwlro_val_ipaddr(eth, hwlro_idx, mac->hwlro_ip[fsp->location]); +@@ -3125,13 +3212,17 @@ static int mtk_hwlro_del_ipaddr(struct net_device *dev, + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + int hwlro_idx; ++ u32 ip4dst; + + if (fsp->location > 1) + return -EINVAL; + +- mac->hwlro_ip[fsp->location] = 0; +- hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + fsp->location; ++ ip4dst = mac->hwlro_ip[fsp->location]; ++ hwlro_idx = mtk_hwlro_get_ipaddr_idx(dev, ip4dst); ++ if (hwlro_idx < 0) ++ return hwlro_idx; + ++ mac->hwlro_ip[fsp->location] = 0; + mac->hwlro_ip_cnt = mtk_hwlro_get_ip_cnt(mac); + + mtk_hwlro_inval_ipaddr(eth, hwlro_idx); +@@ -3139,6 +3230,24 @@ static int mtk_hwlro_del_ipaddr(struct net_device *dev, + return 0; + } + ++static void mtk_hwlro_netdev_enable(struct net_device *dev) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ int i, hwlro_idx; ++ ++ for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { ++ if (mac->hwlro_ip[i] == 0) ++ continue; ++ ++ hwlro_idx = mtk_hwlro_get_ipaddr_idx(dev, mac->hwlro_ip[i]); ++ if (hwlro_idx < 0) ++ continue; ++ ++ mtk_hwlro_val_ipaddr(eth, hwlro_idx, mac->hwlro_ip[i]); ++ } ++} ++ + static void mtk_hwlro_netdev_disable(struct net_device *dev) + { + struct mtk_mac *mac = netdev_priv(dev); +@@ -3146,8 +3255,14 @@ static void mtk_hwlro_netdev_disable(struct net_device *dev) + int i, hwlro_idx; + + for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { ++ if (mac->hwlro_ip[i] == 0) ++ continue; ++ ++ hwlro_idx = mtk_hwlro_get_ipaddr_idx(dev, mac->hwlro_ip[i]); ++ if (hwlro_idx < 0) ++ continue; ++ + mac->hwlro_ip[i] = 0; +- hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + i; + + mtk_hwlro_inval_ipaddr(eth, hwlro_idx); + } +@@ -3333,6 +3448,8 @@ static int mtk_set_features(struct net_device *dev, netdev_features_t features) + + if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) + mtk_hwlro_netdev_disable(dev); ++ else if ((diff & NETIF_F_LRO) && (features & NETIF_F_LRO)) ++ mtk_hwlro_netdev_enable(dev); + + return 0; + } +@@ -3390,8 +3507,8 @@ static int mtk_dma_init(struct mtk_eth *eth) + return err; + + if (eth->hwlro) { +- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) { +- err = mtk_rx_alloc(eth, i, MTK_RX_FLAGS_HWLRO); ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ err = mtk_rx_alloc(eth, MTK_HW_LRO_RING(i), MTK_RX_FLAGS_HWLRO); + if (err) + return err; + } +@@ -3453,8 +3570,8 @@ static void mtk_dma_free(struct mtk_eth *eth) + + if (eth->hwlro) { + mtk_hwlro_rx_uninit(eth); +- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) +- mtk_rx_clean(eth, ð->rx_ring[i], false); ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) ++ mtk_rx_clean(eth, ð->rx_ring[MTK_HW_LRO_RING(i)], false); + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { +@@ -3650,16 +3767,21 @@ static int mtk_start_dma(struct mtk_eth *eth) + val |= MTK_RX_BT_32DWORDS; + mtk_w32(eth, val, reg_map->qdma.glo_cfg); + +- mtk_w32(eth, +- MTK_RX_DMA_EN | rx_2b_offset | +- MTK_RX_BT_32DWORDS | MTK_MULTI_EN, +- reg_map->pdma.glo_cfg); ++ val = mtk_r32(eth, reg_map->pdma.glo_cfg); ++ val |= MTK_RX_DMA_EN | rx_2b_offset | ++ MTK_RX_BT_32DWORDS | MTK_MULTI_EN; ++ mtk_w32(eth, val, reg_map->pdma.glo_cfg); + } else { + mtk_w32(eth, MTK_TX_WB_DDONE | MTK_TX_DMA_EN | MTK_RX_DMA_EN | + MTK_MULTI_EN | MTK_PDMA_SIZE_8DWORDS, + reg_map->pdma.glo_cfg); + } + ++ if (eth->hwlro && mtk_is_netsys_v3_or_greater(eth)) { ++ val = mtk_r32(eth, reg_map->pdma.glo_cfg); ++ mtk_w32(eth, val | MTK_RX_DMA_LRO_EN, reg_map->pdma.glo_cfg); ++ } ++ + return 0; + } + +@@ -3803,6 +3925,13 @@ static int mtk_open(struct net_device *dev) + } + } + ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ napi_enable(ð->rx_napi[MTK_HW_LRO_RING(i)].napi); ++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i))); ++ } ++ } ++ + refcount_set(ð->dma_refcnt, 1); + } else { + refcount_inc(ð->dma_refcnt); +@@ -3898,6 +4027,14 @@ static int mtk_stop(struct net_device *dev) + } + } + ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i))); ++ napi_synchronize(ð->rx_napi[MTK_HW_LRO_RING(i)].napi); ++ napi_disable(ð->rx_napi[MTK_HW_LRO_RING(i)].napi); ++ } ++ } ++ + cancel_work_sync(ð->rx_dim.work); + cancel_work_sync(ð->tx_dim.work); + +@@ -4342,6 +4479,14 @@ static int mtk_napi_init(struct mtk_eth *eth) + } + } + ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ rx_napi = ð->rx_napi[MTK_HW_LRO_RING(i)]; ++ rx_napi->eth = eth; ++ rx_napi->rx_ring = ð->rx_ring[MTK_HW_LRO_RING(i)]; ++ } ++ } ++ + return 0; + } + +@@ -4905,7 +5050,7 @@ static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + if (dev->hw_features & NETIF_F_LRO) { +- cmd->data = MTK_MAX_RX_RING_NUM; ++ cmd->data = MTK_HW_LRO_RING_NUM; + ret = 0; + } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) { + cmd->data = MTK_RX_RSS_NUM; +@@ -5661,6 +5806,21 @@ static int mtk_probe(struct platform_device *pdev) + goto err_free_dev; + } + } ++ ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ irqname = devm_kasprintf(eth->dev, GFP_KERNEL, ++ "%s LRO RX %d", ++ dev_name(eth->dev), i); ++ err = devm_request_irq(eth->dev, ++ eth->irq_pdma[MTK_HW_LRO_IRQ(i)], ++ mtk_handle_irq_rx, IRQF_SHARED, ++ irqname, ++ ð->rx_napi[MTK_HW_LRO_RING(i)]); ++ if (err) ++ goto err_free_dev; ++ } ++ } + } else { + irqname = devm_kasprintf(eth->dev, GFP_KERNEL, "%s RX", + dev_name(eth->dev)); +@@ -5732,6 +5892,13 @@ static int mtk_probe(struct platform_device *pdev) + mtk_napi_rx); + } + ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) { ++ netif_napi_add(eth->dummy_dev, ð->rx_napi[MTK_HW_LRO_RING(i)].napi, ++ mtk_napi_rx); ++ } ++ } ++ + platform_set_drvdata(pdev, eth); + schedule_delayed_work(ð->reset.monitor_work, + MTK_DMA_MONITOR_TIMEOUT); +@@ -5780,6 +5947,12 @@ static void mtk_remove(struct platform_device *pdev) + for (i = 1; i < MTK_RX_RSS_NUM; i++) + netif_napi_del(ð->rx_napi[MTK_RSS_RING(i)].napi); + } ++ ++ if (eth->hwlro) { ++ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) ++ netif_napi_del(ð->rx_napi[MTK_HW_LRO_RING(i)].napi); ++ } ++ + mtk_cleanup(eth); + free_netdev(eth->dummy_dev); + mtk_mdio_cleanup(eth); +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 025f4a8119f7..f4f6ea355c52 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -36,7 +36,7 @@ + #define MTK_DMA_SIZE(x) (SZ_##x) + #define MTK_FQ_DMA_HEAD 32 + #define MTK_FQ_DMA_LENGTH 2048 +-#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN) ++#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN) + #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) + #define MTK_DMA_DUMMY_DESC 0xffffffff + #define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \ +@@ -64,10 +64,13 @@ + + #define MTK_QRX_OFFSET 0x10 + +-#define MTK_MAX_RX_RING_NUM 4 +-#define MTK_HW_LRO_DMA_SIZE 8 ++#define MTK_MAX_RX_RING_NUM (8) ++#define MTK_HW_LRO_DMA_SIZE (mtk_is_netsys_v3_or_greater(eth) ? 64 : 8) ++#define IS_HW_LRO_RING(ring_no) (mtk_is_netsys_v3_or_greater(eth) ? \ ++ (((ring_no) > 3) && ((ring_no) < 8)) : \ ++ (((ring_no) > 0) && ((ring_no) < 4))) + +-#define MTK_MAX_LRO_RX_LENGTH (4096 * 3) ++#define MTK_MAX_LRO_RX_LENGTH (4096 * 3 + MTK_MAX_RX_LENGTH) + #define MTK_MAX_LRO_IP_CNT 2 + #define MTK_HW_LRO_TIMER_UNIT 1 /* 20 us */ + #define MTK_HW_LRO_REFRESH_TIME 50000 /* 1 sec. */ +@@ -183,31 +186,35 @@ + #define MTK_CDMM_THRES 0x165c + + /* PDMA HW LRO Control Registers */ +-#define MTK_PDMA_LRO_CTRL_DW0 0x980 ++#define MTK_HW_LRO_DIP_NUM (mtk_is_netsys_v3_or_greater(eth) ? 4 : 3) + #define MTK_HW_LRO_RING_NUM (mtk_is_netsys_v3_or_greater(eth) ? 4 : 3) ++#define MTK_HW_LRO_RING(x) ((x) + (mtk_is_netsys_v3_or_greater(eth) ? 4 : 1)) ++#define MTK_HW_LRO_IRQ(x) ((x) + (mtk_is_netsys_v3_or_greater(eth) ? 0 : 1)) ++#define MTK_LRO_CRSN_BNW BIT((mtk_is_netsys_v3_or_greater(eth) ? 22 : 6)) + #define MTK_LRO_EN BIT(0) + #define MTK_NON_LRO_MULTI_EN BIT(2) + #define MTK_LRO_DLY_INT_EN BIT(5) +-#define MTK_L3_CKS_UPD_EN BIT(7) +-#define MTK_L3_CKS_UPD_EN_V2 BIT(19) ++#define MTK_L3_CKS_UPD_EN BIT(mtk_is_netsys_v3_or_greater(eth) ? 19 : 7) + #define MTK_LRO_ALT_PKT_CNT_MODE BIT(21) +-#define MTK_LRO_RING_RELINQUISH_REQ (0x7 << 26) +-#define MTK_LRO_RING_RELINQUISH_REQ_V2 (0xf << 24) +-#define MTK_LRO_RING_RELINQUISH_DONE (0x7 << 29) +-#define MTK_LRO_RING_RELINQUISH_DONE_V2 (0xf << 28) +- +-#define MTK_PDMA_LRO_CTRL_DW1 0x984 +-#define MTK_PDMA_LRO_CTRL_DW2 0x988 +-#define MTK_PDMA_LRO_CTRL_DW3 0x98c ++#define MTK_LRO_RING_RELINQUISH_REQ (mtk_is_netsys_v3_or_greater(eth) ? 0xf << 24 : 0x7 << 26) ++#define MTK_LRO_RING_RELINQUISH_DONE (mtk_is_netsys_v3_or_greater(eth) ? 0xf << 28 : 0x7 << 29) ++ ++#define MTK_PDMA_LRO_CTRL_DW0 (reg_map->pdma.lro_ctrl_dw0) ++#define MTK_PDMA_LRO_CTRL_DW1 (reg_map->pdma.lro_ctrl_dw0 + 0x04) ++#define MTK_PDMA_LRO_CTRL_DW2 (reg_map->pdma.lro_ctrl_dw0 + 0x08) ++#define MTK_PDMA_LRO_CTRL_DW3 (reg_map->pdma.lro_ctrl_dw0 + 0x0c) + #define MTK_ADMA_MODE BIT(15) + #define MTK_LRO_MIN_RXD_SDL (MTK_HW_LRO_SDL_REMAIN_ROOM << 16) + ++#define MTK_CTRL_DW0_SDL_OFFSET (3) ++#define MTK_CTRL_DW0_SDL_MASK BITS(3, 18) ++ + #define MTK_RX_DMA_LRO_EN BIT(8) + #define MTK_MULTI_EN BIT(10) + #define MTK_PDMA_SIZE_8DWORDS (1 << 4) + + /* PDMA RSS Control Registers */ +-#define MTK_RX_NAPI_NUM (4) ++#define MTK_RX_NAPI_NUM (8) + #define MTK_RX_RSS_NUM (eth->soc->rss_num) + #define MTK_RSS_RING(x) (x) + #define MTK_RSS_EN BIT(0) +@@ -243,11 +250,10 @@ + #define MTK_PDMA_DELAY_PTIME_MASK 0xff + + /* PDMA HW LRO Alter Flow Delta Register */ +-#define MTK_PDMA_LRO_ALT_SCORE_DELTA 0xa4c ++#define MTK_PDMA_LRO_ALT_SCORE_DELTA (reg_map->pdma.lro_alt_score_delta) + + /* PDMA HW LRO IP Setting Registers */ +-#define MTK_LRO_RX_RING0_DIP_DW0 0xb04 +-#define MTK_LRO_DIP_DW0_CFG(x) (MTK_LRO_RX_RING0_DIP_DW0 + (x * 0x40)) ++#define MTK_LRO_DIP_DW0_CFG(x) (reg_map->pdma.lro_ring_dip_dw0 + (x * 0x40)) + #define MTK_RING_MYIP_VLD BIT(9) + + /* PDMA HW LRO Ring Control Registers */ +@@ -1231,7 +1237,7 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ + MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ + MTK_QDMA | MTK_SRAM | MTK_PDMA_INT | MTK_RSS | \ +- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2) ++ MTK_HWLRO | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1512,6 +1518,7 @@ struct mtk_mac { + + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; ++extern u32 mtk_hwlro_stats_ebl; + + static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) + { +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0077-readme-add-README.md-for-RSS-LRO.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0077-readme-add-README.md-for-RSS-LRO.patch new file mode 100644 index 000000000..2452d5acc --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0077-readme-add-README.md-for-RSS-LRO.patch @@ -0,0 +1,101 @@ +From 0d853dd76392d669385fd472c1154c2a818ae2e6 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 10 Jun 2025 23:28:00 +0200 +Subject: [PATCH 77/84] readme: add README.md for RSS/LRO + +--- + README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 82 insertions(+) + create mode 100644 README.md + +diff --git a/README.md b/README.md +new file mode 100644 +index 000000000000..f6b88d4d502a +--- /dev/null ++++ b/README.md +@@ -0,0 +1,82 @@ ++# RSS / LRO ++ ++HW-acceleration for ending traffic. ++For routed traffic PPE is needed and hw offloading in nftables. ++Bridged traffic may need addional changes (openwrt use bridger utility). ++ ++## RSS ++ ++(Receive Side Scaling) ++ ++using 4 additional IRQ for spreading load ++ ++cat /proc/interrupts | grep ethernet ++ ++echo 1 > /proc/irq/105/smp_affinity ++echo 2 > /proc/irq/106/smp_affinity ++echo 4 > /proc/irq/107/smp_affinity ++echo 8 > /proc/irq/108/smp_affinity ++ ++moving tx frame-engine irq to different cpu (here 3rd) ++echo 4 > /proc/irq/103/smp_affinity ++ ++disable RPS (Receive Packet Steering) for all macs: ++echo 0 > /sys/devices/platform/soc/15100000.ethernet/net/eth0/queues/rx-0/rps_cpus ++ ++pay attention on iperf-version (iperf 3.17 is ok, 3.12 is not) ++ ++traffic must be created using multiple streams so that it can be splitted, so use multithreaded iperf3 ++ ++on R4: ++bin/iperf3 -s ++ ++on the other side: ++iperf3 -c 192.168.1.1 -i 1 -P 4 ++ ++you should reach ~9.3 GBit/s ++ ++and see spreading load over CPU cores ++ ++root@bpi-r4-phy-8G:~# cat /proc/interrupts | grep eth ++103: 20 198366 0 0 GICv3 229 Level 15100000.ethernet ++105: 3611 0 0 0 GICv3 221 Level 15100000.ethernet, 15100000.ethernet ++106: 2 6842 0 0 GICv3 222 Level 15100000.ethernet, 15100000.ethernet ++107: 4 0 27643 0 GICv3 223 Level 15100000.ethernet, 15100000.ethernet ++108: 3 0 0 27925 GICv3 224 Level 15100000.ethernet, 15100000.ethernet ++ ++using the default iperf3 from debian bookworm (3.12) results in only 6.7GBit/s ++ ++## LRO ++(Large Receive Offload) ++ ++Add HW LRO RX rule: ++ ++ethtool -N [interface] flow-type tcp4 dst-ip [IP] action 0 loc [0/1] ++ ++Delete HW LRO RX rule: ++ ++ethtool -N [interface] delete [0/1] ++ ++Enable/Disable HW LRO rule: ++ ++ethtool -K [interface] lro [on | off] ++ ++Show the current offload features: ++ ++ethtool -k [interface] ++ ++example: ++ ++ethtool -N eth2 flow-type tcp4 dst-ip 192.168.1.1 action 0 loc 0 ++ethtool -K eth2 lro on ++ethtool -k eth2 ++ ++using iperf instead of iperf3! ++ ++verify with propritary debugfs ++Enable HW LRO rings ++echo 4 1 > /proc/mtketh/hw_lro_auto_tlb ++Enable HW LRO statistics ++echo 5 1 > /proc/mtketh/hw_lro_auto_tlb ++ ++cat /proc/mtketh/hw_lro_stats +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0078-net-ethernet-mtk_eth_soc-support-forced-reset-contro.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0078-net-ethernet-mtk_eth_soc-support-forced-reset-contro.patch new file mode 100644 index 000000000..242a5d8d5 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0078-net-ethernet-mtk_eth_soc-support-forced-reset-contro.patch @@ -0,0 +1,61 @@ +From ad2f0a1e65bd58dee78804dc28736ff616381356 Mon Sep 17 00:00:00 2001 +From: Bo-Cun Chen +Date: Wed, 27 Nov 2024 10:16:27 +0800 +Subject: [PATCH 78/84] net: ethernet: mtk_eth_soc: support forced reset + control + +Without this patch, users are unable to control the forced reset +through the proprietary debugfs. + +Signed-off-by: Bo-Cun Chen +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 799dc58e2581..730146eb322e 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3609,7 +3609,8 @@ static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) + eth->netdev[mac->id]->stats.tx_errors++; + netif_err(eth, tx_err, dev, "transmit timed out\n"); + +- schedule_work(ð->pending_work); ++ if (atomic_read(ð->reset.force)) ++ schedule_work(ð->pending_work); + } + + static int mtk_get_irqs_fe(struct platform_device *pdev, struct mtk_eth *eth) +@@ -4455,7 +4456,7 @@ static void mtk_hw_reset_monitor_work(struct work_struct *work) + goto out; + + /* DMA stuck checks */ +- if (mtk_hw_check_dma_hang(eth)) ++ if (mtk_hw_check_dma_hang(eth) && atomic_read(ð->reset.force)) + schedule_work(ð->pending_work); + + out: +@@ -5617,6 +5618,7 @@ static int mtk_probe(struct platform_device *pdev) + + eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + INIT_WORK(ð->rx_dim.work, mtk_dim_rx); ++ atomic_set(ð->reset.force, 0); + INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); + + eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index f4f6ea355c52..14c3ce16f733 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1479,6 +1479,7 @@ struct mtk_eth { + + struct { + struct delayed_work monitor_work; ++ atomic_t force; + u32 wdidx; + u8 wdma_hang_count; + u8 qdma_hang_count; +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0079-net-mediatek-add-proprietary-debugfs.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0079-net-mediatek-add-proprietary-debugfs.patch new file mode 100644 index 000000000..1ac6251b4 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0079-net-mediatek-add-proprietary-debugfs.patch @@ -0,0 +1,3007 @@ +From 3e9c1d3f9d6001378c48848925bbd263b5107c1a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 15 Jan 2025 20:00:57 +0100 +Subject: [PATCH 79/84] net: mediatek: add proprietary debugfs + +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:355:5: warning: no previous prototype for 'mt798x_iomap' [-Wmissing-prototypes] + 355 | int mt798x_iomap(void) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:375:5: warning: no previous prototype for 'mt798x_iounmap' [-Wmissing-prototypes] + 375 | int mt798x_iounmap(void) + | ^~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:384:6: warning: no previous prototype for 'mt7530_mdio_w32' [-Wmissing-prototypes] + 384 | void mt7530_mdio_w32(struct mtk_eth *eth, u16 reg, u32 val) + | ^~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:399:5: warning: no previous prototype for 'mt7530_mdio_r32' [-Wmissing-prototypes] + 399 | u32 mt7530_mdio_r32(struct mtk_eth *eth, u32 reg) + | ^~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:420:6: warning: no previous prototype for 'mtk_switch_w32' [-Wmissing-prototypes] + 420 | void mtk_switch_w32(struct mtk_eth *eth, u32 val, unsigned int reg) + | ^~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:426:5: warning: no previous prototype for 'mtk_switch_r32' [-Wmissing-prototypes] + 426 | u32 mtk_switch_r32(struct mtk_eth *eth, unsigned int reg) + | ^~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'mtketh_debugfs_reset': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:680:39: error: 'struct ' has no member named 'force' + 680 | atomic_set(ð->reset.force, 0); + | ^ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:683:44: error: 'struct ' has no member named 'force' + 683 | if (atomic_read(ð->reset.force)) + | ^ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:689:39: error: 'struct ' has no member named 'force' + 689 | atomic_set(ð->reset.force, 1); + | ^ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:782:6: warning: no previous prototype for 'mii_mgr_read_combine' [-Wmissing-prototypes] + 782 | void mii_mgr_read_combine(struct mtk_eth *eth, u32 phy_addr, u32 phy_register, + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:792:6: warning: no previous prototype for 'mii_mgr_write_combine' [-Wmissing-prototypes] + 792 | void mii_mgr_write_combine(struct mtk_eth *eth, u16 phy_addr, u16 phy_register, + | ^~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:991:6: warning: no previous prototype for 'dump_each_port' [-Wmissing-prototypes] + 991 | void dump_each_port(struct seq_file *seq, struct mtk_eth *eth, u32 base) + | ^~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'dump_each_port': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1003:33: warning: suggest braces around empty body in an 'else' statement [-Wempty-body] + 1003 | ; + | ^ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1011:5: warning: no previous prototype for 'esw_cnt_read' [-Wmissing-prototypes] + 1011 | int esw_cnt_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1085:6: warning: no previous prototype for 'xfi_mib_dump' [-Wmissing-prototypes] + 1085 | void xfi_mib_dump(struct seq_file *seq, u32 gdm_id) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1111:5: warning: no previous prototype for 'xfi_cnt_read' [-Wmissing-prototypes] + 1111 | int xfi_cnt_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1144:5: warning: no previous prototype for 'tx_ring_read' [-Wmissing-prototypes] + 1144 | int tx_ring_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1190:5: warning: no previous prototype for 'hwtx_ring_read' [-Wmissing-prototypes] + 1190 | int hwtx_ring_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1230:5: warning: no previous prototype for 'rx_ring_read' [-Wmissing-prototypes] + 1230 | int rx_ring_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1282:5: warning: no previous prototype for 'dbg_regs_read' [-Wmissing-prototypes] + 1282 | int dbg_regs_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1482:9: warning: no previous prototype for 'hw_lro_stats_write' [-Wmissing-prototypes] + 1482 | ssize_t hw_lro_stats_write(struct file *file, const char __user *buffer, + | ^~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1501:5: warning: no previous prototype for 'hw_lro_stats_read_v1' [-Wmissing-prototypes] + 1501 | int hw_lro_stats_read_v1(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1598:5: warning: no previous prototype for 'hw_lro_stats_read_v2' [-Wmissing-prototypes] + 1598 | int hw_lro_stats_read_v2(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1705:5: warning: no previous prototype for 'hw_lro_stats_read_wrapper' [-Wmissing-prototypes] + 1705 | int hw_lro_stats_read_wrapper(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1730:5: warning: no previous prototype for 'hwlro_agg_cnt_ctrl' [-Wmissing-prototypes] + 1730 | int hwlro_agg_cnt_ctrl(int cnt) + | ^~~~~~~~~~~~~~~~~~ +In file included from /media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:29: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hwlro_agg_cnt_ctrl': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:263:42: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 263 | #define MTK_LRO_CTRL_DW2_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x4 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.h:118:37: note: in expansion of macro 'MTK_LRO_CTRL_DW2_CFG' + 118 | u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1736:17: note: in expansion of macro 'SET_PDMA_RXRING_MAX_AGG_CNT' + 1736 | SET_PDMA_RXRING_MAX_AGG_CNT(eth, i, cnt); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:263:42: note: each undeclared identifier is reported only once for each function it appears in + 263 | #define MTK_LRO_CTRL_DW2_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x4 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.h:118:37: note: in expansion of macro 'MTK_LRO_CTRL_DW2_CFG' + 118 | u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1736:17: note: in expansion of macro 'SET_PDMA_RXRING_MAX_AGG_CNT' + 1736 | SET_PDMA_RXRING_MAX_AGG_CNT(eth, i, cnt); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1741:5: warning: no previous prototype for 'hwlro_agg_time_ctrl' [-Wmissing-prototypes] + 1741 | int hwlro_agg_time_ctrl(int time) + | ^~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hwlro_agg_time_ctrl': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:263:42: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 263 | #define MTK_LRO_CTRL_DW2_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x4 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.h:131:36: note: in expansion of macro 'MTK_LRO_CTRL_DW2_CFG' + 131 | u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1747:17: note: in expansion of macro 'SET_PDMA_RXRING_AGG_TIME' + 1747 | SET_PDMA_RXRING_AGG_TIME(eth, i, time); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1752:5: warning: no previous prototype for 'hwlro_age_time_ctrl' [-Wmissing-prototypes] + 1752 | int hwlro_age_time_ctrl(int time) + | ^~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hwlro_age_time_ctrl': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:262:42: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 262 | #define MTK_LRO_CTRL_DW1_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.h:139:37: note: in expansion of macro 'MTK_LRO_CTRL_DW1_CFG' + 139 | u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW1_CFG(x)); \ + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1758:17: note: in expansion of macro 'SET_PDMA_RXRING_AGE_TIME' + 1758 | SET_PDMA_RXRING_AGE_TIME(eth, i, time); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1762:5: warning: no previous prototype for 'hwlro_threshold_ctrl' [-Wmissing-prototypes] + 1762 | int hwlro_threshold_ctrl(int bandwidth) + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1771:5: warning: no previous prototype for 'hwlro_ring_enable_ctrl' [-Wmissing-prototypes] + 1771 | int hwlro_ring_enable_ctrl(int enable) + | ^~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hwlro_ring_enable_ctrl': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:263:42: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 263 | #define MTK_LRO_CTRL_DW2_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + 0x4 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.h:159:36: note: in expansion of macro 'MTK_LRO_CTRL_DW2_CFG' + 159 | u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1779:17: note: in expansion of macro 'SET_PDMA_RXRING_VALID' + 1779 | SET_PDMA_RXRING_VALID(eth, i, enable); + | ^~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: At top level: +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1784:5: warning: no previous prototype for 'hwlro_stats_enable_ctrl' [-Wmissing-prototypes] + 1784 | int hwlro_stats_enable_ctrl(int enable) + | ^~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1801:9: warning: no previous prototype for 'hw_lro_auto_tlb_write' [-Wmissing-prototypes] + 1801 | ssize_t hw_lro_auto_tlb_write(struct file *file, const char __user *buffer, + | ^~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1839:6: warning: no previous prototype for 'hw_lro_auto_tlb_dump_v1' [-Wmissing-prototypes] + 1839 | void hw_lro_auto_tlb_dump_v1(struct seq_file *seq, u32 index) + | ^~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1898:6: warning: no previous prototype for 'hw_lro_auto_tlb_dump_v2' [-Wmissing-prototypes] + 1898 | void hw_lro_auto_tlb_dump_v2(struct seq_file *seq, u32 index) + | ^~~~~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1969:5: warning: no previous prototype for 'hw_lro_auto_tlb_read' [-Wmissing-prototypes] + 1969 | int hw_lro_auto_tlb_read(struct seq_file *seq, void *v) + | ^~~~~~~~~~~~~~~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hw_lro_auto_tlb_read': +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.h:262:42: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 262 | #define MTK_LRO_CTRL_DW1_CFG(x) (reg_map->pdma.lro_ring_ctrl_dw1 + (x * 0x40)) + | ^~~~~~~ +/media/data_ext/git/kernel/BPI-R2-4.14/drivers/net/ethernet/mediatek/mtk_eth_dbg.c:2009:40: note: in expansion of macro 'MTK_LRO_CTRL_DW1_CFG' + 2009 | reg_op1 = mtk_r32(eth, MTK_LRO_CTRL_DW1_CFG(i)); + | ^~~~~~~~~~~~~~~~~~~~ +make[7]: *** [/media/data_ext/git/kernel/BPI-R2-4.14/scripts/Makefile.build:194: drivers/net/ethernet/mediatek/mtk_eth_dbg.o] Error 1 +make[7]: *** Waiting for unfinished jobs.... +make[6]: *** [/media/data_ext/git/kernel/BPI-R2-4.14/scripts/Makefile.build:440: drivers/net/ethernet/mediatek] Error 2 +make[5]: *** [/media/data_ext/git/kernel/BPI-R2-4.14/scripts/Makefile.build:440: drivers/net/ethernet] Error 2 +make[1]: Leaving directory '/media/data_ext/git/kernel/build' + +fix build-errors/warnings for mtk_eth_dbg + +these are still there: + +In file included from drivers/net/ethernet/mediatek/mtk_eth_dbg.c:29: +drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hwlro_threshold_ctrl': +drivers/net/ethernet/mediatek/mtk_eth_soc.h:204:34: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 204 | #define MTK_PDMA_LRO_CTRL_DW2 (reg_map->pdma.lro_ctrl_dw0 + 0x08) + | ^~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.h:152:36: note: in expansion of macro 'MTK_PDMA_LRO_CTRL_DW2' + 152 | u32 reg_val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW2); \ + | ^~~~~~~~~~~~~~~~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1769:9: note: in expansion of macro 'SET_PDMA_LRO_BW_THRESHOLD' + 1769 | SET_PDMA_LRO_BW_THRESHOLD(eth, bandwidth); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_soc.h:204:34: note: each undeclared identifier is reported only once for each function it appears in + 204 | #define MTK_PDMA_LRO_CTRL_DW2 (reg_map->pdma.lro_ctrl_dw0 + 0x08) + | ^~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.h:152:36: note: in expansion of macro 'MTK_PDMA_LRO_CTRL_DW2' + 152 | u32 reg_val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW2); \ + | ^~~~~~~~~~~~~~~~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1769:9: note: in expansion of macro 'SET_PDMA_LRO_BW_THRESHOLD' + 1769 | SET_PDMA_LRO_BW_THRESHOLD(eth, bandwidth); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hw_lro_auto_tlb_dump_v1': +drivers/net/ethernet/mediatek/mtk_eth_soc.h:202:34: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 202 | #define MTK_PDMA_LRO_CTRL_DW0 (reg_map->pdma.lro_ctrl_dw0) + | ^~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1868:26: note: in expansion of macro 'MTK_PDMA_LRO_CTRL_DW0' + 1868 | if (mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE) + | ^~~~~~~~~~~~~~~~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c: In function 'hw_lro_auto_tlb_dump_v2': +drivers/net/ethernet/mediatek/mtk_eth_soc.h:202:34: error: 'reg_map' undeclared (first use in this function); did you mean 'regmap'? + 202 | #define MTK_PDMA_LRO_CTRL_DW0 (reg_map->pdma.lro_ctrl_dw0) + | ^~~~~~~ +drivers/net/ethernet/mediatek/mtk_eth_dbg.c:1919:26: note: in expansion of macro 'MTK_PDMA_LRO_CTRL_DW0' + 1919 | if (mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE) + | ^~~~~~~~~~~~~~~~~~~~~ + +more fixes for mtk_eth_dbg after adding lro code + +net: mediatek: update propritary debugfs + +net: mediatek: add some missing values +--- + drivers/net/ethernet/mediatek/Makefile | 2 +- + drivers/net/ethernet/mediatek/mtk_eth_dbg.c | 2152 +++++++++++++++++++ + drivers/net/ethernet/mediatek/mtk_eth_dbg.h | 335 +++ + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 66 +- + 5 files changed, 2570 insertions(+), 7 deletions(-) + create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_dbg.c + create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_dbg.h + +diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile +index 03e008fbc859..b6b45ce24bd1 100644 +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -4,7 +4,7 @@ + # + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o +-mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o ++mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_eth_dbg.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/drivers/net/ethernet/mediatek/mtk_eth_dbg.c +new file mode 100644 +index 000000000000..28b04d52cb57 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_eth_dbg.c +@@ -0,0 +1,2152 @@ ++/* ++ * Copyright (C) 2018 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2009-2016 John Crispin ++ * Copyright (C) 2009-2016 Felix Fietkau ++ * Copyright (C) 2013-2016 Michael Lee ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mtk_eth_soc.h" ++#include "mtk_eth_dbg.h" ++#include "mtk_wed_regs.h" ++ ++u32 hw_lro_agg_num_cnt[MTK_MAX_RX_RING_NUM][MTK_HW_LRO_MAX_AGG_CNT + 1]; ++u32 hw_lro_agg_size_cnt[MTK_MAX_RX_RING_NUM][16]; ++u32 hw_lro_tot_agg_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_tot_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_agg_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_age_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_seq_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_timestamp_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 hw_lro_norule_flush_cnt[MTK_MAX_RX_RING_NUM]; ++u32 mtk_hwlro_stats_ebl; ++u32 dbg_show_level; ++ ++static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb; ++typedef int (*mtk_lro_dbg_func) (int par); ++ ++struct mtk_eth_debug { ++ struct dentry *root; ++ void __iomem *base; ++ int direct_access; ++}; ++ ++struct mtk_eth *g_eth; ++ ++struct mtk_eth_debug eth_debug; ++ ++static ssize_t qdma_sched_show(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_soc_data *soc = eth->soc; ++ long id = (long)file->private_data; ++ char *buf; ++ unsigned int len = 0, buf_len = 1500; ++ u32 qdma_tx_sch, sch_reg; ++ int enable, scheduling, max_rate, scheduler, i; ++ ssize_t ret_cnt; ++ ++ buf = kzalloc(buf_len, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ qdma_tx_sch = mtk_r32(eth, soc->reg_map->qdma.tx_sch_rate + (id >> 1) * 0x4); ++ else ++ qdma_tx_sch = mtk_r32(eth, soc->reg_map->qdma.tx_sch_rate); ++ ++ if (id & 0x1) ++ qdma_tx_sch >>= 16; ++ ++ qdma_tx_sch &= MTK_QDMA_TX_SCH; ++ enable = FIELD_GET(MTK_QDMA_TX_SCH_RATE_EN, qdma_tx_sch); ++ scheduling = FIELD_GET(MTK_QDMA_TX_SCH_MAX_WFQ, qdma_tx_sch); ++ max_rate = FIELD_GET(MTK_QDMA_TX_SCH_RATE_MAN, qdma_tx_sch); ++ qdma_tx_sch = FIELD_GET(MTK_QDMA_TX_SCH_RATE_EXP, qdma_tx_sch); ++ while (qdma_tx_sch--) ++ max_rate *= 10; ++ ++ len += scnprintf(buf + len, buf_len - len, ++ "EN\tScheduling\tMAX\tQueue#\n%d\t%s%16d\t", enable, ++ (scheduling == 1) ? "WRR" : "SP", max_rate); ++ ++ for (i = 0; i < MTK_QDMA_NUM_QUEUES; i++) { ++ mtk_w32(eth, (i / MTK_QTX_PER_PAGE), soc->reg_map->qdma.page); ++ sch_reg = mtk_r32(eth, soc->reg_map->qdma.qtx_sch + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ scheduler = FIELD_GET(MTK_QTX_SCH_TX_SEL_V2, sch_reg); ++ else ++ scheduler = FIELD_GET(MTK_QTX_SCH_TX_SEL, sch_reg); ++ if (id == scheduler) ++ len += scnprintf(buf + len, buf_len - len, "%d ", i); ++ } ++ ++ len += scnprintf(buf + len, buf_len - len, "\n"); ++ if (len > buf_len) ++ len = buf_len; ++ ++ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++ kfree(buf); ++ ++ return ret_cnt; ++} ++ ++static ssize_t qdma_sched_write(struct file *file, const char __user *buf, ++ size_t length, loff_t *offset) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_soc_data *soc = eth->soc; ++ long id = (long)file->private_data; ++ char line[64] = {0}, scheduling[32]; ++ int enable, rate, exp = 0, shift = 0; ++ size_t size; ++ u32 qdma_tx_sch, val = 0; ++ ++ if (length >= sizeof(line)) ++ return -EINVAL; ++ ++ if (copy_from_user(line, buf, length)) ++ return -EFAULT; ++ ++ if (sscanf(line, "%1d %3s %9d", &enable, scheduling, &rate) != 3) ++ return -EFAULT; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ if (rate > 10000000 || rate < 0) ++ return -EINVAL; ++ } else { ++ if (rate > 1000000 || rate < 0) ++ return -EINVAL; ++ } ++ ++ while (rate > 127) { ++ rate /= 10; ++ exp++; ++ } ++ ++ line[length] = '\0'; ++ ++ if (enable) ++ val |= MTK_QDMA_TX_SCH_RATE_EN; ++ if (strcmp(scheduling, "sp") != 0) ++ val |= MTK_QDMA_TX_SCH_MAX_WFQ; ++ val |= FIELD_PREP(MTK_QDMA_TX_SCH_RATE_MAN, rate); ++ val |= FIELD_PREP(MTK_QDMA_TX_SCH_RATE_EXP, exp); ++ if (id & 0x1) ++ shift = 16; ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ qdma_tx_sch = mtk_r32(eth, soc->reg_map->qdma.tx_sch_rate + (id >> 1) * 0x4); ++ else ++ qdma_tx_sch = mtk_r32(eth, soc->reg_map->qdma.tx_sch_rate); ++ ++ qdma_tx_sch &= ~(MTK_QDMA_TX_SCH << shift); ++ qdma_tx_sch |= val << shift; ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ mtk_w32(eth, qdma_tx_sch, soc->reg_map->qdma.tx_sch_rate + (id >> 1) * 0x4); ++ else ++ mtk_w32(eth, qdma_tx_sch, soc->reg_map->qdma.tx_sch_rate); ++ ++ size = strlen(line); ++ *offset += size; ++ ++ return length; ++} ++ ++static const struct file_operations qdma_sched_fops = { ++ .open = simple_open, ++ .read = qdma_sched_show, ++ .write = qdma_sched_write, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t qdma_queue_show(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_soc_data *soc = eth->soc; ++ long id = (long)file->private_data; ++ char *buf; ++ unsigned int len = 0, buf_len = 1500; ++ u32 qtx_sch, qtx_cfg; ++ int scheduler; ++ int min_rate_en, min_rate, min_rate_exp; ++ int max_rate_en, max_weight, max_rate, max_rate_exp; ++ ssize_t ret_cnt; ++ ++ buf = kzalloc(buf_len, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ mtk_w32(eth, (id / MTK_QTX_PER_PAGE), soc->reg_map->qdma.page); ++ qtx_cfg = mtk_r32(eth, soc->reg_map->qdma.qtx_cfg + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ qtx_sch = mtk_r32(eth, soc->reg_map->qdma.qtx_sch + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ scheduler = FIELD_GET(MTK_QTX_SCH_TX_SEL_V2, qtx_sch); ++ else ++ scheduler = FIELD_GET(MTK_QTX_SCH_TX_SEL, qtx_sch); ++ ++ min_rate_en = FIELD_GET(MTK_QTX_SCH_MIN_RATE_EN, qtx_sch); ++ min_rate = FIELD_GET(MTK_QTX_SCH_MIN_RATE_MAN, qtx_sch); ++ min_rate_exp = FIELD_GET(MTK_QTX_SCH_MIN_RATE_EXP, qtx_sch); ++ max_rate_en = FIELD_GET(MTK_QTX_SCH_MAX_RATE_EN, qtx_sch); ++ max_weight = FIELD_GET(MTK_QTX_SCH_MAX_RATE_WEIGHT, qtx_sch); ++ max_rate = FIELD_GET(MTK_QTX_SCH_MAX_RATE_MAN, qtx_sch); ++ max_rate_exp = FIELD_GET(MTK_QTX_SCH_MAX_RATE_EXP, qtx_sch); ++ ++ while (min_rate_exp--) ++ min_rate *= 10; ++ ++ while (max_rate_exp--) ++ max_rate *= 10; ++ ++ len += scnprintf(buf + len, buf_len - len, ++ "scheduler: %d\nhw resv: %d\nsw resv: %d\n", scheduler, ++ (qtx_cfg >> 8) & 0xff, qtx_cfg & 0xff); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ /* Switch to debug mode */ ++ mtk_m32(eth, MTK_MIB_ON_QTX_CFG, MTK_MIB_ON_QTX_CFG, soc->reg_map->qdma.qtx_mib_if); ++ mtk_m32(eth, MTK_VQTX_MIB_EN, MTK_VQTX_MIB_EN, soc->reg_map->qdma.qtx_mib_if); ++ qtx_cfg = mtk_r32(eth, soc->reg_map->qdma.qtx_cfg + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ qtx_sch = mtk_r32(eth, soc->reg_map->qdma.qtx_sch + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ len += scnprintf(buf + len, buf_len - len, ++ "packet count: %u\n", qtx_cfg); ++ len += scnprintf(buf + len, buf_len - len, ++ "packet drop: %u\n\n", qtx_sch); ++ ++ /* Recover to normal mode */ ++ mtk_m32(eth, MTK_MIB_ON_QTX_CFG, 0, soc->reg_map->qdma.qtx_mib_if); ++ mtk_m32(eth, MTK_VQTX_MIB_EN, 0, soc->reg_map->qdma.qtx_mib_if); ++ } ++ ++ len += scnprintf(buf + len, buf_len - len, ++ " EN RATE WEIGHT\n"); ++ len += scnprintf(buf + len, buf_len - len, ++ "----------------------------\n"); ++ len += scnprintf(buf + len, buf_len - len, ++ "max%5d%9d%9d\n", max_rate_en, max_rate, max_weight); ++ len += scnprintf(buf + len, buf_len - len, ++ "min%5d%9d -\n", min_rate_en, min_rate); ++ ++ if (len > buf_len) ++ len = buf_len; ++ ++ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++ kfree(buf); ++ ++ return ret_cnt; ++} ++ ++static ssize_t qdma_queue_write(struct file *file, const char __user *buf, ++ size_t length, loff_t *offset) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_soc_data *soc = eth->soc; ++ long id = (long)file->private_data; ++ char line[64] = {0}; ++ int max_enable, max_rate, max_exp = 0; ++ int min_enable, min_rate, min_exp = 0; ++ int weight; ++ int resv; ++ int scheduler; ++ size_t size; ++ u32 qtx_sch = 0, qtx_cfg = 0; ++ ++ mtk_w32(eth, (id / MTK_QTX_PER_PAGE), soc->reg_map->qdma.page); ++ if (length >= sizeof(line)) ++ return -EINVAL; ++ ++ if (copy_from_user(line, buf, length)) ++ return -EFAULT; ++ ++ if (sscanf(line, "%d %d %d %d %d %d %d", &scheduler, &min_enable, &min_rate, ++ &max_enable, &max_rate, &weight, &resv) != 7) ++ return -EFAULT; ++ ++ line[length] = '\0'; ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ if (max_rate > 10000000 || max_rate < 0 || ++ min_rate > 10000000 || min_rate < 0) ++ return -EINVAL; ++ } else { ++ if (max_rate > 1000000 || max_rate < 0 || ++ min_rate > 1000000 || min_rate < 0) ++ return -EINVAL; ++ } ++ ++ while (max_rate > 127) { ++ max_rate /= 10; ++ max_exp++; ++ } ++ ++ while (min_rate > 127) { ++ min_rate /= 10; ++ min_exp++; ++ } ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_TX_SEL_V2, scheduler); ++ else ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_TX_SEL, scheduler); ++ ++ if (min_enable) ++ qtx_sch |= MTK_QTX_SCH_MIN_RATE_EN; ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, min_rate); ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, min_exp); ++ if (max_enable) ++ qtx_sch |= MTK_QTX_SCH_MAX_RATE_EN; ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, weight); ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, max_rate); ++ qtx_sch |= FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, max_exp); ++ mtk_w32(eth, qtx_sch, soc->reg_map->qdma.qtx_sch + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ ++ qtx_cfg = mtk_r32(eth, soc->reg_map->qdma.qtx_cfg + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ qtx_cfg &= 0xffff0000; ++ qtx_cfg |= FIELD_PREP(MTK_QTX_CFG_HW_RESV, resv); ++ qtx_cfg |= FIELD_PREP(MTK_QTX_CFG_SW_RESV, resv); ++ mtk_w32(eth, qtx_cfg, soc->reg_map->qdma.qtx_cfg + ++ (id % MTK_QTX_PER_PAGE) * MTK_QTX_OFFSET); ++ ++ size = strlen(line); ++ *offset += size; ++ ++ return length; ++} ++ ++static const struct file_operations qdma_queue_fops = { ++ .open = simple_open, ++ .read = qdma_queue_show, ++ .write = qdma_queue_write, ++ .llseek = default_llseek, ++}; ++ ++static int mt798x_iomap(void) ++{ ++ struct device_node *np = NULL; ++ ++ np = of_find_node_by_name(NULL, "switch0"); ++ if (np) { ++ eth_debug.base = of_iomap(np, 0); ++ if (!eth_debug.base) { ++ pr_err("of_iomap failed\n"); ++ of_node_put(np); ++ return -ENOMEM; ++ } ++ ++ of_node_put(np); ++ eth_debug.direct_access = 1; ++ } ++ ++ return 0; ++} ++ ++static int mt798x_iounmap(void) ++{ ++ eth_debug.direct_access = 0; ++ if (eth_debug.base) ++ iounmap(eth_debug.base); ++ ++ return 0; ++} ++ ++static void mt7530_mdio_w32(struct mtk_eth *eth, u16 reg, u32 val) ++{ ++ mutex_lock(ð->mii_bus->mdio_lock); ++ ++ if (eth_debug.direct_access) ++ __raw_writel(val, eth_debug.base + reg); ++ else { ++ _mtk_mdio_write_c22(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff); ++ _mtk_mdio_write_c22(eth, 0x1f, (reg >> 2) & 0xf, val & 0xffff); ++ _mtk_mdio_write_c22(eth, 0x1f, 0x10, val >> 16); ++ } ++ ++ mutex_unlock(ð->mii_bus->mdio_lock); ++} ++ ++static u32 mt7530_mdio_r32(struct mtk_eth *eth, u32 reg) ++{ ++ u16 high, low; ++ u32 ret; ++ ++ mutex_lock(ð->mii_bus->mdio_lock); ++ ++ if (eth_debug.direct_access) { ++ ret = __raw_readl(eth_debug.base + reg); ++ mutex_unlock(ð->mii_bus->mdio_lock); ++ return ret; ++ } ++ _mtk_mdio_write_c22(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff); ++ low = _mtk_mdio_read_c22(eth, 0x1f, (reg >> 2) & 0xf); ++ high = _mtk_mdio_read_c22(eth, 0x1f, 0x10); ++ ++ mutex_unlock(ð->mii_bus->mdio_lock); ++ ++ return (high << 16) | (low & 0xffff); ++} ++ ++void mtk_switch_w32(struct mtk_eth *eth, u32 val, unsigned int reg) ++{ ++ mtk_w32(eth, val, reg + 0x10000); ++} ++EXPORT_SYMBOL(mtk_switch_w32); ++ ++u32 mtk_switch_r32(struct mtk_eth *eth, unsigned int reg) ++{ ++ return mtk_r32(eth, reg + 0x10000); ++} ++EXPORT_SYMBOL(mtk_switch_r32); ++ ++static int mtketh_debug_show(struct seq_file *m, void *private) ++{ ++ struct mtk_eth *eth = m->private; ++ struct mtk_mac *mac = 0; ++ int i = 0; ++ ++ for (i = 0 ; i < MTK_MAX_DEVS ; i++) { ++ if (!eth->mac[i] || ++ of_phy_is_fixed_link(eth->mac[i]->of_node)) ++ continue; ++ mac = eth->mac[i]; ++/* FIXME */ ++/* ++ while (j < 30) { ++ d = _mtk_mdio_read_c22(eth, mac->phy_dev->addr, j); ++ ++ seq_printf(m, "phy=%d, reg=0x%08x, data=0x%08x\n", ++ mac->phy_dev->addr, j, d); ++ j++; ++ } ++*/ ++ } ++ return 0; ++} ++ ++static int mtketh_debug_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, mtketh_debug_show, inode->i_private); ++} ++ ++static const struct file_operations mtketh_debug_fops = { ++ .owner = THIS_MODULE, ++ .open = mtketh_debug_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int mtketh_mt7530sw_debug_show(struct seq_file *m, void *private) ++{ ++ struct mtk_eth *eth = m->private; ++ u32 offset, data; ++ int i; ++ struct mt7530_ranges { ++ u32 start; ++ u32 end; ++ } ranges[] = { ++ {0x0, 0xac}, ++ {0x1000, 0x10e0}, ++ {0x1100, 0x1140}, ++ {0x1200, 0x1240}, ++ {0x1300, 0x1340}, ++ {0x1400, 0x1440}, ++ {0x1500, 0x1540}, ++ {0x1600, 0x1640}, ++ {0x1800, 0x1848}, ++ {0x1900, 0x1948}, ++ {0x1a00, 0x1a48}, ++ {0x1b00, 0x1b48}, ++ {0x1c00, 0x1c48}, ++ {0x1d00, 0x1d48}, ++ {0x1e00, 0x1e48}, ++ {0x1f60, 0x1ffc}, ++ {0x2000, 0x212c}, ++ {0x2200, 0x222c}, ++ {0x2300, 0x232c}, ++ {0x2400, 0x242c}, ++ {0x2500, 0x252c}, ++ {0x2600, 0x262c}, ++ {0x3000, 0x3014}, ++ {0x30c0, 0x30f8}, ++ {0x3100, 0x3114}, ++ {0x3200, 0x3214}, ++ {0x3300, 0x3314}, ++ {0x3400, 0x3414}, ++ {0x3500, 0x3514}, ++ {0x3600, 0x3614}, ++ {0x4000, 0x40d4}, ++ {0x4100, 0x41d4}, ++ {0x4200, 0x42d4}, ++ {0x4300, 0x43d4}, ++ {0x4400, 0x44d4}, ++ {0x4500, 0x45d4}, ++ {0x4600, 0x46d4}, ++ {0x4f00, 0x461c}, ++ {0x7000, 0x7038}, ++ {0x7120, 0x7124}, ++ {0x7800, 0x7804}, ++ {0x7810, 0x7810}, ++ {0x7830, 0x7830}, ++ {0x7a00, 0x7a7c}, ++ {0x7b00, 0x7b04}, ++ {0x7e00, 0x7e04}, ++ {0x7ffc, 0x7ffc}, ++ }; ++ ++ if (!mt7530_exist(eth)) ++ return -EOPNOTSUPP; ++ ++ if ((!eth->mac[0] || !of_phy_is_fixed_link(eth->mac[0]->of_node)) && ++ (!eth->mac[1] || !of_phy_is_fixed_link(eth->mac[1]->of_node))) { ++ seq_puts(m, "no switch found\n"); ++ return 0; ++ } ++ ++ for (i = 0 ; i < ARRAY_SIZE(ranges) ; i++) { ++ for (offset = ranges[i].start; ++ offset <= ranges[i].end; offset += 4) { ++ data = mt7530_mdio_r32(eth, offset); ++ seq_printf(m, "mt7530 switch reg=0x%08x, data=0x%08x\n", ++ offset, data); ++ } ++ } ++ ++ return 0; ++} ++ ++static int mtketh_debug_mt7530sw_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, mtketh_mt7530sw_debug_show, inode->i_private); ++} ++ ++static const struct file_operations mtketh_debug_mt7530sw_fops = { ++ .owner = THIS_MODULE, ++ .open = mtketh_debug_mt7530sw_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static ssize_t mtketh_mt7530sw_debugfs_write(struct file *file, ++ const char __user *ptr, ++ size_t len, loff_t *off) ++{ ++ struct mtk_eth *eth = file->private_data; ++ char buf[32], *token, *p = buf; ++ unsigned long reg, value, phy; ++ int ret; ++ ++ if (!mt7530_exist(eth)) ++ return -EOPNOTSUPP; ++ ++ if (*off != 0) ++ return 0; ++ ++ if (len > sizeof(buf) - 1) ++ len = sizeof(buf) - 1; ++ ++ ret = strncpy_from_user(buf, ptr, len); ++ if (ret < 0) ++ return ret; ++ buf[len] = '\0'; ++ ++ token = strsep(&p, " "); ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)&phy)) ++ return -EINVAL; ++ ++ token = strsep(&p, " "); ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)®)) ++ return -EINVAL; ++ ++ token = strsep(&p, " "); ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)&value)) ++ return -EINVAL; ++ ++ pr_info("%s:phy=%d, reg=0x%lx, val=0x%lx\n", __func__, ++ 0x1f, reg, value); ++ mt7530_mdio_w32(eth, reg, value); ++ pr_info("%s:phy=%d, reg=0x%lx, val=0x%x confirm..\n", __func__, ++ 0x1f, reg, mt7530_mdio_r32(eth, reg)); ++ ++ return len; ++} ++ ++static ssize_t mtketh_debugfs_write(struct file *file, const char __user *ptr, ++ size_t len, loff_t *off) ++{ ++ struct mtk_eth *eth = file->private_data; ++ char buf[32], *token, *p = buf; ++ unsigned long reg, value, phy; ++ int ret; ++ ++ if (*off != 0) ++ return 0; ++ ++ if (len > sizeof(buf) - 1) ++ len = sizeof(buf) - 1; ++ ++ ret = strncpy_from_user(buf, ptr, len); ++ if (ret < 0) ++ return ret; ++ buf[len] = '\0'; ++ ++ token = strsep(&p, " "); ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)&phy)) ++ return -EINVAL; ++ ++ token = strsep(&p, " "); ++ ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)®)) ++ return -EINVAL; ++ ++ token = strsep(&p, " "); ++ ++ if (!token) ++ return -EINVAL; ++ if (kstrtoul(token, 16, (unsigned long *)&value)) ++ return -EINVAL; ++ ++ pr_info("%s:phy=%ld, reg=0x%lx, val=0x%lx\n", __func__, ++ phy, reg, value); ++ ++ _mtk_mdio_write_c22(eth, phy, reg, value); ++ ++ pr_info("%s:phy=%ld, reg=0x%lx, val=0x%x confirm..\n", __func__, ++ phy, reg, _mtk_mdio_read_c22(eth, phy, reg)); ++ ++ return len; ++} ++ ++static ssize_t mtketh_debugfs_reset(struct file *file, const char __user *ptr, ++ size_t len, loff_t *off) ++{ ++ struct mtk_eth *eth = file->private_data; ++ unsigned long dbg_level = 0; ++ char buf[8] = ""; ++ int count = len; ++ ++ len = min((size_t)count, sizeof(buf) - 1); ++ if (copy_from_user(buf, ptr, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (kstrtoul(buf, 0, &dbg_level)) ++ return -EINVAL; ++ ++ switch (dbg_level) { ++ case 0: ++ atomic_set(ð->reset.force, 0); ++ break; ++ case 1: ++ if (atomic_read(ð->reset.force)) ++ schedule_work(ð->pending_work); ++ else ++ pr_info(" stat:disable\n"); ++ break; ++ case 2: ++ atomic_set(ð->reset.force, 1); ++ break; ++ default: ++ pr_info("Usage: echo [level] > /sys/kernel/debug/mtketh/reset\n"); ++ pr_info("Commands: [level]\n"); ++ pr_info(" 0 disable FE force reset\n"); ++ pr_info(" 1 trigger FE and WDMA force reset\n"); ++ pr_info(" 2 enable FE force reset\n"); ++ break; ++ } ++ ++ return count; ++} ++ ++static const struct file_operations fops_reg_w = { ++ .owner = THIS_MODULE, ++ .open = simple_open, ++ .write = mtketh_debugfs_write, ++ .llseek = noop_llseek, ++}; ++ ++static const struct file_operations fops_eth_reset = { ++ .owner = THIS_MODULE, ++ .open = simple_open, ++ .write = mtketh_debugfs_reset, ++ .llseek = noop_llseek, ++}; ++ ++static const struct file_operations fops_mt7530sw_reg_w = { ++ .owner = THIS_MODULE, ++ .open = simple_open, ++ .write = mtketh_mt7530sw_debugfs_write, ++ .llseek = noop_llseek, ++}; ++ ++void mtketh_debugfs_exit(struct mtk_eth *eth) ++{ ++ debugfs_remove_recursive(eth_debug.root); ++} ++ ++int mtketh_debugfs_init(struct mtk_eth *eth) ++{ ++ char name[16]; ++ int i, ret = 0; ++ ++ eth_debug.root = debugfs_create_dir("mtketh", NULL); ++ if (!eth_debug.root) { ++ dev_notice(eth->dev, "%s:err at %d\n", __func__, __LINE__); ++ ret = -ENOMEM; ++ } ++ ++ debugfs_create_file("phy_regs", 0444, ++ eth_debug.root, eth, &mtketh_debug_fops); ++ debugfs_create_file("phy_reg_w", 0200, ++ eth_debug.root, eth, &fops_reg_w); ++ debugfs_create_file("reset", 0444, ++ eth_debug.root, eth, &fops_eth_reset); ++ if (mt7530_exist(eth)) { ++ debugfs_create_file("mt7530sw_regs", 0444, ++ eth_debug.root, eth, ++ &mtketh_debug_mt7530sw_fops); ++ debugfs_create_file("mt7530sw_reg_w", 0200, ++ eth_debug.root, eth, ++ &fops_mt7530sw_reg_w); ++ } ++ ++ for (i = 0; i < (mtk_is_netsys_v2_or_greater(eth) ? 4 : 2); i++) { ++ ret = snprintf(name, sizeof(name), "qdma_sch%d", i); ++ if (ret != strlen(name)) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ debugfs_create_file(name, 0444, eth_debug.root, (void *)(uintptr_t)i, ++ &qdma_sched_fops); ++ } ++ ++ for (i = 0; i < MTK_QDMA_NUM_QUEUES; i++) { ++ ret = snprintf(name, sizeof(name), "qdma_txq%d", i); ++ if (ret != strlen(name)) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ debugfs_create_file(name, 0444, eth_debug.root, (void *)(uintptr_t)i, ++ &qdma_queue_fops); ++ } ++ ++ return 0; ++ ++err: ++ debugfs_remove_recursive(eth_debug.root); ++ return ret; ++} ++ ++static void mii_mgr_read_combine(struct mtk_eth *eth, u32 phy_addr, u32 phy_register, ++ u32 *read_data) ++{ ++ if (mt7530_exist(eth) && phy_addr == 31) ++ *read_data = mt7530_mdio_r32(eth, phy_register); ++ ++ else ++ *read_data = mdiobus_read(eth->mii_bus, phy_addr, phy_register); ++} ++ ++static void mii_mgr_write_combine(struct mtk_eth *eth, u16 phy_addr, u16 phy_register, ++ u32 write_data) ++{ ++ if (mt7530_exist(eth) && phy_addr == 31) ++ mt7530_mdio_w32(eth, phy_register, write_data); ++ ++ else ++ mdiobus_write(eth->mii_bus, phy_addr, phy_register, write_data); ++} ++ ++static void mii_mgr_read_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data) ++{ ++ *data = mdiobus_c45_read(eth->mii_bus, port, devad, reg); ++} ++ ++static void mii_mgr_write_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data) ++{ ++ mdiobus_c45_write(eth->mii_bus, port, devad, reg, data); ++} ++ ++int mtk_do_priv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ struct mtk_mii_ioctl_data mii; ++ struct mtk_esw_reg reg; ++ u16 val; ++ ++ switch (cmd) { ++ case MTKETH_MII_READ: ++ if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii))) ++ goto err_copy; ++ mii_mgr_read_combine(eth, mii.phy_id, mii.reg_num, ++ &mii.val_out); ++ if (copy_to_user(ifr->ifr_data, &mii, sizeof(mii))) ++ goto err_copy; ++ ++ return 0; ++ case MTKETH_MII_WRITE: ++ if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii))) ++ goto err_copy; ++ mii_mgr_write_combine(eth, mii.phy_id, mii.reg_num, ++ mii.val_in); ++ return 0; ++ case MTKETH_MII_READ_CL45: ++ if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii))) ++ goto err_copy; ++ mii_mgr_read_cl45(eth, ++ mdio_phy_id_prtad(mii.phy_id), ++ mdio_phy_id_devad(mii.phy_id), ++ mii.reg_num, ++ &val); ++ mii.val_out = val; ++ if (copy_to_user(ifr->ifr_data, &mii, sizeof(mii))) ++ goto err_copy; ++ ++ return 0; ++ case MTKETH_MII_WRITE_CL45: ++ if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii))) ++ goto err_copy; ++ val = mii.val_in; ++ mii_mgr_write_cl45(eth, ++ mdio_phy_id_prtad(mii.phy_id), ++ mdio_phy_id_devad(mii.phy_id), ++ mii.reg_num, ++ val); ++ return 0; ++ case MTKETH_ESW_REG_READ: ++ if (!mt7530_exist(eth)) ++ return -EOPNOTSUPP; ++ if (copy_from_user(®, ifr->ifr_data, sizeof(reg))) ++ goto err_copy; ++ if (reg.off > REG_ESW_MAX) ++ return -EINVAL; ++ reg.val = mtk_switch_r32(eth, reg.off); ++ ++ if (copy_to_user(ifr->ifr_data, ®, sizeof(reg))) ++ goto err_copy; ++ ++ return 0; ++ case MTKETH_ESW_REG_WRITE: ++ if (!mt7530_exist(eth)) ++ return -EOPNOTSUPP; ++ if (copy_from_user(®, ifr->ifr_data, sizeof(reg))) ++ goto err_copy; ++ if (reg.off > REG_ESW_MAX) ++ return -EINVAL; ++ mtk_switch_w32(eth, reg.val, reg.off); ++ ++ return 0; ++ default: ++ break; ++ } ++ ++ return -EOPNOTSUPP; ++err_copy: ++ return -EFAULT; ++} ++ ++static void gdm_reg_dump_v3(struct mtk_eth *eth, u32 gdm_id, u32 mib_base) ++{ ++ pr_info("| GDMA%d_RX_GBCNT : %010u (Rx Good Bytes) |\n", ++ gdm_id, mtk_r32(eth, mib_base)); ++ pr_info("| GDMA%d_RX_GPCNT : %010u (Rx Good Pkts) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x08)); ++ pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x10)); ++ pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x14)); ++ pr_info("| GDMA%d_RX_SERCNT : %010u (too short) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x18)); ++ pr_info("| GDMA%d_RX_LERCNT : %010u (too long) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x1C)); ++ pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x20)); ++ pr_info("| GDMA%d_RX_FCCNT : %010u (flow control) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x24)); ++ pr_info("| GDMA%d_RX_VDPCNT : %010u (VID drop) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x28)); ++ pr_info("| GDMA%d_RX_PFCCNT : %010u (priority flow control)\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x2C)); ++ pr_info("| GDMA%d_TX_GBCNT : %010u (Tx Good Bytes) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x40)); ++ pr_info("| GDMA%d_TX_GPCNT : %010u (Tx Good Pkts) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x48)); ++ pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x50)); ++ pr_info("| GDMA%d_TX_COLCNT : %010u (collision count)|\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x54)); ++ pr_info("| GDMA%d_TX_OERCNT : %010u (overflow error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x58)); ++ pr_info("| GDMA%d_TX_FCCNT : %010u (flow control) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x60)); ++ pr_info("| GDMA%d_TX_PFCCNT : %010u (priority flow control)\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x64)); ++ pr_info("| |\n"); ++} ++ ++static void gdm_reg_dump_v2(struct mtk_eth *eth, u32 gdm_id, u32 mib_base) ++{ ++ pr_info("| GDMA%d_RX_GBCNT : %010u (Rx Good Bytes) |\n", ++ gdm_id, mtk_r32(eth, mib_base)); ++ pr_info("| GDMA%d_RX_GPCNT : %010u (Rx Good Pkts) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x08)); ++ pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x10)); ++ pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x14)); ++ pr_info("| GDMA%d_RX_SERCNT : %010u (too short) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x18)); ++ pr_info("| GDMA%d_RX_LERCNT : %010u (too long) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x1C)); ++ pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x20)); ++ pr_info("| GDMA%d_RX_FCCNT : %010u (flow control) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x24)); ++ pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x28)); ++ pr_info("| GDMA%d_TX_COLCNT : %010u (collision count) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x2C)); ++ pr_info("| GDMA%d_TX_GBCNT : %010u (Tx Good Bytes) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x30)); ++ pr_info("| GDMA%d_TX_GPCNT : %010u (Tx Good Pkts) |\n", ++ gdm_id, mtk_r32(eth, mib_base + 0x38)); ++ pr_info("| |\n"); ++} ++ ++static void gdm_cnt_read(struct mtk_eth *eth) ++{ ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ struct mtk_hw_stats *hw_stats; ++ u32 i, mib_base; ++ ++ pr_info("\n <>\n"); ++ pr_info(" |\n"); ++ pr_info("+-----------------------------------------------+\n"); ++ pr_info("| <> |\n"); ++ pr_info("+-----------------------------------------------+\n"); ++ pr_info(" |\n"); ++ pr_info("+-----------------------------------------------+\n"); ++ pr_info("| <> |\n"); ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->mac[i] || !eth->mac[i]->hw_stats) ++ continue; ++ ++ hw_stats = eth->mac[i]->hw_stats; ++ ++ mib_base = reg_map->gdm1_cnt + hw_stats->reg_offset * i; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ gdm_reg_dump_v3(eth, i + 1, mib_base); ++ else ++ gdm_reg_dump_v2(eth, i + 1, mib_base); ++ } ++ ++ pr_info("+-----------------------------------------------+\n"); ++} ++ ++static void dump_each_port(struct seq_file *seq, struct mtk_eth *eth, u32 base) ++{ ++ u32 pkt_cnt = 0; ++ int i = 0; ++ ++ for (i = 0; i < 7; i++) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ if ((base == 0x402C) && (i == 6)) ++ base = 0x408C; ++ else if ((base == 0x408C) && (i == 6)) ++ base = 0x402C; ++ else { ++ }; ++ } ++ pkt_cnt = mt7530_mdio_r32(eth, (base) + (i * 0x100)); ++ seq_printf(seq, "%8u ", pkt_cnt); ++ } ++ seq_puts(seq, "\n"); ++} ++ ++static int esw_cnt_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ ++ gdm_cnt_read(eth); ++ ++ if (!mt7530_exist(eth)) ++ return 0; ++ ++ mt798x_iomap(); ++ ++ seq_printf(seq, "===================== %8s %8s %8s %8s %8s %8s %8s\n", ++ "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", ++ "Port6"); ++ seq_puts(seq, "Tx Drop Packet :"); ++ dump_each_port(seq, eth, 0x4000); ++ seq_puts(seq, "Tx CRC Error :"); ++ dump_each_port(seq, eth, 0x4004); ++ seq_puts(seq, "Tx Unicast Packet :"); ++ dump_each_port(seq, eth, 0x4008); ++ seq_puts(seq, "Tx Multicast Packet :"); ++ dump_each_port(seq, eth, 0x400C); ++ seq_puts(seq, "Tx Broadcast Packet :"); ++ dump_each_port(seq, eth, 0x4010); ++ seq_puts(seq, "Tx Collision Event :"); ++ dump_each_port(seq, eth, 0x4014); ++ seq_puts(seq, "Tx Pause Packet :"); ++ dump_each_port(seq, eth, 0x402C); ++ seq_puts(seq, "Rx Drop Packet :"); ++ dump_each_port(seq, eth, 0x4060); ++ seq_puts(seq, "Rx Filtering Packet :"); ++ dump_each_port(seq, eth, 0x4064); ++ seq_puts(seq, "Rx Unicast Packet :"); ++ dump_each_port(seq, eth, 0x4068); ++ seq_puts(seq, "Rx Multicast Packet :"); ++ dump_each_port(seq, eth, 0x406C); ++ seq_puts(seq, "Rx Broadcast Packet :"); ++ dump_each_port(seq, eth, 0x4070); ++ seq_puts(seq, "Rx Alignment Error :"); ++ dump_each_port(seq, eth, 0x4074); ++ seq_puts(seq, "Rx CRC Error :"); ++ dump_each_port(seq, eth, 0x4078); ++ seq_puts(seq, "Rx Undersize Error :"); ++ dump_each_port(seq, eth, 0x407C); ++ seq_puts(seq, "Rx Fragment Error :"); ++ dump_each_port(seq, eth, 0x4080); ++ seq_puts(seq, "Rx Oversize Error :"); ++ dump_each_port(seq, eth, 0x4084); ++ seq_puts(seq, "Rx Jabber Error :"); ++ dump_each_port(seq, eth, 0x4088); ++ seq_puts(seq, "Rx Pause Packet :"); ++ dump_each_port(seq, eth, 0x408C); ++ mt7530_mdio_w32(eth, 0x4fe0, 0xf0); ++ mt7530_mdio_w32(eth, 0x4fe0, 0x800000f0); ++ ++ seq_puts(seq, "\n"); ++ ++ mt798x_iounmap(); ++ ++ return 0; ++} ++ ++static int switch_count_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, esw_cnt_read, 0); ++} ++ ++static const struct proc_ops switch_count_fops = { ++ .proc_open = switch_count_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static void xfi_mib_dump(struct seq_file *seq, u32 gdm_id) ++{ ++ struct mtk_eth *eth = g_eth; ++ ++ PRINT_FORMATTED_XFI_MIB(seq, TX_PKT_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, TX_ETH_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, TX_PAUSE_CNT, GENMASK(15, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, TX_BYTE_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB64(seq, TX_UC_PKT_CNT); ++ PRINT_FORMATTED_XFI_MIB64(seq, TX_MC_PKT_CNT); ++ PRINT_FORMATTED_XFI_MIB64(seq, TX_BC_PKT_CNT); ++ ++ PRINT_FORMATTED_XFI_MIB(seq, RX_PKT_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_ETH_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_PAUSE_CNT, GENMASK(15, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_LEN_ERR_CNT, GENMASK(15, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_CRC_ERR_CNT, GENMASK(15, 0)); ++ PRINT_FORMATTED_XFI_MIB64(seq, RX_UC_PKT_CNT); ++ PRINT_FORMATTED_XFI_MIB64(seq, RX_MC_PKT_CNT); ++ PRINT_FORMATTED_XFI_MIB64(seq, RX_BC_PKT_CNT); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_UC_DROP_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_BC_DROP_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_MC_DROP_CNT, GENMASK(31, 0)); ++ PRINT_FORMATTED_XFI_MIB(seq, RX_ALL_DROP_CNT, GENMASK(31, 0)); ++} ++ ++static int xfi_cnt_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ int i; ++ ++ seq_puts(seq, "+------------------------------------+\n"); ++ seq_puts(seq, "| <> |\n"); ++ ++ for (i = MTK_GMAC2_ID; i < MTK_GMAC_ID_MAX; i++) { ++ xfi_mib_dump(seq, i); ++ mtk_m32(eth, 0x1, 0x1, MTK_XFI_MIB_BASE(i) + MTK_XFI_CNT_CTRL); ++ seq_puts(seq, "| |\n"); ++ } ++ ++ seq_puts(seq, "+------------------------------------+\n"); ++ ++ return 0; ++} ++ ++static int xfi_count_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, xfi_cnt_read, 0); ++} ++ ++static const struct proc_ops xfi_count_fops = { ++ .proc_open = xfi_count_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static struct proc_dir_entry *proc_tx_ring, *proc_hwtx_ring, *proc_rx_ring; ++ ++static int tx_ring_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ struct mtk_tx_ring *ring = &g_eth->tx_ring; ++ struct mtk_tx_dma_v2 *tx_ring; ++ int i = 0; ++ ++ seq_printf(seq, "free count = %d\n", (int)atomic_read(&ring->free_count)); ++ seq_printf(seq, "cpu next free: %d\n", ++ (int)(ring->next_free - (struct mtk_tx_dma *)ring->dma)); ++ seq_printf(seq, "cpu last free: %d\n", ++ (int)(ring->last_free - (struct mtk_tx_dma *)ring->dma)); ++ for (i = 0; i < eth->soc->tx.dma_size; i++) { ++ dma_addr_t tmp = ring->phys + ++ i * (dma_addr_t)eth->soc->tx.desc_size; ++ ++ tx_ring = ring->dma + i * eth->soc->tx.desc_size; ++ ++ seq_printf(seq, "%d (%pad): %08x %08x %08x %08x", i, &tmp, ++ tx_ring->txd1, tx_ring->txd2, ++ tx_ring->txd3, tx_ring->txd4); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, " %08x %08x %08x %08x", ++ tx_ring->txd5, tx_ring->txd6, ++ tx_ring->txd7, tx_ring->txd8); ++ } ++ ++ seq_puts(seq, "\n"); ++ } ++ ++ return 0; ++} ++ ++static int tx_ring_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, tx_ring_read, NULL); ++} ++ ++static const struct proc_ops tx_ring_fops = { ++ .proc_open = tx_ring_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static int hwtx_ring_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ struct mtk_tx_dma_v2 *hwtx_ring; ++ int i = 0; ++ ++ for (i = 0; i < MTK_QDMA_RING_SIZE; i++) { ++ dma_addr_t addr = eth->phy_scratch_ring + ++ i * (dma_addr_t)eth->soc->tx.desc_size; ++ ++ hwtx_ring = eth->scratch_ring + i * eth->soc->tx.desc_size; ++ ++ seq_printf(seq, "%d (%pad): %08x %08x %08x %08x", i, &addr, ++ hwtx_ring->txd1, hwtx_ring->txd2, ++ hwtx_ring->txd3, hwtx_ring->txd4); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, " %08x %08x %08x %08x", ++ hwtx_ring->txd5, hwtx_ring->txd6, ++ hwtx_ring->txd7, hwtx_ring->txd8); ++ } ++ ++ seq_puts(seq, "\n"); ++ } ++ ++ return 0; ++} ++ ++static int hwtx_ring_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, hwtx_ring_read, NULL); ++} ++ ++static const struct proc_ops hwtx_ring_fops = { ++ .proc_open = hwtx_ring_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static int rx_ring_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ struct mtk_rx_ring *ring = &g_eth->rx_ring[0]; ++ struct mtk_rx_dma_v2 *rx_ring; ++ int i = 0; ++ ++ seq_printf(seq, "next to read: %d\n", ++ NEXT_DESP_IDX(ring->calc_idx, eth->soc->rx.dma_size)); ++ for (i = 0; i < eth->soc->rx.dma_size; i++) { ++ rx_ring = ring->dma + i * eth->soc->rx.desc_size; ++ ++ seq_printf(seq, "%d: %08x %08x %08x %08x", i, ++ rx_ring->rxd1, rx_ring->rxd2, ++ rx_ring->rxd3, rx_ring->rxd4); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, " %08x %08x %08x %08x", ++ rx_ring->rxd5, rx_ring->rxd6, ++ rx_ring->rxd7, rx_ring->rxd8); ++ } ++ ++ seq_puts(seq, "\n"); ++ } ++ ++ return 0; ++} ++ ++static int rx_ring_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, rx_ring_read, NULL); ++} ++ ++static const struct proc_ops rx_ring_fops = { ++ .proc_open = rx_ring_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static inline u32 mtk_dbg_r32(u32 reg) ++{ ++ void __iomem *virt_reg; ++ u32 val; ++ ++ virt_reg = ioremap(reg, 32); ++ val = __raw_readl(virt_reg); ++ iounmap(virt_reg); ++ ++ return val; ++} ++ ++static int dbg_regs_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ ++ seq_puts(seq, " <>\n"); ++ ++ seq_printf(seq, "| FE_INT_STA : %08x |\n", ++ mtk_r32(eth, MTK_FE_INT_STATUS)); ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ seq_printf(seq, "| FE_INT_STA2 : %08x |\n", ++ mtk_r32(eth, MTK_FE_INT_STATUS2)); ++ ++ seq_printf(seq, "| PSE_FQFC_CFG : %08x |\n", ++ mtk_r32(eth, MTK_PSE_FQFC_CFG)); ++ seq_printf(seq, "| PSE_IQ_STA1 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x00)); ++ seq_printf(seq, "| PSE_IQ_STA2 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x04)); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, "| PSE_IQ_STA3 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x08)); ++ seq_printf(seq, "| PSE_IQ_STA4 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x0c)); ++ seq_printf(seq, "| PSE_IQ_STA5 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x10)); ++ seq_printf(seq, "| PSE_IQ_STA6 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x14)); ++ seq_printf(seq, "| PSE_IQ_STA7 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x18)); ++ seq_printf(seq, "| PSE_IQ_STA8 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_iq_sta + 0x1c)); ++ } ++ ++ seq_printf(seq, "| PSE_OQ_STA1 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x00)); ++ seq_printf(seq, "| PSE_OQ_STA2 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x04)); ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, "| PSE_OQ_STA3 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x08)); ++ seq_printf(seq, "| PSE_OQ_STA4 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x0c)); ++ seq_printf(seq, "| PSE_OQ_STA5 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x10)); ++ seq_printf(seq, "| PSE_OQ_STA6 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x14)); ++ seq_printf(seq, "| PSE_OQ_STA7 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x18)); ++ seq_printf(seq, "| PSE_OQ_STA8 : %08x |\n", ++ mtk_r32(eth, reg_map->pse_oq_sta + 0x1c)); ++ } ++ ++ seq_printf(seq, "| PDMA_CRX_IDX : %08x |\n", ++ mtk_r32(eth, reg_map->pdma.pcrx_ptr)); ++ seq_printf(seq, "| PDMA_DRX_IDX : %08x |\n", ++ mtk_r32(eth, reg_map->pdma.pdrx_ptr)); ++ seq_printf(seq, "| QDMA_CTX_IDX : %08x |\n", ++ mtk_r32(eth, reg_map->qdma.ctx_ptr)); ++ seq_printf(seq, "| QDMA_DTX_IDX : %08x |\n", ++ mtk_r32(eth, reg_map->qdma.dtx_ptr)); ++ seq_printf(seq, "| QDMA_FQ_CNT : %08x |\n", ++ mtk_r32(eth, reg_map->qdma.fq_count)); ++ seq_printf(seq, "| QDMA_FWD_CNT : %08x |\n", ++ mtk_r32(eth, reg_map->qdma.fwd_count)); ++ seq_printf(seq, "| QDMA_FSM : %08x |\n", ++ mtk_r32(eth, reg_map->qdma.fsm)); ++ seq_printf(seq, "| FE_PSE_FREE : %08x |\n", ++ mtk_r32(eth, MTK_FE_PSE_FREE)); ++ seq_printf(seq, "| FE_DROP_FQ : %08x |\n", ++ mtk_r32(eth, MTK_FE_DROP_FQ)); ++ seq_printf(seq, "| FE_DROP_FC : %08x |\n", ++ mtk_r32(eth, MTK_FE_DROP_FC)); ++ seq_printf(seq, "| FE_DROP_PPE : %08x |\n", ++ mtk_r32(eth, MTK_FE_DROP_PPE)); ++ seq_printf(seq, "| GDM1_IG_CTRL : %08x |\n", ++ mtk_r32(eth, MTK_GDMA_FWD_CFG(0))); ++ seq_printf(seq, "| GDM2_IG_CTRL : %08x |\n", ++ mtk_r32(eth, MTK_GDMA_FWD_CFG(1))); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ seq_printf(seq, "| GDM3_IG_CTRL : %08x |\n", ++ mtk_r32(eth, MTK_GDMA_FWD_CFG(2))); ++ } ++ seq_printf(seq, "| MAC_P1_MCR : %08x |\n", ++ mtk_r32(eth, MTK_MAC_MCR(0))); ++ seq_printf(seq, "| MAC_P2_MCR : %08x |\n", ++ mtk_r32(eth, MTK_MAC_MCR(1))); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ seq_printf(seq, "| MAC_P3_MCR : %08x |\n", ++ mtk_r32(eth, MTK_MAC_MCR(2))); ++ } ++ seq_printf(seq, "| MAC_P1_FSM : %08x |\n", ++ mtk_r32(eth, MTK_MAC_FSM(0))); ++ seq_printf(seq, "| MAC_P2_FSM : %08x |\n", ++ mtk_r32(eth, MTK_MAC_FSM(1))); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ seq_printf(seq, "| MAC_P3_FSM : %08x |\n", ++ mtk_r32(eth, MTK_MAC_FSM(2))); ++ } ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ seq_printf(seq, "| FE_CDM1_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM1_FSM)); ++ seq_printf(seq, "| FE_CDM2_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM2_FSM)); ++ seq_printf(seq, "| FE_CDM3_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM3_FSM)); ++ seq_printf(seq, "| FE_CDM4_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM4_FSM)); ++ seq_printf(seq, "| FE_CDM5_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM5_FSM)); ++ seq_printf(seq, "| FE_CDM6_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_CDM6_FSM)); ++ seq_printf(seq, "| FE_GDM1_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_GDM1_FSM)); ++ seq_printf(seq, "| FE_GDM2_FSM : %08x |\n", ++ mtk_r32(eth, MTK_FE_GDM2_FSM)); ++ seq_printf(seq, "| SGMII_EFUSE : %08x |\n", ++ mtk_dbg_r32(MTK_SGMII_EFUSE)); ++ seq_printf(seq, "| SGMII0_RX_CNT : %08x |\n", ++ mtk_dbg_r32(MTK_SGMII_FALSE_CARRIER_CNT(0))); ++ seq_printf(seq, "| SGMII1_RX_CNT : %08x |\n", ++ mtk_dbg_r32(MTK_SGMII_FALSE_CARRIER_CNT(1))); ++ seq_printf(seq, "| WED_RTQM_GLO : %08x |\n", ++ mtk_dbg_r32(MTK_WED_RTQM_GLO_CFG)); ++ } ++ ++ mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS); ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS2); ++ ++ return 0; ++} ++ ++static int dbg_regs_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, dbg_regs_read, 0); ++} ++ ++static const struct proc_ops dbg_regs_fops = { ++ .proc_open = dbg_regs_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++void hw_lro_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd) ++{ ++ struct mtk_eth *eth = g_eth; ++ u32 idx, agg_cnt, agg_size; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ idx = ring_no - 4; ++ agg_cnt = FIELD_GET(RX_DMA_GET_AGG_CNT_V2, rxd->rxd6); ++ } else { ++ idx = ring_no - 1; ++ agg_cnt = FIELD_GET(RX_DMA_GET_AGG_CNT, rxd->rxd2); ++ } ++ ++ if (idx >= MTK_HW_LRO_RING_NUM) ++ return; ++ ++ agg_size = RX_DMA_GET_PLEN0(rxd->rxd2); ++ ++ hw_lro_agg_size_cnt[idx][agg_size / 5000]++; ++ hw_lro_agg_num_cnt[idx][agg_cnt]++; ++ hw_lro_tot_flush_cnt[idx]++; ++ hw_lro_tot_agg_cnt[idx] += agg_cnt; ++} ++ ++void hw_lro_flush_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd) ++{ ++ struct mtk_eth *eth = g_eth; ++ u32 idx, flush_reason; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ idx = ring_no - 4; ++ flush_reason = FIELD_GET(RX_DMA_GET_FLUSH_RSN_V2, rxd->rxd6); ++ } else { ++ idx = ring_no - 1; ++ flush_reason = FIELD_GET(RX_DMA_GET_REV, rxd->rxd2); ++ } ++ ++ if (idx >= MTK_HW_LRO_RING_NUM) ++ return; ++ ++ if ((flush_reason & 0x7) == MTK_HW_LRO_AGG_FLUSH) ++ hw_lro_agg_flush_cnt[idx]++; ++ else if ((flush_reason & 0x7) == MTK_HW_LRO_AGE_FLUSH) ++ hw_lro_age_flush_cnt[idx]++; ++ else if ((flush_reason & 0x7) == MTK_HW_LRO_NOT_IN_SEQ_FLUSH) ++ hw_lro_seq_flush_cnt[idx]++; ++ else if ((flush_reason & 0x7) == MTK_HW_LRO_TIMESTAMP_FLUSH) ++ hw_lro_timestamp_flush_cnt[idx]++; ++ else if ((flush_reason & 0x7) == MTK_HW_LRO_NON_RULE_FLUSH) ++ hw_lro_norule_flush_cnt[idx]++; ++} ++ ++static ssize_t hw_lro_stats_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ memset(hw_lro_agg_num_cnt, 0, sizeof(hw_lro_agg_num_cnt)); ++ memset(hw_lro_agg_size_cnt, 0, sizeof(hw_lro_agg_size_cnt)); ++ memset(hw_lro_tot_agg_cnt, 0, sizeof(hw_lro_tot_agg_cnt)); ++ memset(hw_lro_tot_flush_cnt, 0, sizeof(hw_lro_tot_flush_cnt)); ++ memset(hw_lro_agg_flush_cnt, 0, sizeof(hw_lro_agg_flush_cnt)); ++ memset(hw_lro_age_flush_cnt, 0, sizeof(hw_lro_age_flush_cnt)); ++ memset(hw_lro_seq_flush_cnt, 0, sizeof(hw_lro_seq_flush_cnt)); ++ memset(hw_lro_timestamp_flush_cnt, 0, ++ sizeof(hw_lro_timestamp_flush_cnt)); ++ memset(hw_lro_norule_flush_cnt, 0, sizeof(hw_lro_norule_flush_cnt)); ++ ++ pr_info("clear hw lro cnt table\n"); ++ ++ return count; ++} ++ ++static int hw_lro_stats_read_v1(struct seq_file *seq, void *v) ++{ ++ int i; ++ ++ seq_puts(seq, "HW LRO statistic dump:\n"); ++ ++ /* Agg number count */ ++ seq_puts(seq, "Cnt: RING1 | RING2 | RING3 | Total\n"); ++ for (i = 0; i <= MTK_HW_LRO_MAX_AGG_CNT; i++) { ++ seq_printf(seq, " %d : %d %d %d %d\n", ++ i, hw_lro_agg_num_cnt[0][i], ++ hw_lro_agg_num_cnt[1][i], hw_lro_agg_num_cnt[2][i], ++ hw_lro_agg_num_cnt[0][i] + hw_lro_agg_num_cnt[1][i] + ++ hw_lro_agg_num_cnt[2][i]); ++ } ++ ++ /* Total agg count */ ++ seq_puts(seq, "Total agg: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ hw_lro_tot_agg_cnt[0], hw_lro_tot_agg_cnt[1], ++ hw_lro_tot_agg_cnt[2], ++ hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] + ++ hw_lro_tot_agg_cnt[2]); ++ ++ /* Total flush count */ ++ seq_puts(seq, "Total flush: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ hw_lro_tot_flush_cnt[0], hw_lro_tot_flush_cnt[1], ++ hw_lro_tot_flush_cnt[2], ++ hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] + ++ hw_lro_tot_flush_cnt[2]); ++ ++ /* Avg agg count */ ++ seq_puts(seq, "Avg agg: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ (hw_lro_tot_flush_cnt[0]) ? ++ hw_lro_tot_agg_cnt[0] / hw_lro_tot_flush_cnt[0] : 0, ++ (hw_lro_tot_flush_cnt[1]) ? ++ hw_lro_tot_agg_cnt[1] / hw_lro_tot_flush_cnt[1] : 0, ++ (hw_lro_tot_flush_cnt[2]) ? ++ hw_lro_tot_agg_cnt[2] / hw_lro_tot_flush_cnt[2] : 0, ++ (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] + ++ hw_lro_tot_flush_cnt[2]) ? ++ ((hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] + ++ hw_lro_tot_agg_cnt[2]) / (hw_lro_tot_flush_cnt[0] + ++ hw_lro_tot_flush_cnt[1] + hw_lro_tot_flush_cnt[2])) : 0); ++ ++ /* Statistics of aggregation size counts */ ++ seq_puts(seq, "HW LRO flush pkt len:\n"); ++ seq_puts(seq, " Length | RING1 | RING2 | RING3 | Total\n"); ++ for (i = 0; i < 15; i++) { ++ seq_printf(seq, "%d~%d: %d %d %d %d\n", i * 5000, ++ (i + 1) * 5000, hw_lro_agg_size_cnt[0][i], ++ hw_lro_agg_size_cnt[1][i], hw_lro_agg_size_cnt[2][i], ++ hw_lro_agg_size_cnt[0][i] + ++ hw_lro_agg_size_cnt[1][i] + ++ hw_lro_agg_size_cnt[2][i]); ++ } ++ ++ seq_puts(seq, "Flush reason: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, "AGG timeout: %d %d %d %d\n", ++ hw_lro_agg_flush_cnt[0], hw_lro_agg_flush_cnt[1], ++ hw_lro_agg_flush_cnt[2], ++ (hw_lro_agg_flush_cnt[0] + hw_lro_agg_flush_cnt[1] + ++ hw_lro_agg_flush_cnt[2])); ++ ++ seq_printf(seq, "AGE timeout: %d %d %d %d\n", ++ hw_lro_age_flush_cnt[0], hw_lro_age_flush_cnt[1], ++ hw_lro_age_flush_cnt[2], ++ (hw_lro_age_flush_cnt[0] + hw_lro_age_flush_cnt[1] + ++ hw_lro_age_flush_cnt[2])); ++ ++ seq_printf(seq, "Not in-sequence: %d %d %d %d\n", ++ hw_lro_seq_flush_cnt[0], hw_lro_seq_flush_cnt[1], ++ hw_lro_seq_flush_cnt[2], ++ (hw_lro_seq_flush_cnt[0] + hw_lro_seq_flush_cnt[1] + ++ hw_lro_seq_flush_cnt[2])); ++ ++ seq_printf(seq, "Timestamp: %d %d %d %d\n", ++ hw_lro_timestamp_flush_cnt[0], ++ hw_lro_timestamp_flush_cnt[1], ++ hw_lro_timestamp_flush_cnt[2], ++ (hw_lro_timestamp_flush_cnt[0] + ++ hw_lro_timestamp_flush_cnt[1] + ++ hw_lro_timestamp_flush_cnt[2])); ++ ++ seq_printf(seq, "No LRO rule: %d %d %d %d\n", ++ hw_lro_norule_flush_cnt[0], ++ hw_lro_norule_flush_cnt[1], ++ hw_lro_norule_flush_cnt[2], ++ (hw_lro_norule_flush_cnt[0] + ++ hw_lro_norule_flush_cnt[1] + ++ hw_lro_norule_flush_cnt[2])); ++ ++ return 0; ++} ++ ++static int hw_lro_stats_read_v2(struct seq_file *seq, void *v) ++{ ++ int i; ++ ++ seq_puts(seq, "HW LRO statistic dump:\n"); ++ ++ /* Agg number count */ ++ seq_puts(seq, "Cnt: RING4 | RING5 | RING6 | RING7 Total\n"); ++ for (i = 0; i <= MTK_HW_LRO_MAX_AGG_CNT; i++) { ++ seq_printf(seq, ++ " %d : %d %d %d %d %d\n", ++ i, hw_lro_agg_num_cnt[0][i], hw_lro_agg_num_cnt[1][i], ++ hw_lro_agg_num_cnt[2][i], hw_lro_agg_num_cnt[3][i], ++ hw_lro_agg_num_cnt[0][i] + hw_lro_agg_num_cnt[1][i] + ++ hw_lro_agg_num_cnt[2][i] + hw_lro_agg_num_cnt[3][i]); ++ } ++ ++ /* Total agg count */ ++ seq_puts(seq, "Total agg: RING4 | RING5 | RING6 | RING7 Total\n"); ++ seq_printf(seq, " %d %d %d %d %d\n", ++ hw_lro_tot_agg_cnt[0], hw_lro_tot_agg_cnt[1], ++ hw_lro_tot_agg_cnt[2], hw_lro_tot_agg_cnt[3], ++ hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] + ++ hw_lro_tot_agg_cnt[2] + hw_lro_tot_agg_cnt[3]); ++ ++ /* Total flush count */ ++ seq_puts(seq, "Total flush: RING4 | RING5 | RING6 | RING7 Total\n"); ++ seq_printf(seq, " %d %d %d %d %d\n", ++ hw_lro_tot_flush_cnt[0], hw_lro_tot_flush_cnt[1], ++ hw_lro_tot_flush_cnt[2], hw_lro_tot_flush_cnt[3], ++ hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] + ++ hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3]); ++ ++ /* Avg agg count */ ++ seq_puts(seq, "Avg agg: RING4 | RING5 | RING6 | RING7 Total\n"); ++ seq_printf(seq, " %d %d %d %d %d\n", ++ (hw_lro_tot_flush_cnt[0]) ? ++ hw_lro_tot_agg_cnt[0] / hw_lro_tot_flush_cnt[0] : 0, ++ (hw_lro_tot_flush_cnt[1]) ? ++ hw_lro_tot_agg_cnt[1] / hw_lro_tot_flush_cnt[1] : 0, ++ (hw_lro_tot_flush_cnt[2]) ? ++ hw_lro_tot_agg_cnt[2] / hw_lro_tot_flush_cnt[2] : 0, ++ (hw_lro_tot_flush_cnt[3]) ? ++ hw_lro_tot_agg_cnt[3] / hw_lro_tot_flush_cnt[3] : 0, ++ (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] + ++ hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3]) ? ++ ((hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] + ++ hw_lro_tot_agg_cnt[2] + hw_lro_tot_agg_cnt[3]) / ++ (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] + ++ hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3])) : 0); ++ ++ /* Statistics of aggregation size counts */ ++ seq_puts(seq, "HW LRO flush pkt len:\n"); ++ seq_puts(seq, " Length | RING4 | RING5 | RING6 | RING7 Total\n"); ++ for (i = 0; i < 15; i++) { ++ seq_printf(seq, "%d~%d: %d %d %d %d %d\n", ++ i * 5000, (i + 1) * 5000, ++ hw_lro_agg_size_cnt[0][i], hw_lro_agg_size_cnt[1][i], ++ hw_lro_agg_size_cnt[2][i], hw_lro_agg_size_cnt[3][i], ++ hw_lro_agg_size_cnt[0][i] + ++ hw_lro_agg_size_cnt[1][i] + ++ hw_lro_agg_size_cnt[2][i] + ++ hw_lro_agg_size_cnt[3][i]); ++ } ++ ++ seq_puts(seq, "Flush reason: RING4 | RING5 | RING6 | RING7 Total\n"); ++ seq_printf(seq, "AGG timeout: %d %d %d %d %d\n", ++ hw_lro_agg_flush_cnt[0], hw_lro_agg_flush_cnt[1], ++ hw_lro_agg_flush_cnt[2], hw_lro_agg_flush_cnt[3], ++ (hw_lro_agg_flush_cnt[0] + hw_lro_agg_flush_cnt[1] + ++ hw_lro_agg_flush_cnt[2] + hw_lro_agg_flush_cnt[3])); ++ ++ seq_printf(seq, "AGE timeout: %d %d %d %d %d\n", ++ hw_lro_age_flush_cnt[0], hw_lro_age_flush_cnt[1], ++ hw_lro_age_flush_cnt[2], hw_lro_age_flush_cnt[3], ++ (hw_lro_age_flush_cnt[0] + hw_lro_age_flush_cnt[1] + ++ hw_lro_age_flush_cnt[2] + hw_lro_age_flush_cnt[3])); ++ ++ seq_printf(seq, "Not in-sequence: %d %d %d %d %d\n", ++ hw_lro_seq_flush_cnt[0], hw_lro_seq_flush_cnt[1], ++ hw_lro_seq_flush_cnt[2], hw_lro_seq_flush_cnt[3], ++ (hw_lro_seq_flush_cnt[0] + hw_lro_seq_flush_cnt[1] + ++ hw_lro_seq_flush_cnt[2] + hw_lro_seq_flush_cnt[3])); ++ ++ seq_printf(seq, "Timestamp: %d %d %d %d %d\n", ++ hw_lro_timestamp_flush_cnt[0], ++ hw_lro_timestamp_flush_cnt[1], ++ hw_lro_timestamp_flush_cnt[2], ++ hw_lro_timestamp_flush_cnt[3], ++ (hw_lro_timestamp_flush_cnt[0] + ++ hw_lro_timestamp_flush_cnt[1] + ++ hw_lro_timestamp_flush_cnt[2] + ++ hw_lro_timestamp_flush_cnt[3])); ++ ++ seq_printf(seq, "No LRO rule: %d %d %d %d %d\n", ++ hw_lro_norule_flush_cnt[0], ++ hw_lro_norule_flush_cnt[1], ++ hw_lro_norule_flush_cnt[2], ++ hw_lro_norule_flush_cnt[3], ++ (hw_lro_norule_flush_cnt[0] + ++ hw_lro_norule_flush_cnt[1] + ++ hw_lro_norule_flush_cnt[2] + ++ hw_lro_norule_flush_cnt[3])); ++ ++ return 0; ++} ++ ++static int hw_lro_stats_read_wrapper(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ ++ if (mtk_is_netsys_v2_or_greater(eth)) ++ hw_lro_stats_read_v2(seq, v); ++ else ++ hw_lro_stats_read_v1(seq, v); ++ ++ return 0; ++} ++ ++static int hw_lro_stats_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, hw_lro_stats_read_wrapper, NULL); ++} ++ ++static const struct proc_ops hw_lro_stats_fops = { ++ .proc_open = hw_lro_stats_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = hw_lro_stats_write, ++ .proc_release = single_release ++}; ++ ++static int hwlro_agg_cnt_ctrl(int cnt) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ int i; ++ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) ++ SET_PDMA_RXRING_MAX_AGG_CNT(eth, i, cnt); ++ ++ return 0; ++} ++ ++static int hwlro_agg_time_ctrl(int time) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ int i; ++ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) ++ SET_PDMA_RXRING_AGG_TIME(eth, i, time); ++ ++ return 0; ++} ++ ++static int hwlro_age_time_ctrl(int time) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ int i; ++ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) ++ SET_PDMA_RXRING_AGE_TIME(eth, i, time); ++ return 0; ++} ++ ++static int hwlro_threshold_ctrl(int bandwidth) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ ++ SET_PDMA_LRO_BW_THRESHOLD(eth, bandwidth); ++ ++ return 0; ++} ++ ++static int hwlro_ring_enable_ctrl(int enable) ++{ ++ struct mtk_eth *eth = g_eth; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ int i; ++ ++ pr_info("[%s] %s HW LRO rings\n", __func__, (enable) ? "Enable" : "Disable"); ++ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) ++ SET_PDMA_RXRING_VALID(eth, i, enable); ++ ++ return 0; ++} ++ ++static int hwlro_stats_enable_ctrl(int enable) ++{ ++ pr_info("[%s] %s HW LRO statistics\n", __func__, (enable) ? "Enable" : "Disable"); ++ mtk_hwlro_stats_ebl = enable; ++ ++ return 0; ++} ++ ++static const mtk_lro_dbg_func lro_dbg_func[] = { ++ [0] = hwlro_agg_cnt_ctrl, ++ [1] = hwlro_agg_time_ctrl, ++ [2] = hwlro_age_time_ctrl, ++ [3] = hwlro_threshold_ctrl, ++ [4] = hwlro_ring_enable_ctrl, ++ [5] = hwlro_stats_enable_ctrl, ++}; ++ ++static ssize_t hw_lro_auto_tlb_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[32]; ++ char *p_buf; ++ char *p_token = NULL; ++ char *p_delimiter = " \t"; ++ long x = 0, y = 0; ++ u32 len = count; ++ int ret; ++ ++ if (len >= sizeof(buf)) { ++ pr_info("Input handling fail!\n"); ++ return -1; ++ } ++ ++ if (copy_from_user(buf, buffer, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ ++ p_buf = buf; ++ p_token = strsep(&p_buf, p_delimiter); ++ if (!p_token) ++ x = 0; ++ else ++ ret = kstrtol(p_token, 10, &x); ++ ++ p_token = strsep(&p_buf, "\t\n "); ++ if (p_token) ++ ret = kstrtol(p_token, 10, &y); ++ ++ if (lro_dbg_func[x] && (ARRAY_SIZE(lro_dbg_func) > x)) ++ (*lro_dbg_func[x]) (y); ++ ++ return count; ++} ++ ++static void hw_lro_auto_tlb_dump_v1(struct seq_file *seq, u32 index) ++{ ++ struct mtk_eth *eth = g_eth; ++ struct mtk_lro_alt_v1 alt; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ __be32 addr; ++ u32 tlb_info[9]; ++ u32 dw_len, cnt, priority; ++ u32 entry; ++ int i; ++ ++ if (index > 4) ++ index = index - 1; ++ entry = (index * 9) + 1; ++ ++ /* read valid entries of the auto-learn table */ ++ mtk_w32(eth, entry, MTK_FE_ALT_CF8); ++ ++ for (i = 0; i < 9; i++) ++ tlb_info[i] = mtk_r32(eth, MTK_FE_ALT_SEQ_CFC); ++ ++ memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v1)); ++ ++ dw_len = alt.alt_info7.dw_len; ++ cnt = alt.alt_info6.cnt; ++ ++ if (mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE) ++ priority = cnt; /* packet count */ ++ else ++ priority = dw_len; /* byte count */ ++ ++ /* dump valid entries of the auto-learn table */ ++ if (index >= 4) ++ seq_printf(seq, "\n===== TABLE Entry: %d (Act) =====\n", index); ++ else ++ seq_printf(seq, "\n===== TABLE Entry: %d (LRU) =====\n", index); ++ ++ if (alt.alt_info8.ipv4) { ++ addr = htonl(alt.alt_info1.sip0); ++ seq_printf(seq, "SIP = %pI4 (IPv4)\n", &addr); ++ } else { ++ seq_printf(seq, "SIP = %08X:%08X:%08X:%08X (IPv6)\n", ++ alt.alt_info4.sip3, alt.alt_info3.sip2, ++ alt.alt_info2.sip1, alt.alt_info1.sip0); ++ } ++ ++ seq_printf(seq, "DIP_ID = %d\n", alt.alt_info8.dip_id); ++ seq_printf(seq, "TCP SPORT = %d | TCP DPORT = %d\n", ++ alt.alt_info0.stp, alt.alt_info0.dtp); ++ seq_printf(seq, "VLAN_VID_VLD = %d\n", alt.alt_info6.vlan_vid_vld); ++ seq_printf(seq, "VLAN1 = %d | VLAN2 = %d | VLAN3 = %d | VLAN4 =%d\n", ++ (alt.alt_info5.vlan_vid0 & 0xfff), ++ ((alt.alt_info5.vlan_vid0 >> 12) & 0xfff), ++ ((alt.alt_info6.vlan_vid1 << 8) | ++ ((alt.alt_info5.vlan_vid0 >> 24) & 0xfff)), ++ ((alt.alt_info6.vlan_vid1 >> 4) & 0xfff)); ++ seq_printf(seq, "TPUT = %d | FREQ = %d\n", dw_len, cnt); ++ seq_printf(seq, "PRIORITY = %d\n", priority); ++} ++ ++static void hw_lro_auto_tlb_dump_v2(struct seq_file *seq, u32 index) ++{ ++ struct mtk_eth *eth = g_eth; ++ struct mtk_lro_alt_v2 alt; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ u32 score = 0, ipv4 = 0; ++ u32 ipv6[4] = { 0 }; ++ u32 tlb_info[12]; ++ int i; ++ ++ /* read valid entries of the auto-learn table */ ++ mtk_w32(eth, index << MTK_LRO_ALT_INDEX_OFFSET, reg_map->pdma.lro_alt_dbg); ++ ++ for (i = 0; i < 11; i++) ++ tlb_info[i] = mtk_r32(eth, reg_map->pdma.lro_alt_dbg_data); ++ ++ memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v2)); ++ ++ if (mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE) ++ score = 1; /* packet count */ ++ else ++ score = 0; /* byte count */ ++ ++ /* dump valid entries of the auto-learn table */ ++ if (alt.alt_info0.valid) { ++ if (index < 5) ++ seq_printf(seq, ++ "\n===== TABLE Entry: %d (onging) =====\n", ++ index); ++ else ++ seq_printf(seq, ++ "\n===== TABLE Entry: %d (candidate) =====\n", ++ index); ++ ++ if (alt.alt_info1.v4_valid) { ++ ipv4 = (alt.alt_info4.sip0_h << 23) | ++ alt.alt_info5.sip0_l; ++ seq_printf(seq, "SIP = 0x%x: (IPv4)\n", ipv4); ++ ++ ipv4 = (alt.alt_info8.dip0_h << 23) | ++ alt.alt_info9.dip0_l; ++ seq_printf(seq, "DIP = 0x%x: (IPv4)\n", ipv4); ++ } else if (alt.alt_info1.v6_valid) { ++ ipv6[3] = (alt.alt_info1.sip3_h << 23) | ++ (alt.alt_info2.sip3_l << 9); ++ ipv6[2] = (alt.alt_info2.sip2_h << 23) | ++ (alt.alt_info3.sip2_l << 9); ++ ipv6[1] = (alt.alt_info3.sip1_h << 23) | ++ (alt.alt_info4.sip1_l << 9); ++ ipv6[0] = (alt.alt_info4.sip0_h << 23) | ++ (alt.alt_info5.sip0_l << 9); ++ seq_printf(seq, "SIP = 0x%x:0x%x:0x%x:0x%x (IPv6)\n", ++ ipv6[3], ipv6[2], ipv6[1], ipv6[0]); ++ ++ ipv6[3] = (alt.alt_info5.dip3_h << 23) | ++ (alt.alt_info6.dip3_l << 9); ++ ipv6[2] = (alt.alt_info6.dip2_h << 23) | ++ (alt.alt_info7.dip2_l << 9); ++ ipv6[1] = (alt.alt_info7.dip1_h << 23) | ++ (alt.alt_info8.dip1_l << 9); ++ ipv6[0] = (alt.alt_info8.dip0_h << 23) | ++ (alt.alt_info9.dip0_l << 9); ++ seq_printf(seq, "DIP = 0x%x:0x%x:0x%x:0x%x (IPv6)\n", ++ ipv6[3], ipv6[2], ipv6[1], ipv6[0]); ++ } ++ ++ seq_printf(seq, "TCP SPORT = %d | TCP DPORT = %d\n", ++ (alt.alt_info9.sp_h << 7) | (alt.alt_info10.sp_l), ++ alt.alt_info10.dp); ++ } ++} ++ ++static int hw_lro_auto_tlb_read(struct seq_file *seq, void *v) ++{ ++ struct mtk_eth *eth = g_eth; ++ int i; ++ u32 reg_val; ++ u32 reg_op1, reg_op2, reg_op3, reg_op4; ++ u32 agg_cnt, agg_time, age_time; ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ ++ seq_puts(seq, "Usage of /proc/mtketh/hw_lro_auto_tlb:\n"); ++ seq_puts(seq, "echo [function] [setting] > /proc/mtketh/hw_lro_auto_tlb\n"); ++ seq_puts(seq, "Functions:\n"); ++ seq_puts(seq, "[0] = hwlro_agg_cnt_ctrl\n"); ++ seq_puts(seq, "[1] = hwlro_agg_time_ctrl\n"); ++ seq_puts(seq, "[2] = hwlro_age_time_ctrl\n"); ++ seq_puts(seq, "[3] = hwlro_threshold_ctrl\n"); ++ seq_puts(seq, "[4] = hwlro_ring_enable_ctrl\n"); ++ seq_puts(seq, "[5] = hwlro_stats_enable_ctrl\n\n"); ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ for (i = 1; i <= 8; i++) ++ hw_lro_auto_tlb_dump_v2(seq, i); ++ } else { ++ /* Read valid entries of the auto-learn table */ ++ mtk_w32(eth, 0, MTK_FE_ALT_CF8); ++ reg_val = mtk_r32(eth, MTK_FE_ALT_SEQ_CFC); ++ ++ seq_printf(seq, ++ "HW LRO Auto-learn Table: (MTK_FE_ALT_SEQ_CFC=0x%x)\n", ++ reg_val); ++ ++ for (i = 7; i >= 0; i--) { ++ if (reg_val & (1 << i)) ++ hw_lro_auto_tlb_dump_v1(seq, i); ++ } ++ } ++ ++ /* Read the agg_time/age_time/agg_cnt of LRO rings */ ++ seq_puts(seq, "\nHW LRO Ring Settings\n"); ++ ++ for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) { ++ reg_op1 = mtk_r32(eth, MTK_LRO_CTRL_DW1_CFG(i)); ++ reg_op2 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(i)); ++ reg_op3 = mtk_r32(eth, MTK_LRO_CTRL_DW3_CFG(i)); ++ reg_op4 = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW2); ++ ++ agg_cnt = ++ ((reg_op3 & 0x3) << 6) | ++ ((reg_op2 >> MTK_LRO_RING_AGG_CNT_L_OFFSET) & 0x3f); ++ agg_time = (reg_op2 >> MTK_LRO_RING_AGG_TIME_OFFSET) & 0xffff; ++ age_time = ++ ((reg_op2 & 0x3f) << 10) | ++ ((reg_op1 >> MTK_LRO_RING_AGE_TIME_L_OFFSET) & 0x3ff); ++ seq_printf(seq, ++ "Ring[%d]: MAX_AGG_CNT=%d, AGG_TIME=%d, AGE_TIME=%d, Threshold=%d\n", ++ !(mtk_is_netsys_v2_or_greater(eth)) ? ++ i : i+3, ++ agg_cnt, agg_time, age_time, reg_op4); ++ } ++ ++ seq_puts(seq, "\n"); ++ ++ return 0; ++} ++ ++static int hw_lro_auto_tlb_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, hw_lro_auto_tlb_read, NULL); ++} ++ ++static const struct proc_ops hw_lro_auto_tlb_fops = { ++ .proc_open = hw_lro_auto_tlb_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = hw_lro_auto_tlb_write, ++ .proc_release = single_release ++}; ++ ++struct proc_dir_entry *proc_reg_dir; ++static struct proc_dir_entry *proc_esw_cnt, *proc_xfi_cnt, ++ *proc_dbg_regs, *proc_reset_event; ++ ++int debug_proc_init(struct mtk_eth *eth) ++{ ++ g_eth = eth; ++ ++ if (!proc_reg_dir) ++ proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL); ++ ++ proc_tx_ring = ++ proc_create(PROCREG_TXRING, 0, proc_reg_dir, &tx_ring_fops); ++ if (!proc_tx_ring) ++ pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_TXRING); ++ ++ proc_hwtx_ring = ++ proc_create(PROCREG_HWTXRING, 0, proc_reg_dir, &hwtx_ring_fops); ++ if (!proc_hwtx_ring) ++ pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_HWTXRING); ++ ++ proc_rx_ring = ++ proc_create(PROCREG_RXRING, 0, proc_reg_dir, &rx_ring_fops); ++ if (!proc_rx_ring) ++ pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_RXRING); ++ ++ proc_esw_cnt = ++ proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops); ++ if (!proc_esw_cnt) ++ pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); ++ ++ if (mtk_is_netsys_v3_or_greater(g_eth)) { ++ proc_xfi_cnt = ++ proc_create(PROCREG_XFI_CNT, 0, ++ proc_reg_dir, &xfi_count_fops); ++ if (!proc_xfi_cnt) ++ pr_notice("!! FAIL to create %s PROC !!\n", ++ PROCREG_XFI_CNT); ++ } ++ ++ proc_dbg_regs = ++ proc_create(PROCREG_DBG_REGS, 0, proc_reg_dir, &dbg_regs_fops); ++ if (!proc_dbg_regs) ++ pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_DBG_REGS); ++ ++ if (g_eth->hwlro) { ++ proc_hw_lro_stats = ++ proc_create(PROCREG_HW_LRO_STATS, 0, proc_reg_dir, ++ &hw_lro_stats_fops); ++ if (!proc_hw_lro_stats) ++ pr_info("!! FAIL to create %s PROC !!\n", PROCREG_HW_LRO_STATS); ++ ++ proc_hw_lro_auto_tlb = ++ proc_create(PROCREG_HW_LRO_AUTO_TLB, 0, proc_reg_dir, ++ &hw_lro_auto_tlb_fops); ++ if (!proc_hw_lro_auto_tlb) ++ pr_info("!! FAIL to create %s PROC !!\n", ++ PROCREG_HW_LRO_AUTO_TLB); ++ } ++ ++ dbg_show_level = 1; ++ ++ return 0; ++} ++ ++void debug_proc_exit(void) ++{ ++ if (proc_tx_ring) ++ remove_proc_entry(PROCREG_TXRING, proc_reg_dir); ++ ++ if (proc_hwtx_ring) ++ remove_proc_entry(PROCREG_HWTXRING, proc_reg_dir); ++ ++ if (proc_rx_ring) ++ remove_proc_entry(PROCREG_RXRING, proc_reg_dir); ++ ++ if (proc_esw_cnt) ++ remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir); ++ ++ if (proc_xfi_cnt) ++ remove_proc_entry(PROCREG_XFI_CNT, proc_reg_dir); ++ ++ if (proc_reg_dir) ++ remove_proc_entry(PROCREG_DIR, 0); ++ ++ if (proc_dbg_regs) ++ remove_proc_entry(PROCREG_DBG_REGS, proc_reg_dir); ++ ++ if (g_eth->hwlro) { ++ if (proc_hw_lro_stats) ++ remove_proc_entry(PROCREG_HW_LRO_STATS, proc_reg_dir); ++ ++ if (proc_hw_lro_auto_tlb) ++ remove_proc_entry(PROCREG_HW_LRO_AUTO_TLB, proc_reg_dir); ++ } ++ ++ if (proc_reset_event) ++ remove_proc_entry(PROCREG_RESET_EVENT, proc_reg_dir); ++} +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/drivers/net/ethernet/mediatek/mtk_eth_dbg.h +new file mode 100644 +index 000000000000..7371131c5448 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_eth_dbg.h +@@ -0,0 +1,335 @@ ++/* ++ * Copyright (C) 2018 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2009-2016 John Crispin ++ * Copyright (C) 2009-2016 Felix Fietkau ++ * Copyright (C) 2013-2016 Michael Lee ++ */ ++ ++#ifndef MTK_ETH_DBG_H ++#define MTK_ETH_DBG_H ++ ++/* Debug Purpose Register */ ++#define MTK_PSE_FQFC_CFG 0x100 ++#define MTK_FE_CDM1_FSM 0x220 ++#define MTK_FE_CDM2_FSM 0x224 ++#define MTK_FE_CDM3_FSM 0x238 ++#define MTK_FE_CDM4_FSM 0x298 ++#define MTK_FE_CDM5_FSM 0x318 ++#define MTK_FE_CDM6_FSM 0x328 ++#define MTK_FE_GDM1_FSM 0x228 ++#define MTK_FE_GDM2_FSM 0x22C ++#define MTK_FE_GDM3_FSM 0x23C ++#define MTK_FE_PSE_FREE 0x240 ++#define MTK_FE_DROP_FQ 0x244 ++#define MTK_FE_DROP_FC 0x248 ++#define MTK_FE_DROP_PPE 0x24C ++#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) ++#define MTK_SGMII_FALSE_CARRIER_CNT(x) (0x10060028 + ((x) * 0x10000)) ++#define MTK_SGMII_EFUSE 0x11D008C8 ++ ++#define MTKETH_MII_READ 0x89F3 ++#define MTKETH_MII_WRITE 0x89F4 ++#define MTKETH_ESW_REG_READ 0x89F1 ++#define MTKETH_ESW_REG_WRITE 0x89F2 ++#define MTKETH_MII_READ_CL45 0x89FC ++#define MTKETH_MII_WRITE_CL45 0x89FD ++#define REG_ESW_MAX 0xFC ++ ++#define PROCREG_ESW_CNT "esw_cnt" ++#define PROCREG_XFI_CNT "xfi_cnt" ++#define PROCREG_TXRING "tx_ring" ++#define PROCREG_HWTXRING "hwtx_ring" ++#define PROCREG_RXRING "rx_ring" ++#define PROCREG_DIR "mtketh" ++#define PROCREG_DBG_REGS "dbg_regs" ++#define PROCREG_RSS_CTRL "rss_ctrl" ++#define PROCREG_HW_LRO_STATS "hw_lro_stats" ++#define PROCREG_HW_LRO_AUTO_TLB "hw_lro_auto_tlb" ++#define PROCREG_RESET_EVENT "reset_event" ++ ++/* XFI MAC MIB Register */ ++#define MTK_XFI_MIB_BASE(x) (MTK_XMAC_MCR(x)) ++#define MTK_XFI_CNT_CTRL 0x100 ++#define MTK_XFI_TX_PKT_CNT 0x108 ++#define MTK_XFI_TX_ETH_CNT 0x114 ++#define MTK_XFI_TX_PAUSE_CNT 0x120 ++#define MTK_XFI_TX_BYTE_CNT 0x134 ++#define MTK_XFI_TX_UC_PKT_CNT_L 0x150 ++#define MTK_XFI_TX_UC_PKT_CNT_H 0x154 ++#define MTK_XFI_TX_MC_PKT_CNT_L 0x160 ++#define MTK_XFI_TX_MC_PKT_CNT_H 0x164 ++#define MTK_XFI_TX_BC_PKT_CNT_L 0x170 ++#define MTK_XFI_TX_BC_PKT_CNT_H 0x174 ++ ++#define MTK_XFI_RX_PKT_CNT 0x188 ++#define MTK_XFI_RX_ETH_CNT 0x18C ++#define MTK_XFI_RX_PAUSE_CNT 0x190 ++#define MTK_XFI_RX_LEN_ERR_CNT 0x194 ++#define MTK_XFI_RX_CRC_ERR_CNT 0x198 ++#define MTK_XFI_RX_UC_PKT_CNT_L 0x1C0 ++#define MTK_XFI_RX_UC_PKT_CNT_H 0x1C4 ++#define MTK_XFI_RX_MC_PKT_CNT_L 0x1D0 ++#define MTK_XFI_RX_MC_PKT_CNT_H 0x1D4 ++#define MTK_XFI_RX_BC_PKT_CNT_L 0x1E0 ++#define MTK_XFI_RX_BC_PKT_CNT_H 0x1E4 ++#define MTK_XFI_RX_UC_DROP_CNT 0x200 ++#define MTK_XFI_RX_BC_DROP_CNT 0x204 ++#define MTK_XFI_RX_MC_DROP_CNT 0x208 ++#define MTK_XFI_RX_ALL_DROP_CNT 0x20C ++ ++#define PRINT_FORMATTED_XFI_MIB(seq, reg, mask) \ ++{ \ ++ seq_printf(seq, "| XFI%d_%s : %010lu |\n", \ ++ gdm_id, #reg, \ ++ FIELD_GET(mask, mtk_r32(eth, \ ++ MTK_XFI_MIB_BASE(gdm_id) + \ ++ MTK_XFI_##reg))); \ ++} ++ ++#define PRINT_FORMATTED_XFI_MIB64(seq, reg) \ ++{ \ ++ seq_printf(seq, "| XFI%d_%s : %010llu |\n", \ ++ gdm_id, #reg, \ ++ mtk_r32(eth, MTK_XFI_MIB_BASE(gdm_id) + \ ++ MTK_XFI_##reg##_L) + \ ++ ((u64)mtk_r32(eth, MTK_XFI_MIB_BASE(gdm_id) +\ ++ MTK_XFI_##reg##_H) << 32)); \ ++} ++ ++/* HW LRO flush reason */ ++#define MTK_HW_LRO_AGG_FLUSH (1) ++#define MTK_HW_LRO_AGE_FLUSH (2) ++#define MTK_HW_LRO_NOT_IN_SEQ_FLUSH (3) ++#define MTK_HW_LRO_TIMESTAMP_FLUSH (4) ++#define MTK_HW_LRO_NON_RULE_FLUSH (5) ++ ++#define SET_PDMA_RXRING_MAX_AGG_CNT(eth, x, y) \ ++{ \ ++ u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ ++ u32 reg_val2 = mtk_r32(eth, MTK_LRO_CTRL_DW3_CFG(x)); \ ++ reg_val1 &= ~MTK_LRO_RING_AGG_CNT_L_MASK; \ ++ reg_val2 &= ~MTK_LRO_RING_AGG_CNT_H_MASK; \ ++ reg_val1 |= ((y) & 0x3f) << MTK_LRO_RING_AGG_CNT_L_OFFSET; \ ++ reg_val2 |= (((y) >> 6) & 0x03) << \ ++ MTK_LRO_RING_AGG_CNT_H_OFFSET; \ ++ mtk_w32(eth, reg_val1, MTK_LRO_CTRL_DW2_CFG(x)); \ ++ mtk_w32(eth, reg_val2, MTK_LRO_CTRL_DW3_CFG(x)); \ ++} ++ ++#define SET_PDMA_RXRING_AGG_TIME(eth, x, y) \ ++{ \ ++ u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ ++ reg_val &= ~MTK_LRO_RING_AGG_TIME_MASK; \ ++ reg_val |= ((y) & 0xffff) << MTK_LRO_RING_AGG_TIME_OFFSET; \ ++ mtk_w32(eth, reg_val, MTK_LRO_CTRL_DW2_CFG(x)); \ ++} ++ ++#define SET_PDMA_RXRING_AGE_TIME(eth, x, y) \ ++{ \ ++ u32 reg_val1 = mtk_r32(eth, MTK_LRO_CTRL_DW1_CFG(x)); \ ++ u32 reg_val2 = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ ++ reg_val1 &= ~MTK_LRO_RING_AGE_TIME_L_MASK; \ ++ reg_val2 &= ~MTK_LRO_RING_AGE_TIME_H_MASK; \ ++ reg_val1 |= ((y) & 0x3ff) << MTK_LRO_RING_AGE_TIME_L_OFFSET; \ ++ reg_val2 |= (((y) >> 10) & 0x03f) << \ ++ MTK_LRO_RING_AGE_TIME_H_OFFSET; \ ++ mtk_w32(eth, reg_val1, MTK_LRO_CTRL_DW1_CFG(x)); \ ++ mtk_w32(eth, reg_val2, MTK_LRO_CTRL_DW2_CFG(x)); \ ++} ++ ++#define SET_PDMA_LRO_BW_THRESHOLD(eth, x) \ ++{ \ ++ u32 reg_val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW2); \ ++ reg_val = (x); \ ++ mtk_w32(eth, reg_val, MTK_PDMA_LRO_CTRL_DW2); \ ++} ++ ++#define SET_PDMA_RXRING_VALID(eth, x, y) \ ++{ \ ++ u32 reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(x)); \ ++ reg_val &= ~(0x1 << MTK_LRO_RING_RX_PORT_VLD_OFFSET); \ ++ reg_val |= ((y) & 0x1) << MTK_LRO_RING_RX_PORT_VLD_OFFSET; \ ++ mtk_w32(eth, reg_val, MTK_LRO_CTRL_DW2_CFG(x)); \ ++} ++ ++struct mtk_lro_alt_v1_info0 { ++ u32 dtp : 16; ++ u32 stp : 16; ++}; ++ ++struct mtk_lro_alt_v1_info1 { ++ u32 sip0 : 32; ++}; ++ ++struct mtk_lro_alt_v1_info2 { ++ u32 sip1 : 32; ++}; ++ ++struct mtk_lro_alt_v1_info3 { ++ u32 sip2 : 32; ++}; ++ ++struct mtk_lro_alt_v1_info4 { ++ u32 sip3 : 32; ++}; ++ ++struct mtk_lro_alt_v1_info5 { ++ u32 vlan_vid0 : 32; ++}; ++ ++struct mtk_lro_alt_v1_info6 { ++ u32 vlan_vid1 : 16; ++ u32 vlan_vid_vld : 4; ++ u32 cnt : 12; ++}; ++ ++struct mtk_lro_alt_v1_info7 { ++ u32 dw_len : 32; ++}; ++ ++struct mtk_lro_alt_v1_info8 { ++ u32 dip_id : 2; ++ u32 ipv6 : 1; ++ u32 ipv4 : 1; ++ u32 resv : 27; ++ u32 valid : 1; ++}; ++ ++struct mtk_lro_alt_v1 { ++ struct mtk_lro_alt_v1_info0 alt_info0; ++ struct mtk_lro_alt_v1_info1 alt_info1; ++ struct mtk_lro_alt_v1_info2 alt_info2; ++ struct mtk_lro_alt_v1_info3 alt_info3; ++ struct mtk_lro_alt_v1_info4 alt_info4; ++ struct mtk_lro_alt_v1_info5 alt_info5; ++ struct mtk_lro_alt_v1_info6 alt_info6; ++ struct mtk_lro_alt_v1_info7 alt_info7; ++ struct mtk_lro_alt_v1_info8 alt_info8; ++}; ++ ++struct mtk_lro_alt_v2_info0 { ++ u32 v2_id_h:3; ++ u32 v1_id:12; ++ u32 v0_id:12; ++ u32 v3_valid:1; ++ u32 v2_valid:1; ++ u32 v1_valid:1; ++ u32 v0_valid:1; ++ u32 valid:1; ++}; ++ ++struct mtk_lro_alt_v2_info1 { ++ u32 sip3_h:9; ++ u32 v6_valid:1; ++ u32 v4_valid:1; ++ u32 v3_id:12; ++ u32 v2_id_l:9; ++}; ++ ++struct mtk_lro_alt_v2_info2 { ++ u32 sip2_h:9; ++ u32 sip3_l:23; ++}; ++struct mtk_lro_alt_v2_info3 { ++ u32 sip1_h:9; ++ u32 sip2_l:23; ++}; ++struct mtk_lro_alt_v2_info4 { ++ u32 sip0_h:9; ++ u32 sip1_l:23; ++}; ++struct mtk_lro_alt_v2_info5 { ++ u32 dip3_h:9; ++ u32 sip0_l:23; ++}; ++struct mtk_lro_alt_v2_info6 { ++ u32 dip2_h:9; ++ u32 dip3_l:23; ++}; ++struct mtk_lro_alt_v2_info7 { ++ u32 dip1_h:9; ++ u32 dip2_l:23; ++}; ++struct mtk_lro_alt_v2_info8 { ++ u32 dip0_h:9; ++ u32 dip1_l:23; ++}; ++struct mtk_lro_alt_v2_info9 { ++ u32 sp_h:9; ++ u32 dip0_l:23; ++}; ++struct mtk_lro_alt_v2_info10 { ++ u32 resv:9; ++ u32 dp:16; ++ u32 sp_l:7; ++}; ++ ++struct mtk_lro_alt_v2 { ++ struct mtk_lro_alt_v2_info0 alt_info0; ++ struct mtk_lro_alt_v2_info1 alt_info1; ++ struct mtk_lro_alt_v2_info2 alt_info2; ++ struct mtk_lro_alt_v2_info3 alt_info3; ++ struct mtk_lro_alt_v2_info4 alt_info4; ++ struct mtk_lro_alt_v2_info5 alt_info5; ++ struct mtk_lro_alt_v2_info6 alt_info6; ++ struct mtk_lro_alt_v2_info7 alt_info7; ++ struct mtk_lro_alt_v2_info8 alt_info8; ++ struct mtk_lro_alt_v2_info9 alt_info9; ++ struct mtk_lro_alt_v2_info10 alt_info10; ++}; ++ ++struct mtk_esw_reg { ++ unsigned int off; ++ unsigned int val; ++}; ++ ++struct mtk_mii_ioctl_data { ++ u16 phy_id; ++ u16 reg_num; ++ unsigned int val_in; ++ unsigned int val_out; ++}; ++ ++#if defined(CONFIG_NET_DSA_MT7530) || defined(CONFIG_MT753X_GSW) ++static inline bool mt7530_exist(struct mtk_eth *eth) ++{ ++ return true; ++} ++#else ++static inline bool mt7530_exist(struct mtk_eth *eth) ++{ ++ return false; ++} ++#endif ++ ++extern int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, ++ u32 write_data); ++extern int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr, ++ u32 devad, u32 phy_reg, u32 write_data); ++extern int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg); ++extern int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr, ++ u32 devad, u32 phy_reg); ++ ++void mtk_switch_w32(struct mtk_eth *eth, u32 val, unsigned int reg); ++u32 mtk_switch_r32(struct mtk_eth *eth, unsigned int reg); ++ ++int debug_proc_init(struct mtk_eth *eth); ++void debug_proc_exit(void); ++ ++int mtketh_debugfs_init(struct mtk_eth *eth); ++void mtketh_debugfs_exit(struct mtk_eth *eth); ++int mtk_do_priv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); ++void hw_lro_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd); ++void hw_lro_flush_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd); ++ ++#endif /* MTK_ETH_DBG_H */ +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 730146eb322e..045619d37d83 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -52,6 +52,7 @@ static const struct mtk_reg_map mtk_reg_map = { + .rx_ptr = 0x0900, + .rx_cnt_cfg = 0x0904, + .pcrx_ptr = 0x0908, ++ .pdrx_ptr = 0x090c, + .lro_ctrl_dw0 = 0x0980, + .glo_cfg = 0x0a04, + .rst_idx = 0x0a08, +@@ -77,9 +78,11 @@ static const struct mtk_reg_map mtk_reg_map = { + .fc_th = 0x1a10, + .tx_sch_rate = 0x1a14, + .int_grp = 0x1a20, ++ .fsm = 0x1a34, + .hred = 0x1a44, + .ctx_ptr = 0x1b00, + .dtx_ptr = 0x1b04, ++ .fwd_count = 0x1b08, + .crx_ptr = 0x1b10, + .drx_ptr = 0x1b14, + .fq_head = 0x1b20, +@@ -107,6 +110,7 @@ static const struct mtk_reg_map mt7628_reg_map = { + .rx_ptr = 0x0900, + .rx_cnt_cfg = 0x0904, + .pcrx_ptr = 0x0908, ++ .pdrx_ptr = 0x090c, + .glo_cfg = 0x0a04, + .rst_idx = 0x0a08, + .delay_irq = 0x0a0c, +@@ -124,6 +128,7 @@ static const struct mtk_reg_map mt7986_reg_map = { + .rx_ptr = 0x4100, + .rx_cnt_cfg = 0x4104, + .pcrx_ptr = 0x4108, ++ .pdrx_ptr = 0x410c, + .glo_cfg = 0x4204, + .rst_idx = 0x4208, + .delay_irq = 0x420c, +@@ -149,9 +154,12 @@ static const struct mtk_reg_map mt7986_reg_map = { + .delay_irq = 0x460c, + .fc_th = 0x4610, + .int_grp = 0x4620, ++ .fsm = 0x4634, + .hred = 0x4644, ++ .qtx_mib_if = 0x46bc, + .ctx_ptr = 0x4700, + .dtx_ptr = 0x4704, ++ .fwd_count = 0x4708, + .crx_ptr = 0x4710, + .drx_ptr = 0x4714, + .fq_head = 0x4720, +@@ -181,6 +189,7 @@ static const struct mtk_reg_map mt7988_reg_map = { + .rx_ptr = 0x6900, + .rx_cnt_cfg = 0x6904, + .pcrx_ptr = 0x6908, ++ .pdrx_ptr = 0x690c, + .glo_cfg = 0x6a04, + .rst_idx = 0x6a08, + .delay_irq = 0x6a0c, +@@ -211,9 +220,12 @@ static const struct mtk_reg_map mt7988_reg_map = { + .delay_irq = 0x460c, + .fc_th = 0x4610, + .int_grp = 0x4620, ++ .fsm = 0x4634, + .hred = 0x4644, ++ .qtx_mib_if = 0x46bc, + .ctx_ptr = 0x4700, + .dtx_ptr = 0x4704, ++ .fwd_count = 0x4708, + .crx_ptr = 0x4710, + .drx_ptr = 0x4714, + .fq_head = 0x4720, +@@ -348,7 +360,7 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth) + return -ETIMEDOUT; + } + +-static int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, ++int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, + u32 write_data) + { + int ret; +@@ -408,7 +420,7 @@ static int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr, + return 0; + } + +-static int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg) ++int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg) + { + int ret; + +@@ -2579,12 +2591,12 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget) + + static void mtk_handle_status_irq(struct mtk_eth *eth) + { +- u32 status2 = mtk_r32(eth, MTK_INT_STATUS2); ++ u32 status2 = mtk_r32(eth, MTK_FE_INT_STATUS); + + if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) { + mtk_stats_update(eth); + mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF), +- MTK_INT_STATUS2); ++ MTK_FE_INT_STATUS); + } + } + +@@ -3588,7 +3600,7 @@ static void mtk_dma_free(struct mtk_eth *eth) + + static bool mtk_hw_reset_check(struct mtk_eth *eth) + { +- u32 val = mtk_r32(eth, MTK_INT_STATUS2); ++ u32 val = mtk_r32(eth, MTK_FE_INT_STATUS); + + return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || + (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 14c3ce16f733..e19a81d3b141 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -92,7 +92,7 @@ + #define RST_GL_PSE BIT(0) + + /* Frame Engine Interrupt Status Register */ +-#define MTK_INT_STATUS2 0x08 ++#define MTK_FE_INT_STATUS 0x08 + #define MTK_FE_INT_ENABLE 0x0c + #define MTK_FE_INT_FQ_EMPTY BIT(8) + #define MTK_FE_INT_TSO_FAIL BIT(12) +@@ -111,6 +111,14 @@ + /* Frame Engine Interrupt Grouping Register */ + #define MTK_FE_INT_GRP 0x20 + ++/* Frame Engine Interrupt Status 2 Register */ ++#define MTK_FE_INT_STATUS2 0x28 ++ ++/* Frame Engine LRO Auto-Learn Table Information */ ++#define MTK_FE_ALT_CF8 0x300 ++#define MTK_FE_ALT_SGL_CFC 0x304 ++#define MTK_FE_ALT_SEQ_CFC 0x308 ++ + /* CDMP Ingress Control Register */ + #define MTK_CDMQ_IG_CTRL 0x1400 + #define MTK_CDMQ_STAG_EN BIT(0) +@@ -226,6 +234,13 @@ + #define MTK_RSS_INDR_TABLE_DW(x) (reg_map->pdma.rss_glo_cfg + 0x50 + \ + ((x) * 0x4)) + ++/* PDMA HW LRO ALT Debug Registers */ ++#define MTK_LRO_ALT_DBG 0xc40 ++#define MTK_LRO_ALT_INDEX_OFFSET (8) ++ ++/* PDMA HW LRO ALT Data Registers */ ++#define MTK_LRO_ALT_DBG_DATA 0xc44 ++ + /* PDMA Global Configuration Register */ + #define MTK_PDMA_LRO_SDL 0x3000 + #define MTK_RX_CFG_SDL_OFFSET 16 +@@ -269,7 +284,29 @@ + #define MTK_RING_MAX_AGG_CNT_L ((MTK_HW_LRO_MAX_AGG_CNT & 0x3f) << 26) + #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) + ++/* PDMA HW LRO Ring Control Mask */ ++#define MTK_LRO_RING_AGG_CNT_H_MASK GENMASK(1, 0) ++#define MTK_LRO_RING_AGG_TIME_MASK GENMASK(25, 10) ++#define MTK_LRO_RING_AGG_CNT_L_MASK GENMASK(31, 26) ++#define MTK_LRO_RING_AGE_TIME_H_MASK GENMASK(5, 0) ++#define MTK_LRO_RING_AGE_TIME_L_MASK GENMASK(31, 22) ++ ++/* PDMA HW LRO Ring Control 1 Offsets */ ++#define MTK_LRO_RING_AGE_TIME_L_OFFSET (22) ++ ++/* PDMA HW LRO Ring Control 2 Offsets */ ++#define MTK_LRO_RING_AGE_TIME_H_OFFSET (0) ++#define MTK_LRO_RING_RX_MODE_OFFSET (6) ++#define MTK_LRO_RING_RX_PORT_VLD_OFFSET (8) ++#define MTK_LRO_RING_AGG_TIME_OFFSET (10) ++#define MTK_LRO_RING_AGG_CNT_L_OFFSET (26) ++ ++/* PDMA HW LRO Ring Control 3 Offsets */ ++#define MTK_LRO_RING_AGG_CNT_H_OFFSET (0) ++ + /* QDMA TX Queue Configuration Registers */ ++#define MTK_QTX_CFG_HW_RESV GENMASK(15, 8) ++#define MTK_QTX_CFG_SW_RESV GENMASK(7, 0) + #define MTK_QTX_OFFSET 0x10 + #define QDMA_RES_THRES 4 + +@@ -287,8 +324,19 @@ + #define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4) + #define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0) + ++/* QDMA Page Configuration Register */ ++#define MTK_QTX_PER_PAGE (16) ++ ++/* QDMA TX Queue MIB Interface Register */ ++#define MTK_MIB_ON_QTX_CFG BIT(31) ++#define MTK_VQTX_MIB_EN BIT(28) ++ + /* QDMA TX Scheduler Rate Control Register */ ++#define MTK_QDMA_TX_SCH GENMASK(15, 0) + #define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15) ++#define MTK_QDMA_TX_SCH_RATE_EN BIT(11) ++#define MTK_QDMA_TX_SCH_RATE_MAN GENMASK(10, 4) ++#define MTK_QDMA_TX_SCH_RATE_EXP GENMASK(3, 0) + + /* QDMA Global Configuration Register */ + #define MTK_RX_2B_OFFSET BIT(31) +@@ -424,6 +472,10 @@ + #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ + #define RX_DMA_SPECIAL_TAG BIT(22) + ++/* PDMA descriptor rxd2 */ ++#define RX_DMA_GET_AGG_CNT GENMASK(9, 2) ++#define RX_DMA_GET_REV GENMASK(15, 10) ++ + /* PDMA descriptor rxd5 */ + #define MTK_RXD5_FOE_ENTRY GENMASK(14, 0) + #define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18) +@@ -438,6 +490,10 @@ + + #define MTK_TDMA_GLO_CFG 0x6204 + ++/* PDMA V2 descriptor rxd6 */ ++#define RX_DMA_GET_FLUSH_RSN_V2 GENMASK(2, 0) ++#define RX_DMA_GET_AGG_CNT_V2 GENMASK(23, 16) ++ + /* PHY Polling and SMI Master Control registers */ + #define MTK_PPSC 0x10000 + #define PPSC_MDC_CFG GENMASK(29, 24) +@@ -1286,14 +1342,18 @@ struct mtk_reg_map { + u32 rx_ptr; /* rx base pointer */ + u32 rx_cnt_cfg; /* rx max count configuration */ + u32 qcrx_ptr; /* rx cpu pointer */ ++ u32 page; /* page configuration */ + u32 glo_cfg; /* global configuration */ + u32 rst_idx; /* reset index */ + u32 delay_irq; /* delay interrupt */ + u32 fc_th; /* flow control */ + u32 int_grp; ++ u32 fsm; + u32 hred; /* interrupt mask */ ++ u32 qtx_mib_if; /* tx queue mib interface */ + u32 ctx_ptr; /* tx acquire cpu pointer */ + u32 dtx_ptr; /* tx acquire dma pointer */ ++ u32 fwd_count; /* tx forward count */ + u32 crx_ptr; /* tx release cpu pointer */ + u32 drx_ptr; /* tx release dma pointer */ + u32 fq_head; /* fq head pointer */ +@@ -1640,6 +1700,10 @@ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); + u32 mtk_r32(struct mtk_eth *eth, unsigned reg); + u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); + ++int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg); ++int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, ++ u32 write_data); ++ + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0080-enable-debugfs.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0080-enable-debugfs.patch new file mode 100644 index 000000000..88344c0ca --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0080-enable-debugfs.patch @@ -0,0 +1,52 @@ +From 59da261a6f057fd191d56b4171dcc12f7b6bd077 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 18 Jan 2025 15:59:43 +0100 +Subject: [PATCH 80/84] enable debugfs + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 045619d37d83..84ab560a1b80 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -32,6 +32,7 @@ + #include + + #include "mtk_eth_soc.h" ++#include "mtk_eth_dbg.h" + #include "mtk_wed.h" + + static int mtk_msg_level = -1; +@@ -384,7 +385,7 @@ int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, + return 0; + } + +-static int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr, ++int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr, + u32 devad, u32 phy_reg, u32 write_data) + { + int ret; +@@ -442,7 +443,7 @@ int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg) + return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK; + } + +-static int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr, ++int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr, + u32 devad, u32 phy_reg) + { + int ret; +@@ -5913,6 +5914,9 @@ static int mtk_probe(struct platform_device *pdev) + } + } + ++ mtketh_debugfs_init(eth); ++ debug_proc_init(eth); ++ + platform_set_drvdata(pdev, eth); + schedule_delayed_work(ð->reset.monitor_work, + MTK_DMA_MONITOR_TIMEOUT); +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0081-net-mediatek-mtk_eth_soc-add-RSS-capabilty-for-mt798.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0081-net-mediatek-mtk_eth_soc-add-RSS-capabilty-for-mt798.patch new file mode 100644 index 000000000..43bac070d --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0081-net-mediatek-mtk_eth_soc-add-RSS-capabilty-for-mt798.patch @@ -0,0 +1,31 @@ +From 9e860e36b0a842cb3de4136cde7258b34caf3564 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 12 Jul 2025 14:59:51 +0200 +Subject: [PATCH 81/84] net: mediatek: mtk_eth_soc: add RSS capabilty for + mt798[16] + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index e19a81d3b141..0cb99f1c1772 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1281,11 +1281,11 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) + + #define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ + MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0082-net-mediatek-mtk_eth_soc-enable-lro-stats-from-debug.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0082-net-mediatek-mtk_eth_soc-enable-lro-stats-from-debug.patch new file mode 100644 index 000000000..586c54e8c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0082-net-mediatek-mtk_eth_soc-enable-lro-stats-from-debug.patch @@ -0,0 +1,53 @@ +From cc6820376ccbacfcf7a495b3d6817c1c7e916f3e Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 7 Mar 2025 13:14:20 +0100 +Subject: [PATCH 82/84] net: mediatek: mtk_eth_soc: enable lro stats from + debugfs + +echo 4 1 > /proc/mtketh/hw_lro_auto_tlb #enable rings +echo 5 1 > /proc/mtketh/hw_lro_auto_tlb #enable statistics +cat /proc/mtketh/hw_lro_stats + +had to disable CONFIG_STRICT_DEVMEM for register values + +root@bpi-r4-v11:~ +busybox devmem 0x15106C54 #LRO2_RING1_DIP_DW0 Destination IP address +0xC0A80101 #192.168.1.1 +root@bpi-r4-v11:~ +busybox devmem 0x15106C58 #LRO2_RING1_DIP_DW1 Destination IP address +0x00000000 +root@bpi-r4-v11:~ +busybox devmem 0x15106C5C #LRO2_RING1_DIP_DW2 Destination IP address +0x00000000 +root@bpi-r4-v11:~ +busybox devmem 0x15106C60 LRO2_RING1_DIP_DW3 Destination IP address +0x00000000 +root@bpi-r4-v11:~ +busybox devmem 0x15106c7c +0x00002BC0 +=LRO2_RING1_CTRL_DW2 LRO2_MAX_AGGREGATED_CNT_L = 0x00002BC0 (bit8 = 1 and bit9 = 1) +means that both DIP and flow information have been enabled. +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 84ab560a1b80..a500ac80e715 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2393,6 +2393,12 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) + mtk_ppe_check_skb(eth->ppe[ppe_idx], skb, hash); + ++ if (eth->hwlro && mtk_hwlro_stats_ebl && ++ IS_HW_LRO_RING(ring->ring_no)) { ++ hw_lro_stats_update(ring->ring_no, &trxd); ++ hw_lro_flush_stats_update(ring->ring_no, &trxd); ++ } ++ + skb_record_rx_queue(skb, 0); + napi_gro_receive(napi, skb); + +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0083-net-mediatek-change-mt7986-from-RSS-to-LRO-only-1-po.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0083-net-mediatek-change-mt7986-from-RSS-to-LRO-only-1-po.patch new file mode 100644 index 000000000..9f8e21f65 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0083-net-mediatek-change-mt7986-from-RSS-to-LRO-only-1-po.patch @@ -0,0 +1,78 @@ +From 2cd641be6c6440c61c1f730722dab5e359acf6da Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 12 Apr 2025 14:36:54 +0200 +Subject: [PATCH 83/84] net: mediatek change mt7986 from RSS to LRO (only 1 + possible) - untested + +https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/30c22fcf9e2dd7d04e630969557c8ef3e96bf451 +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 ++++++++------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- + 2 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index a500ac80e715..eef833f1cd06 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3036,11 +3036,6 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + + lro_ctrl_dw0 |= MTK_PDMA_LRO_SDL << MTK_CTRL_DW0_SDL_OFFSET; + +- /* enable cpu reason black list */ +- lro_ctrl_dw0 |= MTK_LRO_CRSN_BNW; +- +- /* no use PPE cpu reason */ +- mtk_w32(eth, 0xffffffff, MTK_PDMA_LRO_CTRL_DW1); + } else { + /* set HW LRO mode & the max aggregation count for rx packets */ + lro_ctrl_dw3 |= MTK_ADMA_MODE | (MTK_HW_LRO_MAX_AGG_CNT & 0xff); +@@ -3052,9 +3047,15 @@ static int mtk_hwlro_rx_init(struct mtk_eth *eth) + /* enable HW LRO */ + lro_ctrl_dw0 |= MTK_LRO_EN; + ++ /* enable cpu reason black list */ ++ lro_ctrl_dw0 |= MTK_LRO_CRSN_BNW; ++ + mtk_w32(eth, lro_ctrl_dw3, MTK_PDMA_LRO_CTRL_DW3); + mtk_w32(eth, lro_ctrl_dw0, MTK_PDMA_LRO_CTRL_DW0); + ++ /* no use PPE cpu reason */ ++ mtk_w32(eth, 0xffffffff, MTK_PDMA_LRO_CTRL_DW1); ++ + if (mtk_is_netsys_v2_or_greater(eth)) { + i = (soc->rx.desc_size == sizeof(struct mtk_rx_dma_v2)) ? 1 : 0; + mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)), +@@ -6142,7 +6143,7 @@ static const struct mtk_soc_data mt7981_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .dma_l4_valid = RX_DMA_L4_VALID_V2, ++ .dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, + .dma_size = MTK_DMA_SIZE(2K), +@@ -6172,7 +6173,7 @@ static const struct mtk_soc_data mt7986_data = { + }, + .rx = { + .desc_size = sizeof(struct mtk_rx_dma), +- .dma_l4_valid = RX_DMA_L4_VALID_V2, ++ .dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, + .dma_size = MTK_DMA_SIZE(2K), +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 0cb99f1c1772..5ecd6381ad6e 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1285,7 +1285,7 @@ enum mkt_eth_capabilities { + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_RSS) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_PDMA_INT | MTK_HWLRO) + + #define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ + MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/0084-net-mediatek-mtk_eth_soc-check-if-irqs-were-loaded-t.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/0084-net-mediatek-mtk_eth_soc-check-if-irqs-were-loaded-t.patch new file mode 100644 index 000000000..62f4ab4c4 --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/0084-net-mediatek-mtk_eth_soc-check-if-irqs-were-loaded-t.patch @@ -0,0 +1,47 @@ +From 2c586e5b7bf54b2f94ffc6bb00618afad3725cf8 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 12 Jul 2025 15:45:22 +0200 +Subject: [PATCH 84/84] net: mediatek: mtk_eth_soc: check if irqs were loaded + to keep backwards compatibility + +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index eef833f1cd06..106bbeb21ea0 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3340,6 +3340,11 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev, + return 0; + } + ++static bool mtk_rss_available(struct mtk_eth *eth) ++{ ++ return (eth->soc->rss_num && eth->irq_pdma[eth->soc->rss_num - 1]>=0); ++} ++ + static u32 mtk_rss_indr_table(struct mtk_rss_params *rss_params, int index) + { + u32 val = 0; +@@ -4620,7 +4625,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) + mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp); + mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->qdma.int_grp + 4); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) { ++ if (mtk_rss_available(eth)) { + mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP); + } else { + mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); +@@ -5805,7 +5810,7 @@ static int mtk_probe(struct platform_device *pdev) + if (err) + goto err_free_dev; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) { ++ if (mtk_rss_available(eth)) { + irqname = devm_kasprintf(eth->dev, GFP_KERNEL, "%s PDMA RX %d", + dev_name(eth->dev), 0); + err = devm_request_irq(eth->dev, eth->irq_pdma[0], +-- +2.30.2 + diff --git a/patch/kernel/archive/filogic-6.16/patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch b/patch/kernel/archive/filogic-6.16/patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch index 7e22fa54d..f86ff9e77 100644 --- a/patch/kernel/archive/filogic-6.16/patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch +++ b/patch/kernel/archive/filogic-6.16/patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch @@ -13,12 +13,10 @@ Signed-off-by: tabrisnet 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile -index d728953c10ad..15041f497529 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile -@@ -19,14 +19,24 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo +@@ -21,10 +21,20 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb #dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb @@ -39,11 +37,7 @@ index d728953c10ad..15041f497529 100644 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb - #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb - #dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb -@@ -108,7 +118,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb - - # Device tree overlays support +@@ -110,5 +120,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@ DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@ DTC_FLAGS_mt7988a-bananapi-bpi-r4 := -@ @@ -52,4 +46,5 @@ index d728953c10ad..15041f497529 100644 DTC_FLAGS_mt7988a-bananapi-bpi-r4-2g5 := -@ DTC_FLAGS_mt8395-radxa-nio-12l := -@ -- -Created with Armbian build tools https://github.com/armbian/build +Armbian + diff --git a/patch/kernel/archive/filogic-6.16/series.armbian b/patch/kernel/archive/filogic-6.16/series.armbian deleted file mode 100644 index 757c5f0a0..000000000 --- a/patch/kernel/archive/filogic-6.16/series.armbian +++ /dev/null @@ -1,7 +0,0 @@ -# -# This file is made manually by simply copying text -# from the target series.* files. -# Add (-) at the beginning of the line if the patch should not be applied. -# At the same time, the patch does not need to be deleted. -# - patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch diff --git a/patch/kernel/archive/filogic-6.16/series.armbian b/patch/kernel/archive/filogic-6.16/series.armbian new file mode 120000 index 000000000..491b6449c --- /dev/null +++ b/patch/kernel/archive/filogic-6.16/series.armbian @@ -0,0 +1 @@ +series.conf \ No newline at end of file diff --git a/patch/kernel/archive/filogic-6.16/series.conf b/patch/kernel/archive/filogic-6.16/series.conf index 757c5f0a0..0fedd0533 100644 --- a/patch/kernel/archive/filogic-6.16/series.conf +++ b/patch/kernel/archive/filogic-6.16/series.conf @@ -4,4 +4,97 @@ # Add (-) at the beginning of the line if the patch should not be applied. # At the same time, the patch does not need to be deleted. # + +# patch series derived from: +# `git format-patch -o ~/build/armbian-build/patch/kernel/archive/filogic-6.16/patches.armbian/ v6.16.12..6.16.12-rsslro` +# where 6.16.12-rsslro was from taking https://github.com/frank-w/BPI-Router-Linux branch:6.16-rsslro +# then `git rebase v6.16.12` where this tag was from https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git tag:v6.16.12 +# two patches are then skipped for being empty, 0001 & 0017 + + -patches.armbian/0001-v6-coverletter-net-next-rework-IRQ-handling-in-mtk_e.patch + patches.armbian/0002-net-ethernet-mtk_eth_soc-support-named-IRQs.patch + patches.armbian/0003-net-ethernet-mtk_eth_soc-add-consts-for-irq-index.patch + patches.armbian/0004-net-ethernet-mtk_eth_soc-skip-first-IRQ-if-not-used.patch + patches.armbian/0005-net-ethernet-mtk_eth_soc-only-use-legacy-mode-on-mis.patch + patches.armbian/0006-build.sh-add-build-script-config-defconfig-and-fit-s.patch + patches.armbian/0007-build.sh-add-additional-build-script-config-defconfi.patch + patches.armbian/0008-defconfig-r3-fix-warning-about-BASE_SMALL.patch + patches.armbian/0009-build.conf-change-upload-target.patch + patches.armbian/0010-arm-dts-mt7623-swap-mmc-and-put-uart2-first.patch + patches.armbian/0011-arm64-dts-disable-dtbs-for-dtbs_check.patch + patches.armbian/0012-dt-bindings-interconnect-add-mt7988-cci-compatible.patch + patches.armbian/0013-arm64-dts-mediatek-mt7988-add-cci-node.patch + patches.armbian/0014-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch + patches.armbian/0015-arm64-dts-mediatek-mt7988a-bpi-r4-drop-unused-pins.patch + patches.armbian/0016-arm64-dts-mediatek-mt7988a-bpi-r4-add-gpio-leds.patch + -patches.armbian/0017-v9-coverletter-further-mt7988-devicetree-work.patch + patches.armbian/0018-dt-bindings-net-mediatek-net-update-mac-subnode-patt.patch + patches.armbian/0019-dt-bindings-net-mediatek-net-allow-up-to-8-IRQs.patch + patches.armbian/0020-dt-bindings-net-mediatek-net-allow-irq-names.patch + patches.armbian/0021-dt-bindings-net-mediatek-net-add-sram-property.patch + patches.armbian/0022-dt-bindings-net-dsa-mediatek-mt7530-add-dsa-port-def.patch + patches.armbian/0023-dt-bindings-net-dsa-mediatek-mt7530-add-internal-mdi.patch + patches.armbian/0024-arm64-dts-mediatek-mt7986-add-sram-node.patch + patches.armbian/0025-arm64-dts-mediatek-mt7986-add-interrupts-for-RSS-and.patch + patches.armbian/0026-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch + patches.armbian/0027-arm64-dts-mediatek-mt7988-add-switch-node.patch + patches.armbian/0028-arm64-dts-mediatek-mt7988a-bpi-r4-add-aliases-for-et.patch + patches.armbian/0029-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-.patch + patches.armbian/0030-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-p.patch + patches.armbian/0031-arm64-dts-mediatek-mt7988a-bpi-r4-drop-readonly-from.patch + patches.armbian/0032-dt-bindings-net-pcs-mediatek-sgmiisys-add-phys-and-r.patch + patches.armbian/0033-dt-binding-sgmiisys-re-add-pcs-cells.patch + patches.armbian/0034-dts-re-add-sgmiisys.patch + patches.armbian/0035-arm64-dts-mt7988-add-cpufreq-calibration-efuse-subno.patch + patches.armbian/0036-net-ethernet-mtk_eth_soc-move-desc-assignment-below-.patch + patches.armbian/0037-dts-enable-mt818-36-for-cci-testing.patch + patches.armbian/0038-Revert-dts-enable-mt818-36-for-cci-testing.patch + patches.armbian/0039-enable-bpi-r3-DTBs-for-testing.patch + patches.armbian/0040-only-enable-mediatek-for-arm-to-increase-dtbs_check.patch + patches.armbian/0041-enable-some-arm64-dts-to-check-binding.patch + patches.armbian/0042-defconfig-r4-add-sram-driver.patch + patches.armbian/0043-net-ethernet-mtk_eth_soc-improve-support-for-named-i.patch + patches.armbian/0044-net-ethernet-mtk_eth_soc-fix-kernel-doc-comment.patch + patches.armbian/0045-net-ethernet-mtk_eth_soc-use-generic-allocator-for-S.patch + patches.armbian/0046-defconfig-r3-add-sram.patch + patches.armbian/0047-WIP-dts64-r4-add-ubi-partition-to-spin-nand.patch + patches.armbian/0048-add-mtd-rw-driver.patch + patches.armbian/0049-arm64-dts-add-usxgmii-pcs-and-link-both-pcs.patch + patches.armbian/0050-arm64-dts-update-bpi-r4.dtsi-to-actual-state.patch + patches.armbian/0051-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch + patches.armbian/0052-net-phylink-keep-and-use-MAC-supported_interfaces-in.patch + patches.armbian/0053-net-phy-introduce-phy_interface_copy-helper.patch + patches.armbian/0054-net-phylink-introduce-internal-phylink-PCS-handling.patch + patches.armbian/0055-net-phylink-add-phylink_release_pcs-to-externally-re.patch + patches.armbian/0056-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch + patches.armbian/0057-net-phylink-support-late-PCS-provider-attach.patch + patches.armbian/0058-dt-bindings-net-ethernet-controller-permit-to-define.patch + patches.armbian/0059-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch + patches.armbian/0060-dt-bindings-net-pcs-Document-support-for-Airoha-Ethe.patch + patches.armbian/0061-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch + patches.armbian/0062-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch + patches.armbian/0063-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch + patches.armbian/0064-net-ethernet-mtk_eth_soc-add-more-DMA-monitor-for-MT.patch + patches.armbian/0065-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch + patches.armbian/0066-dts64-enable-sata-and-disable-pcie-slot-CN8-shared.patch + patches.armbian/0067-arm64-dts-mt7622-fix-sata.patch + patches.armbian/0068-kdeb-try-to-add-kernels-for-bpi-boards-to-deb-packag.patch + patches.armbian/0069-kdeb-fix-deb-build-for-R3-R4.patch + patches.armbian/0070-build.conf-change-to-r4.patch + patches.armbian/0071-defconfig-r4-disable-STRICT_DEVMEM-to-allow-register.patch + patches.armbian/0072-net-ethernet-mtk_eth_soc-add-register-definitions-fo.patch + patches.armbian/0073-net-ethernet-mtk_eth_soc-add-rss-support.patch + patches.armbian/0074-net-mediatek-mtk_eth_soc-drop-RSS-capabilty-for-mt79.patch + patches.armbian/0075-net-mtk_eth_soc-fix-mtk_-get-set-_rxfh-callback-head.patch + patches.armbian/0076-net-ethernet-mtk_eth_soc-Add-LRO-support.patch + patches.armbian/0077-readme-add-README.md-for-RSS-LRO.patch + patches.armbian/0078-net-ethernet-mtk_eth_soc-support-forced-reset-contro.patch + patches.armbian/0079-net-mediatek-add-proprietary-debugfs.patch + patches.armbian/0080-enable-debugfs.patch + patches.armbian/0081-net-mediatek-mtk_eth_soc-add-RSS-capabilty-for-mt798.patch + patches.armbian/0082-net-mediatek-mtk_eth_soc-enable-lro-stats-from-debug.patch + patches.armbian/0083-net-mediatek-change-mt7986-from-RSS-to-LRO-only-1-po.patch + patches.armbian/0084-net-mediatek-mtk_eth_soc-check-if-irqs-were-loaded-t.patch +# this patch is not from frank-w's tree, but rather is an adaptation to the armbian build framework +# vs the OpenWRT framework's method of building the relevant FDTs as used by the bootloader. patches.armbian/mt7988a-bananapi-bpi-r4-sd.patch diff --git a/patch/kernel/archive/meson64-6.12/dt/meson-gxl-s905x-bestv-r3300-l.dts b/patch/kernel/archive/meson64-6.12/dt/meson-gxl-s905x-bestv-r3300-l.dts new file mode 100644 index 000000000..8f706faf4 --- /dev/null +++ b/patch/kernel/archive/meson64-6.12/dt/meson-gxl-s905x-bestv-r3300-l.dts @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 retro98boy + */ + +/dts-v1/; + +#include "meson-gxl-s905x-p212.dtsi" +#include +#include +#include + +/ { + compatible = "bestv,r3300-l", "amlogic,s905x", "amlogic,meson-gxl"; + model = "BesTV R3300-L"; + + aliases { + rtc1 = &vrtc; + }; + + memory@0 { + reg = <0x0 0x0 0x0 0x40000000>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + rst-btn { + label = "rst-btn"; + linux,code = ; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + /* + * The power LED on the device is always on, defaulting to red. + * Pulling GPIODV_24 high changes it to green, indicating that the kernel has started. + */ + pwr-led-green { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + /* + * GPIOAO_4 is used to turn on the WLAN LED, defaulting to red, + * and GPIODV_27 is used to change the color of the WLAN LED. + */ + wlan-led-red { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + /* + * modprobe ledtrig-netdev + * echo netdev > /sys/class/leds/green\:wlan/trigger + * echo wlan0 > /sys/class/leds/green\:wlan/device_name + * + * echo 1 > /sys/class/leds/green\:wlan/link + * or + * echo 1 > /sys/class/leds/green\:wlan/rx + */ + wlan-led-green { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "netdev"; + }; + }; + + dio2128: analog-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "AU2"; + VCC-supply = <&hdmi_5v>; + enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; + }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "S905X-P212"; + audio-aux-devs = <&dio2128>; + audio-widgets = "Line", "Lineout"; + audio-routing = "AU2 INL", "ACODEC LOLN", + "AU2 INR", "ACODEC LORN", + "Lineout", "AU2 OUTL", + "Lineout", "AU2 OUTR"; + clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + + codec-1 { + sound-dai = <&aiu AIU_ACODEC CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + + dai-link-3 { + sound-dai = <&aiu AIU_ACODEC CTRL_OUT>; + + codec-0 { + sound-dai = <&acodec>; + }; + }; + }; +}; + +&acodec { + AVDD-supply = <&vddio_ao18>; + status = "okay"; +}; + +&aiu { + status = "okay"; +}; + +&brcmf { + /delete-property/ compatible; +}; + +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; + +&emmc_pwrseq { + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; /* not sure */ +}; + +&hdmi_5v { + /delete-property/ gpio; + /delete-property/ enable-active-high; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; + hdmi-supply = <&hdmi_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&sd_emmc_b { + max-frequency = <200000000>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; +}; + +&sd_emmc_c { + mmc-hs400-1_8v; +}; + +&uart_A { + status = "disabled"; + /delete-node/ bluetooth; +}; + +&usb { + dr_mode = "otg"; +}; diff --git a/patch/kernel/archive/meson64-6.17/0000.patching_config.yaml b/patch/kernel/archive/meson64-6.18/0000.patching_config.yaml similarity index 100% rename from patch/kernel/archive/meson64-6.17/0000.patching_config.yaml rename to patch/kernel/archive/meson64-6.18/0000.patching_config.yaml diff --git a/patch/kernel/archive/meson64-6.17/board-bananapi-cm4-cm4io.patch b/patch/kernel/archive/meson64-6.18/board-bananapi-cm4-cm4io.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-bananapi-cm4-cm4io.patch rename to patch/kernel/archive/meson64-6.18/board-bananapi-cm4-cm4io.patch diff --git a/patch/kernel/archive/meson64-6.17/board-bananapi-m2s.patch b/patch/kernel/archive/meson64-6.18/board-bananapi-m2s.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-bananapi-m2s.patch rename to patch/kernel/archive/meson64-6.18/board-bananapi-m2s.patch diff --git a/patch/kernel/archive/meson64-6.17/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch b/patch/kernel/archive/meson64-6.18/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch similarity index 95% rename from patch/kernel/archive/meson64-6.17/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch rename to patch/kernel/archive/meson64-6.18/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch index 5258c6c69..3d4f8ee41 100644 --- a/patch/kernel/archive/meson64-6.17/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch +++ b/patch/kernel/archive/meson64-6.18/board-bananapim5-001-sd-use-270-mmc-clock-phase-via-dt.patch @@ -22,7 +22,7 @@ index 111111111111..222222222222 100644 / { adc-keys { -@@ -388,6 +389,8 @@ &sd_emmc_b { +@@ -387,6 +388,8 @@ &sd_emmc_b { cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&tflash_vdd>; vqmmc-supply = <&vddio_c>; @@ -31,7 +31,7 @@ index 111111111111..222222222222 100644 }; /* eMMC */ -@@ -407,6 +410,8 @@ &sd_emmc_c { +@@ -406,6 +409,8 @@ &sd_emmc_c { mmc-pwrseq = <&emmc_pwrseq>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&emmc_1v8>; diff --git a/patch/kernel/archive/meson64-6.17/board-bananapim5-002-add-wifi-bt-support.patch b/patch/kernel/archive/meson64-6.18/board-bananapim5-002-add-wifi-bt-support.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-bananapim5-002-add-wifi-bt-support.patch rename to patch/kernel/archive/meson64-6.18/board-bananapim5-002-add-wifi-bt-support.patch diff --git a/patch/kernel/archive/meson64-6.17/board-bananapism1-add-uart_A-and-AO_B.patch b/patch/kernel/archive/meson64-6.18/board-bananapism1-add-uart_A-and-AO_B.patch similarity index 98% rename from patch/kernel/archive/meson64-6.17/board-bananapism1-add-uart_A-and-AO_B.patch rename to patch/kernel/archive/meson64-6.18/board-bananapism1-add-uart_A-and-AO_B.patch index cc5e83d4e..9771f2a5e 100644 --- a/patch/kernel/archive/meson64-6.17/board-bananapism1-add-uart_A-and-AO_B.patch +++ b/patch/kernel/archive/meson64-6.18/board-bananapism1-add-uart_A-and-AO_B.patch @@ -69,7 +69,7 @@ index 111111111111..222222222222 100644 ethernet0 = ðmac; }; -@@ -420,6 +421,12 @@ &uart_AO { +@@ -419,6 +420,12 @@ &uart_AO { pinctrl-names = "default"; }; diff --git a/patch/kernel/archive/meson64-6.17/board-khadas-vim3-add-npu-node.patch b/patch/kernel/archive/meson64-6.18/board-khadas-vim3-add-npu-node.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-khadas-vim3-add-npu-node.patch rename to patch/kernel/archive/meson64-6.18/board-khadas-vim3-add-npu-node.patch diff --git a/patch/kernel/archive/meson64-6.17/board-khadas-vim3-fix-missing-i2c3-nod.patch b/patch/kernel/archive/meson64-6.18/board-khadas-vim3-fix-missing-i2c3-nod.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-khadas-vim3-fix-missing-i2c3-nod.patch rename to patch/kernel/archive/meson64-6.18/board-khadas-vim3-fix-missing-i2c3-nod.patch diff --git a/patch/kernel/archive/meson64-6.17/board-khadas-vims-add-rtc-vrtc-aliases.patch b/patch/kernel/archive/meson64-6.18/board-khadas-vims-add-rtc-vrtc-aliases.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-khadas-vims-add-rtc-vrtc-aliases.patch rename to patch/kernel/archive/meson64-6.18/board-khadas-vims-add-rtc-vrtc-aliases.patch diff --git a/patch/kernel/archive/meson64-6.17/board-nanopi-k2-add-uartC-alias.patch b/patch/kernel/archive/meson64-6.18/board-nanopi-k2-add-uartC-alias.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-nanopi-k2-add-uartC-alias.patch rename to patch/kernel/archive/meson64-6.18/board-nanopi-k2-add-uartC-alias.patch diff --git a/patch/kernel/archive/meson64-6.17/board-nanopi-k2-enable-emmc.patch b/patch/kernel/archive/meson64-6.18/board-nanopi-k2-enable-emmc.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-nanopi-k2-enable-emmc.patch rename to patch/kernel/archive/meson64-6.18/board-nanopi-k2-enable-emmc.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroid-sm1-reset.patch b/patch/kernel/archive/meson64-6.18/board-odroid-sm1-reset.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroid-sm1-reset.patch rename to patch/kernel/archive/meson64-6.18/board-odroid-sm1-reset.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroidc2-add-uartA-uartC.patch b/patch/kernel/archive/meson64-6.18/board-odroidc2-add-uartA-uartC.patch similarity index 97% rename from patch/kernel/archive/meson64-6.17/board-odroidc2-add-uartA-uartC.patch rename to patch/kernel/archive/meson64-6.18/board-odroidc2-add-uartA-uartC.patch index 1a6cbae6d..9388fecc5 100644 --- a/patch/kernel/archive/meson64-6.17/board-odroidc2-add-uartA-uartC.patch +++ b/patch/kernel/archive/meson64-6.18/board-odroidc2-add-uartA-uartC.patch @@ -26,7 +26,7 @@ index 111111111111..222222222222 100644 ethernet0 = ðmac; }; -@@ -387,6 +389,18 @@ &uart_AO { +@@ -383,6 +385,18 @@ &uart_AO { pinctrl-names = "default"; }; diff --git a/patch/kernel/archive/meson64-6.17/board-odroidc2-enable-SPI.patch b/patch/kernel/archive/meson64-6.18/board-odroidc2-enable-SPI.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroidc2-enable-SPI.patch rename to patch/kernel/archive/meson64-6.18/board-odroidc2-enable-SPI.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroidc2-enable-scpi-dvfs.patch b/patch/kernel/archive/meson64-6.18/board-odroidc2-enable-scpi-dvfs.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroidc2-enable-scpi-dvfs.patch rename to patch/kernel/archive/meson64-6.18/board-odroidc2-enable-scpi-dvfs.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroidc2-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch b/patch/kernel/archive/meson64-6.18/board-odroidc2-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroidc2-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch rename to patch/kernel/archive/meson64-6.18/board-odroidc2-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroidhc4-enable-fan1_input.patch b/patch/kernel/archive/meson64-6.18/board-odroidhc4-enable-fan1_input.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroidhc4-enable-fan1_input.patch rename to patch/kernel/archive/meson64-6.18/board-odroidhc4-enable-fan1_input.patch diff --git a/patch/kernel/archive/meson64-6.17/board-odroidn2plus-Add-missing-CPU-opp.patch b/patch/kernel/archive/meson64-6.18/board-odroidn2plus-Add-missing-CPU-opp.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-odroidn2plus-Add-missing-CPU-opp.patch rename to patch/kernel/archive/meson64-6.18/board-odroidn2plus-Add-missing-CPU-opp.patch diff --git a/patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-add-aliases-for-serial-i2c-and-spi.patch b/patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-add-aliases-for-serial-i2c-and-spi.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-add-aliases-for-serial-i2c-and-spi.patch rename to patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-add-aliases-for-serial-i2c-and-spi.patch diff --git a/patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-add-support-for-the-usb-c-controller.patch b/patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-add-support-for-the-usb-c-controller.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-add-support-for-the-usb-c-controller.patch rename to patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-add-support-for-the-usb-c-controller.patch diff --git a/patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-slow-down-sdio-for-working-emmc.patch b/patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-slow-down-sdio-for-working-emmc.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-slow-down-sdio-for-working-emmc.patch rename to patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-slow-down-sdio-for-working-emmc.patch diff --git a/patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-slow-down-sdio-for-working-wifi.patch b/patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-slow-down-sdio-for-working-wifi.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-radxa-zero-dts-slow-down-sdio-for-working-wifi.patch rename to patch/kernel/archive/meson64-6.18/board-radxa-zero-dts-slow-down-sdio-for-working-wifi.patch diff --git a/patch/kernel/archive/meson64-6.17/board-radxa-zero2-arm64-dts-amlogic-Enable-the-npu-node-for-Radxa-Zero2.patch b/patch/kernel/archive/meson64-6.18/board-radxa-zero2-arm64-dts-amlogic-Enable-the-npu-node-for-Radxa-Zero2.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/board-radxa-zero2-arm64-dts-amlogic-Enable-the-npu-node-for-Radxa-Zero2.patch rename to patch/kernel/archive/meson64-6.18/board-radxa-zero2-arm64-dts-amlogic-Enable-the-npu-node-for-Radxa-Zero2.patch diff --git a/patch/kernel/archive/meson64-6.17/board-t95z-add-rc-remote-keymap.patch b/patch/kernel/archive/meson64-6.18/board-t95z-add-rc-remote-keymap.patch similarity index 99% rename from patch/kernel/archive/meson64-6.17/board-t95z-add-rc-remote-keymap.patch rename to patch/kernel/archive/meson64-6.18/board-t95z-add-rc-remote-keymap.patch index 8c138c7c3..21ddcf9d6 100644 --- a/patch/kernel/archive/meson64-6.17/board-t95z-add-rc-remote-keymap.patch +++ b/patch/kernel/archive/meson64-6.18/board-t95z-add-rc-remote-keymap.patch @@ -34,7 +34,7 @@ diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentat index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml -@@ -1504,6 +1504,8 @@ patternProperties: +@@ -1560,6 +1560,8 @@ patternProperties: description: Sundance DSP Inc. "^sunplus,.*": description: Sunplus Technology Co., Ltd. diff --git a/patch/kernel/archive/meson64-6.17/driver-power-meson64-reset.patch b/patch/kernel/archive/meson64-6.18/driver-power-meson64-reset.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/driver-power-meson64-reset.patch rename to patch/kernel/archive/meson64-6.18/driver-power-meson64-reset.patch diff --git a/patch/kernel/archive/meson64-6.17/drv-spi-spidev-remove-warnings.patch b/patch/kernel/archive/meson64-6.18/drv-spi-spidev-remove-warnings.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/drv-spi-spidev-remove-warnings.patch rename to patch/kernel/archive/meson64-6.18/drv-spi-spidev-remove-warnings.patch diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-axg-amper-gateway-am-gz80x.dts b/patch/kernel/archive/meson64-6.18/dt/meson-axg-amper-gateway-am-gz80x.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-axg-amper-gateway-am-gz80x.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-axg-amper-gateway-am-gz80x.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-axg-amper-gateway-gz80x.dtsi b/patch/kernel/archive/meson64-6.18/dt/meson-axg-amper-gateway-gz80x.dtsi similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-axg-amper-gateway-gz80x.dtsi rename to patch/kernel/archive/meson64-6.18/dt/meson-axg-amper-gateway-gz80x.dtsi diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12-enable-spinor.dtsi b/patch/kernel/archive/meson64-6.18/dt/meson-g12-enable-spinor.dtsi similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12-enable-spinor.dtsi rename to patch/kernel/archive/meson64-6.18/dt/meson-g12-enable-spinor.dtsi diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12a-radxa-zero-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12a-radxa-zero-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12a-radxa-zero-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12a-radxa-zero-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-cainiao-cniot-core.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-cainiao-cniot-core.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-cainiao-cniot-core.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-cainiao-cniot-core.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-khadas-vim3-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-khadas-vim3-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-khadas-vim3-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-khadas-vim3-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-khadas-vim3-spinor.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-khadas-vim3-spinor.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-a311d-khadas-vim3-spinor.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-a311d-khadas-vim3-spinor.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-plus-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-plus-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-plus-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-plus-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-plus-spinor.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-plus-spinor.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-plus-spinor.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-plus-spinor.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-spinor.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-spinor.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-odroid-n2-spinor.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-odroid-n2-spinor.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-radxa-zero2-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-radxa-zero2-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-radxa-zero2-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-radxa-zero2-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-g12b-waveshare-cm4-io-base-b.dts b/patch/kernel/archive/meson64-6.18/dt/meson-g12b-waveshare-cm4-io-base-b.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-g12b-waveshare-cm4-io-base-b.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-g12b-waveshare-cm4-io-base-b.dts diff --git a/patch/kernel/archive/meson64-6.18/dt/meson-gxl-s905x-bestv-r3300-l.dts b/patch/kernel/archive/meson64-6.18/dt/meson-gxl-s905x-bestv-r3300-l.dts new file mode 100644 index 000000000..d67705806 --- /dev/null +++ b/patch/kernel/archive/meson64-6.18/dt/meson-gxl-s905x-bestv-r3300-l.dts @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 retro98boy + */ + +/dts-v1/; + +#include "meson-gxl-s905x-p212.dtsi" +#include +#include +#include + +/ { + compatible = "bestv,r3300-l", "amlogic,s905x", "amlogic,meson-gxl"; + model = "BesTV R3300-L"; + + aliases { + rtc1 = &vrtc; + }; + + memory@0 { + reg = <0x0 0x0 0x0 0x40000000>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + rst-btn { + label = "rst-btn"; + linux,code = ; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + /* + * The power LED on the device is always on, defaulting to red. + * Pulling GPIODV_24 high changes it to green, indicating that the kernel has started. + */ + pwr-led-green { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + /* + * GPIOAO_4 is used to turn on the WLAN LED, defaulting to red, + * and GPIODV_27 is used to change the color of the WLAN LED. + */ + wlan-led-red { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + /* + * modprobe ledtrig-netdev + * echo netdev > /sys/class/leds/green\:wlan/trigger + * echo wlan0 > /sys/class/leds/green\:wlan/device_name + * + * echo 1 > /sys/class/leds/green\:wlan/link + * or + * echo 1 > /sys/class/leds/green\:wlan/rx + */ + wlan-led-green { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "netdev"; + }; + }; + + dio2128: analog-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "AU2"; + VCC-supply = <&hdmi_5v>; + enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; + }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "S905X-P212"; + audio-aux-devs = <&dio2128>; + audio-widgets = "Line", "Lineout"; + audio-routing = "AU2 INL", "ACODEC LOLN", + "AU2 INR", "ACODEC LORN", + "Lineout", "AU2 OUTL", + "Lineout", "AU2 OUTR"; + clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + + codec-1 { + sound-dai = <&aiu AIU_ACODEC CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + + dai-link-3 { + sound-dai = <&aiu AIU_ACODEC CTRL_OUT>; + + codec-0 { + sound-dai = <&acodec>; + }; + }; + }; +}; + +&acodec { + AVDD-supply = <&vddio_ao18>; + status = "okay"; +}; + +&aiu { + status = "okay"; +}; + +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; + +&emmc_pwrseq { + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; /* not sure */ +}; + +&hdmi_5v { + /delete-property/ gpio; + /delete-property/ enable-active-high; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; + hdmi-supply = <&hdmi_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&sd_emmc_b { + max-frequency = <200000000>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; +}; + +&sd_emmc_c { + mmc-hs400-1_8v; +}; + +&uart_A { + status = "disabled"; + /delete-node/ bluetooth; +}; + +&usb { + dr_mode = "otg"; +}; diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-gxm-c400-plus.dts b/patch/kernel/archive/meson64-6.18/dt/meson-gxm-c400-plus.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-gxm-c400-plus.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-gxm-c400-plus.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-gxm-mini-m8s-pro.dts b/patch/kernel/archive/meson64-6.18/dt/meson-gxm-mini-m8s-pro.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-gxm-mini-m8s-pro.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-gxm-mini-m8s-pro.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-gxm-t95z-plus.dts b/patch/kernel/archive/meson64-6.18/dt/meson-gxm-t95z-plus.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-gxm-t95z-plus.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-gxm-t95z-plus.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-jethome-jethub-j200-spinor.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-jethome-jethub-j200-spinor.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-jethome-jethub-j200-spinor.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-jethome-jethub-j200-spinor.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-jethome-jethub-j200.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-jethome-jethub-j200.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-jethome-jethub-j200.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-jethome-jethub-j200.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-khadas-vim3l-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-khadas-vim3l-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-khadas-vim3l-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-khadas-vim3l-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-khadas-vim3l-spinor.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-khadas-vim3l-spinor.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-khadas-vim3l-spinor.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-khadas-vim3l-spinor.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-odroid-c4-spidev.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-odroid-c4-spidev.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-odroid-c4-spidev.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-odroid-c4-spidev.dts diff --git a/patch/kernel/archive/meson64-6.17/dt/meson-sm1-ugoos-x3.dts b/patch/kernel/archive/meson64-6.18/dt/meson-sm1-ugoos-x3.dts similarity index 100% rename from patch/kernel/archive/meson64-6.17/dt/meson-sm1-ugoos-x3.dts rename to patch/kernel/archive/meson64-6.18/dt/meson-sm1-ugoos-x3.dts diff --git a/patch/kernel/archive/meson64-6.17/general-add-Amlogic-Meson-GX-PM-Suspend.patch b/patch/kernel/archive/meson64-6.18/general-add-Amlogic-Meson-GX-PM-Suspend.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-add-Amlogic-Meson-GX-PM-Suspend.patch rename to patch/kernel/archive/meson64-6.18/general-add-Amlogic-Meson-GX-PM-Suspend.patch diff --git a/patch/kernel/archive/meson64-6.17/general-add-overlay-compilation-support.patch b/patch/kernel/archive/meson64-6.18/general-add-overlay-compilation-support.patch similarity index 97% rename from patch/kernel/archive/meson64-6.17/general-add-overlay-compilation-support.patch rename to patch/kernel/archive/meson64-6.18/general-add-overlay-compilation-support.patch index 267fd37eb..75b5b3dd7 100644 --- a/patch/kernel/archive/meson64-6.17/general-add-overlay-compilation-support.patch +++ b/patch/kernel/archive/meson64-6.18/general-add-overlay-compilation-support.patch @@ -36,7 +36,7 @@ diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs index 111111111111..222222222222 100644 --- a/scripts/Makefile.dtbs +++ b/scripts/Makefile.dtbs -@@ -122,17 +122,23 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) +@@ -123,17 +123,23 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) quiet_cmd_dtc = DTC $(quiet_dtb_check_tag) $@ cmd_dtc = \ $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ diff --git a/patch/kernel/archive/meson64-6.17/general-driver-tm1628-auxdisplay-add-support-for-Titanmec-TM16.patch b/patch/kernel/archive/meson64-6.18/general-driver-tm1628-auxdisplay-add-support-for-Titanmec-TM16.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-driver-tm1628-auxdisplay-add-support-for-Titanmec-TM16.patch rename to patch/kernel/archive/meson64-6.18/general-driver-tm1628-auxdisplay-add-support-for-Titanmec-TM16.patch diff --git a/patch/kernel/archive/meson64-6.17/general-drm-dw-hdmi-call-hdmi_set_cts_n-after-clock.patch b/patch/kernel/archive/meson64-6.18/general-drm-dw-hdmi-call-hdmi_set_cts_n-after-clock.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-drm-dw-hdmi-call-hdmi_set_cts_n-after-clock.patch rename to patch/kernel/archive/meson64-6.18/general-drm-dw-hdmi-call-hdmi_set_cts_n-after-clock.patch diff --git a/patch/kernel/archive/meson64-6.17/general-drm-panfrost-fix-reference-leak.patch b/patch/kernel/archive/meson64-6.18/general-drm-panfrost-fix-reference-leak.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-drm-panfrost-fix-reference-leak.patch rename to patch/kernel/archive/meson64-6.18/general-drm-panfrost-fix-reference-leak.patch diff --git a/patch/kernel/archive/meson64-6.17/general-fix-Kodi-sysinfo-CPU-information.patch b/patch/kernel/archive/meson64-6.18/general-fix-Kodi-sysinfo-CPU-information.patch similarity index 94% rename from patch/kernel/archive/meson64-6.17/general-fix-Kodi-sysinfo-CPU-information.patch rename to patch/kernel/archive/meson64-6.18/general-fix-Kodi-sysinfo-CPU-information.patch index e5c39348b..63608bed3 100644 --- a/patch/kernel/archive/meson64-6.17/general-fix-Kodi-sysinfo-CPU-information.patch +++ b/patch/kernel/archive/meson64-6.18/general-fix-Kodi-sysinfo-CPU-information.patch @@ -16,7 +16,7 @@ diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 111111111111..222222222222 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c -@@ -223,9 +223,8 @@ static int c_show(struct seq_file *m, void *v) +@@ -224,9 +224,8 @@ static int c_show(struct seq_file *m, void *v) * "processor". Give glibc what it expects. */ seq_printf(m, "processor\t: %d\n", cpu); diff --git a/patch/kernel/archive/meson64-6.17/general-gpu-drm-add-new-display-resolution-2560x1440.patch b/patch/kernel/archive/meson64-6.18/general-gpu-drm-add-new-display-resolution-2560x1440.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-gpu-drm-add-new-display-resolution-2560x1440.patch rename to patch/kernel/archive/meson64-6.18/general-gpu-drm-add-new-display-resolution-2560x1440.patch diff --git a/patch/kernel/archive/meson64-6.17/general-input-touchscreen-Add-D-WAV-Multitouch.patch b/patch/kernel/archive/meson64-6.18/general-input-touchscreen-Add-D-WAV-Multitouch.patch similarity index 98% rename from patch/kernel/archive/meson64-6.17/general-input-touchscreen-Add-D-WAV-Multitouch.patch rename to patch/kernel/archive/meson64-6.18/general-input-touchscreen-Add-D-WAV-Multitouch.patch index e8c47d8e1..1aae2a031 100644 --- a/patch/kernel/archive/meson64-6.17/general-input-touchscreen-Add-D-WAV-Multitouch.patch +++ b/patch/kernel/archive/meson64-6.18/general-input-touchscreen-Add-D-WAV-Multitouch.patch @@ -16,7 +16,7 @@ diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 111111111111..222222222222 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h -@@ -1540,4 +1540,10 @@ +@@ -1546,4 +1546,10 @@ #define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a #define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155 @@ -31,7 +31,7 @@ diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 111111111111..222222222222 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c -@@ -912,6 +912,8 @@ static const struct hid_device_id hid_ignore_list[] = { +@@ -916,6 +916,8 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) }, { HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) }, @@ -44,7 +44,7 @@ diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconf index 111111111111..222222222222 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -1402,4 +1402,14 @@ config TOUCHSCREEN_HIMAX_HX83112B +@@ -1424,4 +1424,14 @@ config TOUCHSCREEN_HIMAX_HX83112B To compile this driver as a module, choose M here: the module will be called himax_hx83112b. @@ -63,7 +63,7 @@ diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Make index 111111111111..222222222222 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile -@@ -117,4 +117,5 @@ obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o +@@ -119,4 +119,5 @@ obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o diff --git a/patch/kernel/archive/meson64-6.17/general-media-cec-silence-CEC-timeout-message-HACK.patch b/patch/kernel/archive/meson64-6.18/general-media-cec-silence-CEC-timeout-message-HACK.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-media-cec-silence-CEC-timeout-message-HACK.patch rename to patch/kernel/archive/meson64-6.18/general-media-cec-silence-CEC-timeout-message-HACK.patch diff --git a/patch/kernel/archive/meson64-6.17/general-memory-marked-nomap.patch b/patch/kernel/archive/meson64-6.18/general-memory-marked-nomap.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-memory-marked-nomap.patch rename to patch/kernel/archive/meson64-6.18/general-memory-marked-nomap.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-aiu-Fix-HDMI-codec-control-selection.patch b/patch/kernel/archive/meson64-6.18/general-meson-aiu-Fix-HDMI-codec-control-selection.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-aiu-Fix-HDMI-codec-control-selection.patch rename to patch/kernel/archive/meson64-6.18/general-meson-aiu-Fix-HDMI-codec-control-selection.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-mmc-1-arm64-amlogic-mmc-meson-gx-Add-core-tx-rx-eMMC-SD-SD.patch b/patch/kernel/archive/meson64-6.18/general-meson-mmc-1-arm64-amlogic-mmc-meson-gx-Add-core-tx-rx-eMMC-SD-SD.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-mmc-1-arm64-amlogic-mmc-meson-gx-Add-core-tx-rx-eMMC-SD-SD.patch rename to patch/kernel/archive/meson64-6.18/general-meson-mmc-1-arm64-amlogic-mmc-meson-gx-Add-core-tx-rx-eMMC-SD-SD.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch b/patch/kernel/archive/meson64-6.18/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch similarity index 94% rename from patch/kernel/archive/meson64-6.17/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch rename to patch/kernel/archive/meson64-6.18/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch index 80a613dbf..0ad3a778f 100644 --- a/patch/kernel/archive/meson64-6.17/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch +++ b/patch/kernel/archive/meson64-6.18/general-meson-mmc-2-arm64-amlogic-dts-meson-update-meson-axg-device-tree.patch @@ -23,7 +23,7 @@ index 111111111111..222222222222 100644 / { compatible = "amlogic,meson-axg"; -@@ -1938,6 +1939,7 @@ sd_emmc_b: mmc@5000 { +@@ -1959,6 +1960,7 @@ sd_emmc_b: mmc@5000 { <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; @@ -31,7 +31,7 @@ index 111111111111..222222222222 100644 resets = <&reset RESET_SD_EMMC_B>; }; -@@ -1951,6 +1953,7 @@ sd_emmc_c: mmc@7000 { +@@ -1972,6 +1974,7 @@ sd_emmc_c: mmc@7000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; diff --git a/patch/kernel/archive/meson64-6.17/general-meson-mmc-3-arm64-dts-docs-Update-mmc-meson-gx-documentation-for.patch b/patch/kernel/archive/meson64-6.18/general-meson-mmc-3-arm64-dts-docs-Update-mmc-meson-gx-documentation-for.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-mmc-3-arm64-dts-docs-Update-mmc-meson-gx-documentation-for.patch rename to patch/kernel/archive/meson64-6.18/general-meson-mmc-3-arm64-dts-docs-Update-mmc-meson-gx-documentation-for.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-vdec-add-HEVC-decode-codec.patch b/patch/kernel/archive/meson64-6.18/general-meson-vdec-add-HEVC-decode-codec.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-vdec-add-HEVC-decode-codec.patch rename to patch/kernel/archive/meson64-6.18/general-meson-vdec-add-HEVC-decode-codec.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-vdec-add-handling-to-HEVC-decoder-.patch b/patch/kernel/archive/meson64-6.18/general-meson-vdec-add-handling-to-HEVC-decoder-.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-vdec-add-handling-to-HEVC-decoder-.patch rename to patch/kernel/archive/meson64-6.18/general-meson-vdec-add-handling-to-HEVC-decoder-.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-vdec-check-if-parser-has-really-parser.patch b/patch/kernel/archive/meson64-6.18/general-meson-vdec-check-if-parser-has-really-parser.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-vdec-check-if-parser-has-really-parser.patch rename to patch/kernel/archive/meson64-6.18/general-meson-vdec-check-if-parser-has-really-parser.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson-vdec-improve-mmu-and-fbc-handling-.patch b/patch/kernel/archive/meson64-6.18/general-meson-vdec-improve-mmu-and-fbc-handling-.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson-vdec-improve-mmu-and-fbc-handling-.patch rename to patch/kernel/archive/meson64-6.18/general-meson-vdec-improve-mmu-and-fbc-handling-.patch diff --git a/patch/kernel/archive/meson64-6.17/general-meson64-overlays.patch b/patch/kernel/archive/meson64-6.18/general-meson64-overlays.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-meson64-overlays.patch rename to patch/kernel/archive/meson64-6.18/general-meson64-overlays.patch diff --git a/patch/kernel/archive/meson64-6.17/general-si2168-fix-cmd-timeout.patch b/patch/kernel/archive/meson64-6.18/general-si2168-fix-cmd-timeout.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-si2168-fix-cmd-timeout.patch rename to patch/kernel/archive/meson64-6.18/general-si2168-fix-cmd-timeout.patch diff --git a/patch/kernel/archive/meson64-6.17/general-soc-0001-soc-amlogic-meson-gx-socinfo-move-common-code-to-hea.patch b/patch/kernel/archive/meson64-6.18/general-soc-0001-soc-amlogic-meson-gx-socinfo-move-common-code-to-hea.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-soc-0001-soc-amlogic-meson-gx-socinfo-move-common-code-to-hea.patch rename to patch/kernel/archive/meson64-6.18/general-soc-0001-soc-amlogic-meson-gx-socinfo-move-common-code-to-hea.patch diff --git a/patch/kernel/archive/meson64-6.17/general-soc-0002-soc-amlogic-meson-gx-socinfo-sm-Add-Amlogic-secure-m.patch b/patch/kernel/archive/meson64-6.18/general-soc-0002-soc-amlogic-meson-gx-socinfo-sm-Add-Amlogic-secure-m.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-soc-0002-soc-amlogic-meson-gx-socinfo-sm-Add-Amlogic-secure-m.patch rename to patch/kernel/archive/meson64-6.18/general-soc-0002-soc-amlogic-meson-gx-socinfo-sm-Add-Amlogic-secure-m.patch diff --git a/patch/kernel/archive/meson64-6.17/general-soc-0003-dt-bindings-arm-amlogic-amlogic-meson-gx-ao-secure-a.patch b/patch/kernel/archive/meson64-6.18/general-soc-0003-dt-bindings-arm-amlogic-amlogic-meson-gx-ao-secure-a.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-soc-0003-dt-bindings-arm-amlogic-amlogic-meson-gx-ao-secure-a.patch rename to patch/kernel/archive/meson64-6.18/general-soc-0003-dt-bindings-arm-amlogic-amlogic-meson-gx-ao-secure-a.patch diff --git a/patch/kernel/archive/meson64-6.17/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch b/patch/kernel/archive/meson64-6.18/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch similarity index 95% rename from patch/kernel/archive/meson64-6.17/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch rename to patch/kernel/archive/meson64-6.18/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch index 23514cef2..572ca5e73 100644 --- a/patch/kernel/archive/meson64-6.17/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch +++ b/patch/kernel/archive/meson64-6.18/general-soc-0004-arm64-dts-meson-add-dts-links-to-secure-monitor-for-.patch @@ -19,7 +19,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/aml index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi -@@ -626,6 +626,7 @@ hwrng: rng@5118 { +@@ -641,6 +641,7 @@ hwrng: rng@5118 { sec_AO: ao-secure@5a20 { compatible = "amlogic,meson-gx-ao-secure", "syscon"; reg = <0x0 0x5a20 0x0 0x140>; @@ -31,7 +31,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/am index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi -@@ -1690,6 +1690,7 @@ mux { +@@ -1711,6 +1711,7 @@ mux { sec_AO: ao-secure@140 { compatible = "amlogic,meson-gx-ao-secure", "syscon"; reg = <0x0 0x140 0x0 0x140>; @@ -55,7 +55,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/aml index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -471,6 +471,7 @@ cec_AO: cec@100 { +@@ -498,6 +498,7 @@ cec_AO: cec@100 { sec_AO: ao-secure@140 { compatible = "amlogic,meson-gx-ao-secure", "syscon"; reg = <0x0 0x140 0x0 0x140>; diff --git a/patch/kernel/archive/meson64-6.17/general-sound-soc-remove-mono-channel-as-it-curren.patch b/patch/kernel/archive/meson64-6.18/general-sound-soc-remove-mono-channel-as-it-curren.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-sound-soc-remove-mono-channel-as-it-curren.patch rename to patch/kernel/archive/meson64-6.18/general-sound-soc-remove-mono-channel-as-it-curren.patch diff --git a/patch/kernel/archive/meson64-6.17/general-spi-nor-add-support-for-XT25F128B.patch b/patch/kernel/archive/meson64-6.18/general-spi-nor-add-support-for-XT25F128B.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-spi-nor-add-support-for-XT25F128B.patch rename to patch/kernel/archive/meson64-6.18/general-spi-nor-add-support-for-XT25F128B.patch diff --git a/patch/kernel/archive/meson64-6.17/general-usb-core-improve-handling-of-hubs-with-no-ports.patch b/patch/kernel/archive/meson64-6.18/general-usb-core-improve-handling-of-hubs-with-no-ports.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/general-usb-core-improve-handling-of-hubs-with-no-ports.patch rename to patch/kernel/archive/meson64-6.18/general-usb-core-improve-handling-of-hubs-with-no-ports.patch diff --git a/patch/kernel/archive/meson64-6.17/hwmon-emc2305-fixups-for-driver.patch b/patch/kernel/archive/meson64-6.18/hwmon-emc2305-fixups-for-driver.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/hwmon-emc2305-fixups-for-driver.patch rename to patch/kernel/archive/meson64-6.18/hwmon-emc2305-fixups-for-driver.patch diff --git a/patch/kernel/archive/meson64-6.17/jethome-0001-Fix-meson64-add-gpio-irq-patch-from-https-lkml.org-l.patch b/patch/kernel/archive/meson64-6.18/jethome-0001-Fix-meson64-add-gpio-irq-patch-from-https-lkml.org-l.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/jethome-0001-Fix-meson64-add-gpio-irq-patch-from-https-lkml.org-l.patch rename to patch/kernel/archive/meson64-6.18/jethome-0001-Fix-meson64-add-gpio-irq-patch-from-https-lkml.org-l.patch diff --git a/patch/kernel/archive/meson64-6.17/jethome-0002-arm64-dts-jethub-j1xx-add-eeprom-node.patch b/patch/kernel/archive/meson64-6.18/jethome-0002-arm64-dts-jethub-j1xx-add-eeprom-node.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/jethome-0002-arm64-dts-jethub-j1xx-add-eeprom-node.patch rename to patch/kernel/archive/meson64-6.18/jethome-0002-arm64-dts-jethub-j1xx-add-eeprom-node.patch diff --git a/patch/kernel/archive/meson64-6.17/jethome-0003-arm64-dts-meson-add-dts-links-to-secure-monitor-for-jethub.patch.disabled b/patch/kernel/archive/meson64-6.18/jethome-0003-arm64-dts-meson-add-dts-links-to-secure-monitor-for-jethub.patch.disabled similarity index 100% rename from patch/kernel/archive/meson64-6.17/jethome-0003-arm64-dts-meson-add-dts-links-to-secure-monitor-for-jethub.patch.disabled rename to patch/kernel/archive/meson64-6.18/jethome-0003-arm64-dts-meson-add-dts-links-to-secure-monitor-for-jethub.patch.disabled diff --git a/patch/kernel/archive/meson64-6.17/kernel-6.8-tools-cgroup-makefile.patch b/patch/kernel/archive/meson64-6.18/kernel-6.8-tools-cgroup-makefile.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/kernel-6.8-tools-cgroup-makefile.patch rename to patch/kernel/archive/meson64-6.18/kernel-6.8-tools-cgroup-makefile.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-g12a-pinctrl-add-missing-ir-options.patch b/patch/kernel/archive/meson64-6.18/meson-g12a-pinctrl-add-missing-ir-options.patch similarity index 92% rename from patch/kernel/archive/meson64-6.17/meson-g12a-pinctrl-add-missing-ir-options.patch rename to patch/kernel/archive/meson64-6.18/meson-g12a-pinctrl-add-missing-ir-options.patch index 9e10e08af..a8bf6a450 100644 --- a/patch/kernel/archive/meson64-6.17/meson-g12a-pinctrl-add-missing-ir-options.patch +++ b/patch/kernel/archive/meson64-6.18/meson-g12a-pinctrl-add-missing-ir-options.patch @@ -59,7 +59,7 @@ index 111111111111..222222222222 100644 /* uart_a */ static const unsigned int uart_a_tx_pins[] = { GPIOX_12 }; static const unsigned int uart_a_rx_pins[] = { GPIOX_13 }; -@@ -753,6 +756,7 @@ static const struct meson_pmx_group meson_g12a_periphs_groups[] = { +@@ -756,6 +759,7 @@ static const struct meson_pmx_group meson_g12a_periphs_groups[] = { /* bank GPIOA */ GROUP(i2c3_sda_a, 2), GROUP(i2c3_sck_a, 2), @@ -67,7 +67,7 @@ index 111111111111..222222222222 100644 GROUP(pdm_din0_a, 1), GROUP(pdm_din1_a, 1), GROUP(pdm_din2_a, 1), -@@ -1038,6 +1042,10 @@ static const char * const i2c3_groups[] = { +@@ -1041,6 +1045,10 @@ static const char * const i2c3_groups[] = { "i2c3_sda_a", "i2c3_sck_a", }; @@ -78,7 +78,7 @@ index 111111111111..222222222222 100644 static const char * const uart_a_groups[] = { "uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts", }; -@@ -1282,6 +1290,7 @@ static const struct meson_pmx_func meson_g12a_periphs_functions[] = { +@@ -1289,6 +1297,7 @@ static const struct meson_pmx_func meson_g12a_periphs_functions[] = { FUNCTION(i2c1), FUNCTION(i2c2), FUNCTION(i2c3), diff --git a/patch/kernel/archive/meson64-6.17/meson-g12a-radxa-zero-gpio-pin-names.patch b/patch/kernel/archive/meson64-6.18/meson-g12a-radxa-zero-gpio-pin-names.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/meson-g12a-radxa-zero-gpio-pin-names.patch rename to patch/kernel/archive/meson64-6.18/meson-g12a-radxa-zero-gpio-pin-names.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch b/patch/kernel/archive/meson64-6.18/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch similarity index 97% rename from patch/kernel/archive/meson64-6.17/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch rename to patch/kernel/archive/meson64-6.18/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch index 9cc60ef9c..aa3d41759 100644 --- a/patch/kernel/archive/meson64-6.17/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch +++ b/patch/kernel/archive/meson64-6.18/meson-g12b-dt-Add-missing-pinmux-node-for-pwm.patch @@ -13,7 +13,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/a index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi -@@ -149,3 +149,45 @@ &pmu { +@@ -197,3 +197,45 @@ &pmu { &npu { power-domains = <&pwrc PWRC_G12A_NNA_ID>; }; diff --git a/patch/kernel/archive/meson64-6.17/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch b/patch/kernel/archive/meson64-6.18/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch similarity index 91% rename from patch/kernel/archive/meson64-6.17/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch rename to patch/kernel/archive/meson64-6.18/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch index 21d766775..5b739238b 100644 --- a/patch/kernel/archive/meson64-6.17/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch +++ b/patch/kernel/archive/meson64-6.18/meson-gx-dts-add-support-for-GX-PM-and-VRTC.patch @@ -12,7 +12,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/aml index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -223,6 +223,10 @@ sm: secure-monitor { +@@ -250,6 +250,10 @@ sm: secure-monitor { }; }; @@ -23,7 +23,7 @@ index 111111111111..222222222222 100644 efuse: efuse { compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse"; #address-cells = <1>; -@@ -461,6 +465,11 @@ clkc_AO: clock-controller { +@@ -488,6 +492,11 @@ clkc_AO: clock-controller { }; }; diff --git a/patch/kernel/archive/meson64-6.17/meson-gxbb-dts-i2cX-missing-pins.patch b/patch/kernel/archive/meson64-6.18/meson-gxbb-dts-i2cX-missing-pins.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/meson-gxbb-dts-i2cX-missing-pins.patch rename to patch/kernel/archive/meson64-6.18/meson-gxbb-dts-i2cX-missing-pins.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-gxbb-vdec-add-HEVC-support-to-GXBB.patch b/patch/kernel/archive/meson64-6.18/meson-gxbb-vdec-add-HEVC-support-to-GXBB.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/meson-gxbb-vdec-add-HEVC-support-to-GXBB.patch rename to patch/kernel/archive/meson64-6.18/meson-gxbb-vdec-add-HEVC-support-to-GXBB.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-gxl-gxm-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch b/patch/kernel/archive/meson64-6.18/meson-gxl-gxm-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/meson-gxl-gxm-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch rename to patch/kernel/archive/meson64-6.18/meson-gxl-gxm-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-gxm-vdec-add-VP9-support-to-GXM.patch b/patch/kernel/archive/meson64-6.18/meson-gxm-vdec-add-VP9-support-to-GXM.patch similarity index 100% rename from patch/kernel/archive/meson64-6.17/meson-gxm-vdec-add-VP9-support-to-GXM.patch rename to patch/kernel/archive/meson64-6.18/meson-gxm-vdec-add-VP9-support-to-GXM.patch diff --git a/patch/kernel/archive/meson64-6.17/meson-sm1-dts-add-higher-clocks.patch b/patch/kernel/archive/meson64-6.18/meson-sm1-dts-add-higher-clocks.patch similarity index 95% rename from patch/kernel/archive/meson64-6.17/meson-sm1-dts-add-higher-clocks.patch rename to patch/kernel/archive/meson64-6.18/meson-sm1-dts-add-higher-clocks.patch index 0e3393e5a..9d8aacfc3 100644 --- a/patch/kernel/archive/meson64-6.17/meson-sm1-dts-add-higher-clocks.patch +++ b/patch/kernel/archive/meson64-6.18/meson-sm1-dts-add-higher-clocks.patch @@ -12,7 +12,7 @@ diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/am index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi -@@ -137,6 +137,16 @@ opp-1908000000 { +@@ -164,6 +164,16 @@ opp-1908000000 { opp-hz = /bits/ 64 <1908000000>; opp-microvolt = <950000>; }; diff --git a/patch/kernel/archive/meson64-6.17/overlay/Makefile b/patch/kernel/archive/meson64-6.18/overlay/Makefile similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/Makefile rename to patch/kernel/archive/meson64-6.18/overlay/Makefile diff --git a/patch/kernel/archive/meson64-6.17/overlay/README.meson-overlays b/patch/kernel/archive/meson64-6.18/overlay/README.meson-overlays similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/README.meson-overlays rename to patch/kernel/archive/meson64-6.18/overlay/README.meson-overlays diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-fixup.scr-cmd b/patch/kernel/archive/meson64-6.18/overlay/meson-fixup.scr-cmd similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-fixup.scr-cmd rename to patch/kernel/archive/meson64-6.18/overlay/meson-fixup.scr-cmd diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12-gxl-cma-pool-896MB.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12-gxl-cma-pool-896MB.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12-gxl-cma-pool-896MB.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12-gxl-cma-pool-896MB.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12-pwm-gpiox-5-fan.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12-pwm-gpiox-5-fan.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12-pwm-gpiox-5-fan.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12-pwm-gpiox-5-fan.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-gpio-10-led.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-gpio-10-led.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-gpio-10-led.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-gpio-10-led.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-gpio-8-led.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-gpio-8-led.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-gpio-8-led.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-gpio-8-led.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ao-m0-gpioao-2-gpioao-3.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ao-m0-gpioao-2-gpioao-3.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ao-m0-gpioao-2-gpioao-3.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ao-m0-gpioao-2-gpioao-3.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpioh-6-gpioh-7.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpioh-6-gpioh-7.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpioh-6-gpioh-7.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpioh-6-gpioh-7.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpiox-10-gpiox-11.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpiox-10-gpiox-11.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpiox-10-gpiox-11.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m1-gpiox-10-gpiox-11.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m3-gpioa-14-gpioa-15.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m3-gpioa-14-gpioa-15.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-i2c-ee-m3-gpioa-14-gpioa-15.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-i2c-ee-m3-gpioa-14-gpioa-15.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-pwm-c-on-gpiox-8.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-pwm-c-on-gpiox-8.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-pwm-c-on-gpiox-8.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-pwm-c-on-gpiox-8.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-pwmao-a-on-gpioao-11.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-pwmao-a-on-gpioao-11.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-pwmao-a-on-gpioao-11.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-pwmao-a-on-gpioao-11.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-spi-spidev.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-spi-spidev.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-spi-spidev.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-spi-spidev.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-a-on-gpioao-0-gpioao-1.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-a-on-gpioao-0-gpioao-1.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-a-on-gpioao-0-gpioao-1.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-a-on-gpioao-0-gpioao-1.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-2-gpioao-3.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-2-gpioao-3.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-2-gpioao-3.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-2-gpioao-3.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-8-gpioao-9.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-8-gpioao-9.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-8-gpioao-9.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ao-b-on-gpioao-8-gpioao-9.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ee-c.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ee-c.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12a-radxa-zero-uart-ee-c.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12a-radxa-zero-uart-ee-c.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-cm4-i2c2.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-cm4-i2c2.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-cm4-i2c2.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-cm4-i2c2.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-cm4-pwm-gpioh-5-fan.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-cm4-pwm-gpioh-5-fan.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-cm4-pwm-gpioh-5-fan.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-cm4-pwm-gpioh-5-fan.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-m2s-rtl8822cs.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-m2s-rtl8822cs.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12b-bananapi-m2s-rtl8822cs.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12b-bananapi-m2s-rtl8822cs.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12b-odroid-n2-spi.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12b-odroid-n2-spi.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12b-odroid-n2-spi.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12b-odroid-n2-spi.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-g12b-waveshare-cm4-io-base-usb.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-g12b-waveshare-cm4-io-base-usb.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-g12b-waveshare-cm4-io-base-usb.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-g12b-waveshare-cm4-io-base-usb.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-i2cA.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-i2cA.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-i2cA.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-i2cA.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-i2cB.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-i2cB.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-i2cB.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-i2cB.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-m5-rtl8822cs.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-m5-rtl8822cs.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-m5-rtl8822cs.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-m5-rtl8822cs.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartA.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartA.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartA.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartA.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartAO_B.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartAO_B.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartAO_B.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartAO_B.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartA_cts_rts.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartA_cts_rts.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-bananapi-uartA_cts_rts.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-bananapi-uartA_cts_rts.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-jethome-jethub-j200-spi.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-jethome-jethub-j200-spi.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-jethome-jethub-j200-spi.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-jethome-jethub-j200-spi.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-odroid-c4-i2c0.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-odroid-c4-i2c0.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-odroid-c4-i2c0.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-odroid-c4-i2c0.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-sm1-odroid-c4-i2c1.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-sm1-odroid-c4-i2c1.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-sm1-odroid-c4-i2c1.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-sm1-odroid-c4-i2c1.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-uartA.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-uartA.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-uartA.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-uartA.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-uartC.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-uartC.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-uartC.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-uartC.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-w1-gpio.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-w1-gpio.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-w1-gpio.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-w1-gpio.dtso diff --git a/patch/kernel/archive/meson64-6.17/overlay/meson-w1AB-gpio.dtso b/patch/kernel/archive/meson64-6.18/overlay/meson-w1AB-gpio.dtso similarity index 100% rename from patch/kernel/archive/meson64-6.17/overlay/meson-w1AB-gpio.dtso rename to patch/kernel/archive/meson64-6.18/overlay/meson-w1AB-gpio.dtso diff --git a/patch/kernel/archive/meson64-6.18/temporary-6.18-rc4-temporary-fix-for-pcie-probe-failure-due-to.patch b/patch/kernel/archive/meson64-6.18/temporary-6.18-rc4-temporary-fix-for-pcie-probe-failure-due-to.patch new file mode 100644 index 000000000..fa7709a4c --- /dev/null +++ b/patch/kernel/archive/meson64-6.18/temporary-6.18-rc4-temporary-fix-for-pcie-probe-failure-due-to.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Mon, 3 Nov 2025 21:02:03 +0100 +Subject: 6.18-rc4: temporary fixes for pcie probe failure due to ASPM stuff + +- https://lore.kernel.org/linux-amlogic/20251031161323.GA1688975@bhelgaas/ +- https://lists.infradead.org/pipermail/linux-amlogic/2025-November/025692.html +--- + arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 +- + drivers/pci/controller/dwc/pci-meson.c | 42 +--------- + 2 files changed, 5 insertions(+), 39 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +@@ -138,7 +138,7 @@ pcie: pcie@fc000000 { + reg = <0x0 0xfc000000 0x0 0x400000>, + <0x0 0xff648000 0x0 0x2000>, + <0x0 0xfc400000 0x0 0x200000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; +diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c +index 111111111111..222222222222 100644 +--- a/drivers/pci/controller/dwc/pci-meson.c ++++ b/drivers/pci/controller/dwc/pci-meson.c +@@ -109,10 +109,6 @@ static int meson_pcie_get_mems(struct platform_device *pdev, + { + struct dw_pcie *pci = &mp->pci; + +- pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi"); +- if (IS_ERR(pci->dbi_base)) +- return PTR_ERR(pci->dbi_base); +- + mp->cfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg"); + if (IS_ERR(mp->cfg_base)) + return PTR_ERR(mp->cfg_base); +@@ -338,40 +334,10 @@ static struct pci_ops meson_pci_ops = { + static bool meson_pcie_link_up(struct dw_pcie *pci) + { + struct meson_pcie *mp = to_meson_pcie(pci); +- struct device *dev = pci->dev; +- u32 speed_okay = 0; +- u32 cnt = 0; +- u32 state12, state17, smlh_up, ltssm_up, rdlh_up; +- +- do { +- state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12); +- state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17); +- smlh_up = IS_SMLH_LINK_UP(state12); +- rdlh_up = IS_RDLH_LINK_UP(state12); +- ltssm_up = IS_LTSSM_UP(state12); +- +- if (PM_CURRENT_STATE(state17) < PCIE_GEN3) +- speed_okay = 1; +- +- if (smlh_up) +- dev_dbg(dev, "smlh_link_up is on\n"); +- if (rdlh_up) +- dev_dbg(dev, "rdlh_link_up is on\n"); +- if (ltssm_up) +- dev_dbg(dev, "ltssm_up is on\n"); +- if (speed_okay) +- dev_dbg(dev, "speed_okay\n"); +- +- if (smlh_up && rdlh_up && ltssm_up && speed_okay) +- return true; +- +- cnt++; +- +- udelay(10); +- } while (cnt < WAIT_LINKUP_TIMEOUT); +- +- dev_err(dev, "error: wait linkup timeout\n"); +- return false; ++ u32 state12; ++ ++ state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12); ++ return IS_SMLH_LINK_UP(state12) && IS_RDLH_LINK_UP(state12); + } + + static int meson_pcie_host_init(struct dw_pcie_rp *pp) +-- +Armbian + diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.108-109.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.108-109.patch new file mode 100644 index 000000000..a0a74cbd8 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.108-109.patch @@ -0,0 +1,3085 @@ +diff --git a/Makefile b/Makefile +index 1e3fb36bb71d78..afeacf5efc9553 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 108 ++SUBLEVEL = 109 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_sodia.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_sodia.dts +index 2564671fc1c67f..59745ba9c8dabd 100644 +--- a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_sodia.dts ++++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_sodia.dts +@@ -66,8 +66,10 @@ &gmac1 { + mdio0 { + #address-cells = <1>; + #size-cells = <0>; +- phy0: ethernet-phy@0 { +- reg = <0>; ++ compatible = "snps,dwmac-mdio"; ++ ++ phy0: ethernet-phy@4 { ++ reg = <4>; + rxd0-skew-ps = <0>; + rxd1-skew-ps = <0>; + rxd2-skew-ps = <0>; +diff --git a/arch/arm/boot/dts/marvell/kirkwood-openrd-client.dts b/arch/arm/boot/dts/marvell/kirkwood-openrd-client.dts +index d4e0b8150a84ce..cf26e2ceaaa074 100644 +--- a/arch/arm/boot/dts/marvell/kirkwood-openrd-client.dts ++++ b/arch/arm/boot/dts/marvell/kirkwood-openrd-client.dts +@@ -38,7 +38,7 @@ sound { + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { +- sound-dai = <&audio0 0>; ++ sound-dai = <&audio0>; + }; + + simple-audio-card,codec { +diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig +index 8789d93a7c04b3..c705bec1410c57 100644 +--- a/arch/arm/mach-bcm/Kconfig ++++ b/arch/arm/mach-bcm/Kconfig +@@ -186,6 +186,7 @@ config ARCH_BRCMSTB + select ARCH_HAS_RESET_CONTROLLER + select ARM_AMBA + select ARM_GIC ++ select ARM_GIC_V3 + select ARM_ERRATA_798181 if SMP + select HAVE_ARM_ARCH_TIMER + select ZONE_DMA if ARM_LPAE +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 69b213ed7a5943..7f7bd8477efde3 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -228,7 +228,7 @@ thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; +- thermal-sensors = <&tmu 0>; ++ thermal-sensors = <&tmu 1>; + trips { + cpu_alert0: trip0 { + temperature = <85000>; +@@ -258,7 +258,7 @@ map0 { + soc-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; +- thermal-sensors = <&tmu 1>; ++ thermal-sensors = <&tmu 0>; + trips { + soc_alert0: trip0 { + temperature = <85000>; +diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c +index 771e1cb17540db..e590b4c096253e 100644 +--- a/arch/s390/kernel/perf_cpum_cf.c ++++ b/arch/s390/kernel/perf_cpum_cf.c +@@ -852,7 +852,7 @@ static int cpumf_pmu_event_type(struct perf_event *event) + static int cpumf_pmu_event_init(struct perf_event *event) + { + unsigned int type = event->attr.type; +- int err; ++ int err = -ENOENT; + + if (is_sampling_event(event)) /* No sampling support */ + return err; +@@ -861,8 +861,6 @@ static int cpumf_pmu_event_init(struct perf_event *event) + else if (event->pmu->type == type) + /* Registered as unknown PMU */ + err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); +- else +- return -ENOENT; + + if (unlikely(err) && event->destroy) + event->destroy(event); +diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c +index e24298a734befd..a04cd13c6315a2 100644 +--- a/arch/um/drivers/mconsole_user.c ++++ b/arch/um/drivers/mconsole_user.c +@@ -71,7 +71,9 @@ static struct mconsole_command *mconsole_parse(struct mc_request *req) + return NULL; + } + ++#ifndef MIN + #define MIN(a,b) ((a)<(b) ? (a):(b)) ++#endif + + #define STRINGX(x) #x + #define STRING(x) STRINGX(x) +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 455e2a2b149f4b..6fe9180aafb36b 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1472,19 +1472,36 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg) + return error; + } + +-static int loop_set_block_size(struct loop_device *lo, unsigned long arg) ++static int loop_set_block_size(struct loop_device *lo, blk_mode_t mode, ++ struct block_device *bdev, unsigned long arg) + { + int err = 0; + +- if (lo->lo_state != Lo_bound) +- return -ENXIO; ++ /* ++ * If we don't hold exclusive handle for the device, upgrade to it ++ * here to avoid changing device under exclusive owner. ++ */ ++ if (!(mode & BLK_OPEN_EXCL)) { ++ err = bd_prepare_to_claim(bdev, loop_set_block_size, NULL); ++ if (err) ++ return err; ++ } ++ ++ err = mutex_lock_killable(&lo->lo_mutex); ++ if (err) ++ goto abort_claim; ++ ++ if (lo->lo_state != Lo_bound) { ++ err = -ENXIO; ++ goto unlock; ++ } + + err = blk_validate_block_size(arg); + if (err) +- return err; ++ goto unlock; + + if (lo->lo_queue->limits.logical_block_size == arg) +- return 0; ++ goto unlock; + + sync_blockdev(lo->lo_device); + invalidate_bdev(lo->lo_device); +@@ -1496,6 +1513,11 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) + loop_update_dio(lo); + blk_mq_unfreeze_queue(lo->lo_queue); + ++unlock: ++ mutex_unlock(&lo->lo_mutex); ++abort_claim: ++ if (!(mode & BLK_OPEN_EXCL)) ++ bd_abort_claiming(bdev, loop_set_block_size); + return err; + } + +@@ -1514,9 +1536,6 @@ static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd, + case LOOP_SET_DIRECT_IO: + err = loop_set_dio(lo, arg); + break; +- case LOOP_SET_BLOCK_SIZE: +- err = loop_set_block_size(lo, arg); +- break; + default: + err = -EINVAL; + } +@@ -1571,9 +1590,12 @@ static int lo_ioctl(struct block_device *bdev, blk_mode_t mode, + break; + case LOOP_GET_STATUS64: + return loop_get_status64(lo, argp); ++ case LOOP_SET_BLOCK_SIZE: ++ if (!(mode & BLK_OPEN_WRITE) && !capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++ return loop_set_block_size(lo, mode, bdev, arg); + case LOOP_SET_CAPACITY: + case LOOP_SET_DIRECT_IO: +- case LOOP_SET_BLOCK_SIZE: + if (!(mode & BLK_OPEN_WRITE) && !capable(CAP_SYS_ADMIN)) + return -EPERM; + fallthrough; +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 30d8f2ada0f176..76b0b9e6309b91 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -2950,6 +2950,15 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) + goto err_null_driver; + } + ++ /* ++ * Mark support for the scheduler's frequency invariance engine for ++ * drivers that implement target(), target_index() or fast_switch(). ++ */ ++ if (!cpufreq_driver->setpolicy) { ++ static_branch_enable_cpuslocked(&cpufreq_freq_invariance); ++ pr_debug("cpufreq: supports frequency invariance\n"); ++ } ++ + ret = subsys_interface_register(&cpufreq_interface); + if (ret) + goto err_boost_unreg; +@@ -2971,21 +2980,14 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) + hp_online = ret; + ret = 0; + +- /* +- * Mark support for the scheduler's frequency invariance engine for +- * drivers that implement target(), target_index() or fast_switch(). +- */ +- if (!cpufreq_driver->setpolicy) { +- static_branch_enable_cpuslocked(&cpufreq_freq_invariance); +- pr_debug("supports frequency invariance"); +- } +- + pr_debug("driver %s up and running\n", driver_data->name); + goto out; + + err_if_unreg: + subsys_interface_unregister(&cpufreq_interface); + err_boost_unreg: ++ if (!cpufreq_driver->setpolicy) ++ static_branch_disable_cpuslocked(&cpufreq_freq_invariance); + remove_boost_sysfs_file(); + err_null_driver: + write_lock_irqsave(&cpufreq_driver_lock, flags); +diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h +index 2ea4d1d1fbef26..1fa31a6fdfcd5d 100644 +--- a/drivers/edac/skx_common.h ++++ b/drivers/edac/skx_common.h +@@ -45,7 +45,6 @@ + #define I10NM_NUM_CHANNELS MAX(I10NM_NUM_DDR_CHANNELS, I10NM_NUM_HBM_CHANNELS) + #define I10NM_NUM_DIMMS MAX(I10NM_NUM_DDR_DIMMS, I10NM_NUM_HBM_DIMMS) + +-#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define NUM_IMC MAX(SKX_NUM_IMC, I10NM_NUM_IMC) + #define NUM_CHANNELS MAX(SKX_NUM_CHANNELS, I10NM_NUM_CHANNELS) + #define NUM_DIMMS MAX(SKX_NUM_DIMMS, I10NM_NUM_DIMMS) +diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c +index 73cc2f2dcbf923..bdf4b035325e95 100644 +--- a/drivers/firewire/core-cdev.c ++++ b/drivers/firewire/core-cdev.c +@@ -39,7 +39,7 @@ + /* + * ABI version history is documented in linux/firewire-cdev.h. + */ +-#define FW_CDEV_KERNEL_VERSION 5 ++#define FW_CDEV_KERNEL_VERSION 6 + #define FW_CDEV_VERSION_EVENT_REQUEST2 4 + #define FW_CDEV_VERSION_ALLOCATE_REGION_END 4 + #define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5 +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index efb592b6f6aa7a..9b8a200423858e 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -4022,6 +4022,23 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, + return desc; + } + ++static struct gpio_desc *gpiod_fwnode_lookup(struct fwnode_handle *fwnode, ++ struct device *consumer, ++ const char *con_id, ++ unsigned int idx, ++ enum gpiod_flags *flags, ++ unsigned long *lookupflags) ++{ ++ struct gpio_desc *desc; ++ ++ desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx, flags, lookupflags); ++ if (gpiod_not_found(desc) && !IS_ERR_OR_NULL(fwnode)) ++ desc = gpiod_find_by_fwnode(fwnode->secondary, consumer, con_id, ++ idx, flags, lookupflags); ++ ++ return desc; ++} ++ + struct gpio_desc *gpiod_find_and_request(struct device *consumer, + struct fwnode_handle *fwnode, + const char *con_id, +@@ -4034,7 +4051,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, + struct gpio_desc *desc; + int ret; + +- desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx, &flags, &lookupflags); ++ desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx, &flags, &lookupflags); + if (gpiod_not_found(desc) && platform_lookup_allowed) { + /* + * Either we are not using DT or ACPI, or their lookup did not +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index c5d706a4c7b4a7..78426f8c5420db 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1285,7 +1285,9 @@ int emu_soc_asic_init(struct amdgpu_device *adev); + for (i = ffs(inst_mask); i-- != 0; \ + i = ffs(inst_mask & BIT_MASK_UPPER(i + 1))) + ++#ifndef MIN + #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) ++#endif + + /* Common functions */ + bool amdgpu_device_has_job_running(struct amdgpu_device *adev); +diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +index 1b2df97226a3f2..40286e8dd4e1ab 100644 +--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c ++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +@@ -25,7 +25,9 @@ + + #include "hdcp.h" + ++#ifndef MIN + #define MIN(a, b) ((a) < (b) ? (a) : (b)) ++#endif + #define HDCP_I2C_ADDR 0x3a /* 0x74 >> 1*/ + #define KSV_READ_SIZE 0xf /* 0x6803b - 0x6802c */ + #define HDCP_MAX_AUX_TRANSACTION_SIZE 16 +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h +index 6f54c410c2f985..409aeec6baa921 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h +@@ -22,12 +22,18 @@ + */ + #include + +-#define SHIFT_AMOUNT 16 /* We multiply all original integers with 2^SHIFT_AMOUNT to get the fInt representation */ ++enum ppevvmath_constants { ++ /* We multiply all original integers with 2^SHIFT_AMOUNT to get the fInt representation */ ++ SHIFT_AMOUNT = 16, + +-#define PRECISION 5 /* Change this value to change the number of decimal places in the final output - 5 is a good default */ ++ /* Change this value to change the number of decimal places in the final output - 5 is a good default */ ++ PRECISION = 5, + +-#define SHIFTED_2 (2 << SHIFT_AMOUNT) +-#define MAX (1 << (SHIFT_AMOUNT - 1)) - 1 /* 32767 - Might change in the future */ ++ SHIFTED_2 = (2 << SHIFT_AMOUNT), ++ ++ /* 32767 - Might change in the future */ ++ MAX = (1 << (SHIFT_AMOUNT - 1)) - 1, ++}; + + /* ------------------------------------------------------------------------------- + * NEW TYPE - fINT +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +index a7f4f82d23b4b9..2fdb982e70ef7d 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -2082,7 +2082,9 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context + return ret; + } + ++#ifndef MAX + #define MAX(a, b) ((a) > (b) ? (a) : (b)) ++#endif + + static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, + uint8_t pcie_gen_cap, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +index 4022dd44ebb2b3..fe6c42a736d08b 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +@@ -1696,7 +1696,10 @@ static int smu_v13_0_0_get_thermal_temperature_range(struct smu_context *smu, + return 0; + } + ++#ifndef MAX + #define MAX(a, b) ((a) > (b) ? (a) : (b)) ++#endif ++ + static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, + void **table) + { +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +index e1521d3a5e0ca1..df99d185cf8e03 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +@@ -1674,7 +1674,10 @@ static int smu_v13_0_7_get_thermal_temperature_range(struct smu_context *smu, + return 0; + } + ++#ifndef MAX + #define MAX(a, b) ((a) > (b) ? (a) : (b)) ++#endif ++ + static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, + void **table) + { +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +index 12618a583e97cd..c1962f1974c6fe 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +@@ -708,7 +708,7 @@ static const char *smu_get_feature_name(struct smu_context *smu, + size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu, + char *buf) + { +- int8_t sort_feature[max(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)]; ++ int8_t sort_feature[MAX(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)]; + uint64_t feature_mask; + int i, feature_index; + uint32_t count = 0; +diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c +index c6f226b6f08136..fc9c36c8b81b99 100644 +--- a/drivers/gpu/drm/ast/ast_dp.c ++++ b/drivers/gpu/drm/ast/ast_dp.c +@@ -62,7 +62,7 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) + * of right-click of mouse. + * 2. The Delays are often longer a lot when system resume from S3/S4. + */ +- mdelay(j+1); ++ msleep(j + 1); + + if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, + ASTDP_MCU_FW_EXECUTING) && +diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c +index ed8626c73541c1..f0ae675581d9a5 100644 +--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c ++++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c +@@ -726,8 +726,8 @@ void oaktrail_hdmi_teardown(struct drm_device *dev) + + if (hdmi_dev) { + pdev = hdmi_dev->dev; +- pci_set_drvdata(pdev, NULL); + oaktrail_hdmi_i2c_exit(pdev); ++ pci_set_drvdata(pdev, NULL); + iounmap(hdmi_dev->regs); + kfree(hdmi_dev); + pci_dev_put(pdev); +diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c +index ff9b9918b0a134..d414627813aab7 100644 +--- a/drivers/gpu/drm/i915/display/intel_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_backlight.c +@@ -40,8 +40,9 @@ static u32 scale(u32 source_val, + { + u64 target_val; + +- WARN_ON(source_min > source_max); +- WARN_ON(target_min > target_max); ++ if (WARN_ON(source_min >= source_max) || ++ WARN_ON(target_min > target_max)) ++ return target_min; + + /* defensive */ + source_val = clamp(source_val, source_min, source_max); +diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c +index 820c2c3641d388..1311f10fad660c 100644 +--- a/drivers/gpu/drm/radeon/evergreen_cs.c ++++ b/drivers/gpu/drm/radeon/evergreen_cs.c +@@ -33,8 +33,10 @@ + #include "evergreen_reg_safe.h" + #include "cayman_reg_safe.h" + ++#ifndef MIN + #define MAX(a,b) (((a)>(b))?(a):(b)) + #define MIN(a,b) (((a)<(b))?(a):(b)) ++#endif + + #define REG_SAFE_BM_SIZE ARRAY_SIZE(evergreen_reg_safe_bm) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 896f73aa4d2c82..a8d440f6e804fb 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -869,7 +869,10 @@ static int asus_input_mapping(struct hid_device *hdev, + case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break; + case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break; + case 0xc7: asus_map_key_clear(KEY_KBDILLUMTOGGLE); break; ++ case 0x4e: asus_map_key_clear(KEY_FN_ESC); break; ++ case 0x7e: asus_map_key_clear(KEY_EMOJI_PICKER); break; + ++ case 0x8b: asus_map_key_clear(KEY_PROG1); break; /* ProArt Creator Hub key */ + case 0x6b: asus_map_key_clear(KEY_F21); break; /* ASUS touchpad toggle */ + case 0x38: asus_map_key_clear(KEY_PROG1); break; /* ROG key */ + case 0xba: asus_map_key_clear(KEY_PROG2); break; /* Fn+C ASUS Splendid */ +diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c +index 14b2547adae8d3..ce0ab4e4e41a73 100644 +--- a/drivers/hwmon/adt7475.c ++++ b/drivers/hwmon/adt7475.c +@@ -22,23 +22,23 @@ + #include + + /* Indexes for the sysfs hooks */ +- +-#define INPUT 0 +-#define MIN 1 +-#define MAX 2 +-#define CONTROL 3 +-#define OFFSET 3 +-#define AUTOMIN 4 +-#define THERM 5 +-#define HYSTERSIS 6 +- ++enum adt_sysfs_id { ++ INPUT = 0, ++ MIN = 1, ++ MAX = 2, ++ CONTROL = 3, ++ OFFSET = 3, // Dup ++ AUTOMIN = 4, ++ THERM = 5, ++ HYSTERSIS = 6, + /* + * These are unique identifiers for the sysfs functions - unlike the + * numbers above, these are not also indexes into an array + */ ++ ALARM = 9, ++ FAULT = 10, ++}; + +-#define ALARM 9 +-#define FAULT 10 + + /* 7475 Common Registers */ + +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index f3245a68563095..1ebcf5673a06b2 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -168,7 +168,7 @@ static inline int dw_i2c_of_configure(struct platform_device *pdev) + } + #endif + +-static int txgbe_i2c_request_regs(struct dw_i2c_dev *dev) ++static int dw_i2c_get_parent_regmap(struct dw_i2c_dev *dev) + { + dev->map = dev_get_regmap(dev->dev->parent, NULL); + if (!dev->map) +@@ -190,12 +190,15 @@ static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) + struct platform_device *pdev = to_platform_device(dev->dev); + int ret; + ++ if (device_is_compatible(dev->dev, "intel,xe-i2c")) ++ return dw_i2c_get_parent_regmap(dev); ++ + switch (dev->flags & MODEL_MASK) { + case MODEL_BAIKAL_BT1: + ret = bt1_i2c_request_regs(dev); + break; + case MODEL_WANGXUN_SP: +- ret = txgbe_i2c_request_regs(dev); ++ ret = dw_i2c_get_parent_regmap(dev); + break; + default: + dev->base = devm_platform_ioremap_resource(pdev, 0); +diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c +index 3f1fa45d936821..388c95562a927a 100644 +--- a/drivers/infiniband/hw/mlx5/devx.c ++++ b/drivers/infiniband/hw/mlx5/devx.c +@@ -191,6 +191,7 @@ static u16 get_legacy_obj_type(u16 opcode) + { + switch (opcode) { + case MLX5_CMD_OP_CREATE_RQ: ++ case MLX5_CMD_OP_CREATE_RMP: + return MLX5_EVENT_QUEUE_TYPE_RQ; + case MLX5_CMD_OP_CREATE_QP: + return MLX5_EVENT_QUEUE_TYPE_QP; +diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c +index 7cb26929dc7328..9dc25eb2be445f 100644 +--- a/drivers/input/touchscreen/cyttsp4_core.c ++++ b/drivers/input/touchscreen/cyttsp4_core.c +@@ -871,7 +871,7 @@ static void cyttsp4_get_mt_touches(struct cyttsp4_mt_data *md, int num_cur_tch) + struct cyttsp4_touch tch; + int sig; + int i, j, t = 0; +- int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)]; ++ int ids[MAX(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)]; + + memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int)); + for (i = 0; i < num_cur_tch; i++) { +diff --git a/drivers/irqchip/irq-sun6i-r.c b/drivers/irqchip/irq-sun6i-r.c +index a01e440494154e..99958d470d6268 100644 +--- a/drivers/irqchip/irq-sun6i-r.c ++++ b/drivers/irqchip/irq-sun6i-r.c +@@ -270,7 +270,7 @@ static const struct irq_domain_ops sun6i_r_intc_domain_ops = { + + static int sun6i_r_intc_suspend(void) + { +- u32 buf[BITS_TO_U32(max(SUN6I_NR_TOP_LEVEL_IRQS, SUN6I_NR_MUX_BITS))]; ++ u32 buf[BITS_TO_U32(MAX(SUN6I_NR_TOP_LEVEL_IRQS, SUN6I_NR_MUX_BITS))]; + int i; + + /* Wake IRQs are enabled during system sleep and shutdown. */ +diff --git a/drivers/media/dvb-frontends/stv0367_priv.h b/drivers/media/dvb-frontends/stv0367_priv.h +index 617f605947b2c4..7f056d1cce8228 100644 +--- a/drivers/media/dvb-frontends/stv0367_priv.h ++++ b/drivers/media/dvb-frontends/stv0367_priv.h +@@ -25,8 +25,11 @@ + #endif + + /* MACRO definitions */ ++#ifndef MIN + #define MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) + #define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) ++#endif ++ + #define INRANGE(X, Y, Z) \ + ((((X) <= (Y)) && ((Y) <= (Z))) || \ + (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) +diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c +index be1505e8c536e8..7759531ccca70f 100644 +--- a/drivers/mmc/host/sdhci-cadence.c ++++ b/drivers/mmc/host/sdhci-cadence.c +@@ -433,6 +433,13 @@ static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = { + }, + }; + ++static const struct sdhci_cdns_drv_data sdhci_eyeq_drv_data = { ++ .pltfm_data = { ++ .ops = &sdhci_cdns_ops, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, ++ }, ++}; ++ + static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data = { + .pltfm_data = { + .ops = &sdhci_cdns_ops, +@@ -595,6 +602,10 @@ static const struct of_device_id sdhci_cdns_match[] = { + .compatible = "amd,pensando-elba-sd4hc", + .data = &sdhci_elba_drv_data, + }, ++ { ++ .compatible = "mobileye,eyeq-sd4hc", ++ .data = &sdhci_eyeq_drv_data, ++ }, + { .compatible = "cdns,sd4hc" }, + { /* sentinel */ } + }; +diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c +index f5aa5dbacaf21f..1f26aba620b988 100644 +--- a/drivers/net/can/rcar/rcar_can.c ++++ b/drivers/net/can/rcar/rcar_can.c +@@ -861,7 +861,6 @@ static int __maybe_unused rcar_can_resume(struct device *dev) + { + struct net_device *ndev = dev_get_drvdata(dev); + struct rcar_can_priv *priv = netdev_priv(ndev); +- u16 ctlr; + int err; + + if (!netif_running(ndev)) +@@ -873,12 +872,7 @@ static int __maybe_unused rcar_can_resume(struct device *dev) + return err; + } + +- ctlr = readw(&priv->regs->ctlr); +- ctlr &= ~RCAR_CAN_CTLR_SLPM; +- writew(ctlr, &priv->regs->ctlr); +- ctlr &= ~RCAR_CAN_CTLR_CANM; +- writew(ctlr, &priv->regs->ctlr); +- priv->can.state = CAN_STATE_ERROR_ACTIVE; ++ rcar_can_start(ndev); + + netif_device_attach(ndev); + netif_start_queue(ndev); +diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c +index b757555ed4c4f6..57ea7dfe8a596f 100644 +--- a/drivers/net/can/spi/hi311x.c ++++ b/drivers/net/can/spi/hi311x.c +@@ -813,6 +813,7 @@ static const struct net_device_ops hi3110_netdev_ops = { + .ndo_open = hi3110_open, + .ndo_stop = hi3110_stop, + .ndo_start_xmit = hi3110_hard_start_xmit, ++ .ndo_change_mtu = can_change_mtu, + }; + + static const struct ethtool_ops hi3110_ethtool_ops = { +diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c +index 283fbf59e66d5e..5ab1f9c7288e59 100644 +--- a/drivers/net/can/sun4i_can.c ++++ b/drivers/net/can/sun4i_can.c +@@ -768,6 +768,7 @@ static const struct net_device_ops sun4ican_netdev_ops = { + .ndo_open = sun4ican_open, + .ndo_stop = sun4ican_close, + .ndo_start_xmit = sun4ican_start_xmit, ++ .ndo_change_mtu = can_change_mtu, + }; + + static const struct ethtool_ops sun4ican_ethtool_ops = { +diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c +index 5e3a72b7c46919..bb49a2c0a9a5c1 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_core.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c +@@ -7,7 +7,7 @@ + * + * Copyright (c) 2019 Robert Bosch Engineering and Business Solutions. All rights reserved. + * Copyright (c) 2020 ETAS K.K.. All rights reserved. +- * Copyright (c) 2020-2022 Vincent Mailhol ++ * Copyright (c) 2020-2025 Vincent Mailhol + */ + + #include +@@ -1977,6 +1977,7 @@ static const struct net_device_ops es58x_netdev_ops = { + .ndo_stop = es58x_stop, + .ndo_start_xmit = es58x_start_xmit, + .ndo_eth_ioctl = can_eth_ioctl_hwts, ++ .ndo_change_mtu = can_change_mtu, + }; + + static const struct ethtool_ops es58x_ethtool_ops = { +diff --git a/drivers/net/can/usb/etas_es58x/es58x_devlink.c b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +index e763a9904bedd0..0d155eb1b9e999 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +@@ -215,7 +215,7 @@ static int es58x_devlink_info_get(struct devlink *devlink, + struct es58x_sw_version *fw_ver = &es58x_dev->firmware_version; + struct es58x_sw_version *bl_ver = &es58x_dev->bootloader_version; + struct es58x_hw_revision *hw_rev = &es58x_dev->hardware_revision; +- char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))]; ++ char buf[MAX(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))]; + int ret = 0; + + if (es58x_sw_version_is_valid(fw_ver)) { +diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c +index 47619e9cb0055b..ecc489afb84163 100644 +--- a/drivers/net/can/usb/mcba_usb.c ++++ b/drivers/net/can/usb/mcba_usb.c +@@ -761,6 +761,7 @@ static const struct net_device_ops mcba_netdev_ops = { + .ndo_open = mcba_usb_open, + .ndo_stop = mcba_usb_close, + .ndo_start_xmit = mcba_usb_start_xmit, ++ .ndo_change_mtu = can_change_mtu, + }; + + static const struct ethtool_ops mcba_ethtool_ops = { +diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c +index 24ad9f593a7736..9d162d1004c267 100644 +--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c +@@ -111,7 +111,7 @@ void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now) + u32 delta_ts = time_ref->ts_dev_2 - time_ref->ts_dev_1; + + if (time_ref->ts_dev_2 < time_ref->ts_dev_1) +- delta_ts &= (1 << time_ref->adapter->ts_used_bits) - 1; ++ delta_ts &= (1ULL << time_ref->adapter->ts_used_bits) - 1; + + time_ref->ts_total += delta_ts; + } +diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c +index 3c76a1a14aee3c..c1a9ab92597685 100644 +--- a/drivers/net/dsa/lantiq_gswip.c ++++ b/drivers/net/dsa/lantiq_gswip.c +@@ -682,30 +682,24 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add) + return 0; + } + +-static int gswip_port_enable(struct dsa_switch *ds, int port, +- struct phy_device *phydev) ++static int gswip_port_setup(struct dsa_switch *ds, int port) + { + struct gswip_priv *priv = ds->priv; + int err; + +- if (!dsa_is_user_port(ds, port)) +- return 0; +- + if (!dsa_is_cpu_port(ds, port)) { + err = gswip_add_single_port_br(priv, port, true); + if (err) + return err; + } + +- /* RMON Counter Enable for port */ +- gswip_switch_w(priv, GSWIP_BM_PCFG_CNTEN, GSWIP_BM_PCFGp(port)); ++ return 0; ++} + +- /* enable port fetch/store dma & VLAN Modification */ +- gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_EN | +- GSWIP_FDMA_PCTRL_VLANMOD_BOTH, +- GSWIP_FDMA_PCTRLp(port)); +- gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN, +- GSWIP_SDMA_PCTRLp(port)); ++static int gswip_port_enable(struct dsa_switch *ds, int port, ++ struct phy_device *phydev) ++{ ++ struct gswip_priv *priv = ds->priv; + + if (!dsa_is_cpu_port(ds, port)) { + u32 mdio_phy = 0; +@@ -717,6 +711,16 @@ static int gswip_port_enable(struct dsa_switch *ds, int port, + GSWIP_MDIO_PHYp(port)); + } + ++ /* RMON Counter Enable for port */ ++ gswip_switch_w(priv, GSWIP_BM_PCFG_CNTEN, GSWIP_BM_PCFGp(port)); ++ ++ /* enable port fetch/store dma & VLAN Modification */ ++ gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_EN | ++ GSWIP_FDMA_PCTRL_VLANMOD_BOTH, ++ GSWIP_FDMA_PCTRLp(port)); ++ gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN, ++ GSWIP_SDMA_PCTRLp(port)); ++ + return 0; + } + +@@ -724,9 +728,6 @@ static void gswip_port_disable(struct dsa_switch *ds, int port) + { + struct gswip_priv *priv = ds->priv; + +- if (!dsa_is_user_port(ds, port)) +- return; +- + gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0, + GSWIP_FDMA_PCTRLp(port)); + gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0, +@@ -1365,8 +1366,9 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port, + int i; + int err; + ++ /* Operation not supported on the CPU port, don't throw errors */ + if (!bridge) +- return -EINVAL; ++ return 0; + + for (i = max_ports; i < ARRAY_SIZE(priv->vlans); i++) { + if (priv->vlans[i].bridge == bridge) { +@@ -1821,6 +1823,7 @@ static int gswip_get_sset_count(struct dsa_switch *ds, int port, int sset) + static const struct dsa_switch_ops gswip_xrx200_switch_ops = { + .get_tag_protocol = gswip_get_tag_protocol, + .setup = gswip_setup, ++ .port_setup = gswip_port_setup, + .port_enable = gswip_port_enable, + .port_disable = gswip_port_disable, + .port_bridge_join = gswip_port_bridge_join, +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +index 273c9ba48f09a1..b896f8d20ff336 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +@@ -244,7 +244,7 @@ bnxt_tc_parse_pedit(struct bnxt *bp, struct bnxt_tc_actions *actions, + offset < offset_of_ip6_daddr + 16) { + actions->nat.src_xlate = false; + idx = (offset - offset_of_ip6_daddr) / 4; +- actions->nat.l3.ipv6.saddr.s6_addr32[idx] = htonl(val); ++ actions->nat.l3.ipv6.daddr.s6_addr32[idx] = htonl(val); + } else { + netdev_err(bp->dev, + "%s: IPv6_hdr: Invalid pedit field\n", +diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h +index 9fb7c5fe05d15f..f095069dc32a9e 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e.h ++++ b/drivers/net/ethernet/intel/i40e/i40e.h +@@ -23,6 +23,7 @@ + #define I40E_MAX_VEB 16 + + #define I40E_MAX_NUM_DESCRIPTORS 4096 ++#define I40E_MAX_NUM_DESCRIPTORS_XL710 8160 + #define I40E_MAX_CSR_SPACE (4 * 1024 * 1024 - 64 * 1024) + #define I40E_DEFAULT_NUM_DESCRIPTORS 512 + #define I40E_REQ_DESCRIPTOR_MULTIPLE 32 +@@ -1228,7 +1229,8 @@ struct i40e_mac_filter *i40e_add_mac_filter(struct i40e_vsi *vsi, + const u8 *macaddr); + int i40e_del_mac_filter(struct i40e_vsi *vsi, const u8 *macaddr); + bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi); +-int i40e_count_filters(struct i40e_vsi *vsi); ++int i40e_count_all_filters(struct i40e_vsi *vsi); ++int i40e_count_active_filters(struct i40e_vsi *vsi); + struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, const u8 *macaddr); + void i40e_vlan_stripping_enable(struct i40e_vsi *vsi); + static inline bool i40e_is_sw_dcb(struct i40e_pf *pf) +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index a89f7ca510fdb8..077d5daaedccaa 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -2015,6 +2015,18 @@ static void i40e_get_drvinfo(struct net_device *netdev, + drvinfo->n_priv_flags += I40E_GL_PRIV_FLAGS_STR_LEN; + } + ++static u32 i40e_get_max_num_descriptors(struct i40e_pf *pf) ++{ ++ struct i40e_hw *hw = &pf->hw; ++ ++ switch (hw->mac.type) { ++ case I40E_MAC_XL710: ++ return I40E_MAX_NUM_DESCRIPTORS_XL710; ++ default: ++ return I40E_MAX_NUM_DESCRIPTORS; ++ } ++} ++ + static void i40e_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, +@@ -2024,8 +2036,8 @@ static void i40e_get_ringparam(struct net_device *netdev, + struct i40e_pf *pf = np->vsi->back; + struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; + +- ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS; +- ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS; ++ ring->rx_max_pending = i40e_get_max_num_descriptors(pf); ++ ring->tx_max_pending = i40e_get_max_num_descriptors(pf); + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = vsi->rx_rings[0]->count; +@@ -2050,12 +2062,12 @@ static int i40e_set_ringparam(struct net_device *netdev, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) + { ++ u32 new_rx_count, new_tx_count, max_num_descriptors; + struct i40e_ring *tx_rings = NULL, *rx_rings = NULL; + struct i40e_netdev_priv *np = netdev_priv(netdev); + struct i40e_hw *hw = &np->vsi->back->hw; + struct i40e_vsi *vsi = np->vsi; + struct i40e_pf *pf = vsi->back; +- u32 new_rx_count, new_tx_count; + u16 tx_alloc_queue_pairs; + int timeout = 50; + int i, err = 0; +@@ -2063,14 +2075,15 @@ static int i40e_set_ringparam(struct net_device *netdev, + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + +- if (ring->tx_pending > I40E_MAX_NUM_DESCRIPTORS || ++ max_num_descriptors = i40e_get_max_num_descriptors(pf); ++ if (ring->tx_pending > max_num_descriptors || + ring->tx_pending < I40E_MIN_NUM_DESCRIPTORS || +- ring->rx_pending > I40E_MAX_NUM_DESCRIPTORS || ++ ring->rx_pending > max_num_descriptors || + ring->rx_pending < I40E_MIN_NUM_DESCRIPTORS) { + netdev_info(netdev, + "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n", + ring->tx_pending, ring->rx_pending, +- I40E_MIN_NUM_DESCRIPTORS, I40E_MAX_NUM_DESCRIPTORS); ++ I40E_MIN_NUM_DESCRIPTORS, max_num_descriptors); + return -EINVAL; + } + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 72869336e3a9a9..affdbd3ee76c54 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -1247,12 +1247,30 @@ void i40e_update_stats(struct i40e_vsi *vsi) + } + + /** +- * i40e_count_filters - counts VSI mac filters ++ * i40e_count_all_filters - counts VSI MAC filters + * @vsi: the VSI to be searched + * +- * Returns count of mac filters +- **/ +-int i40e_count_filters(struct i40e_vsi *vsi) ++ * Return: count of MAC filters in any state. ++ */ ++int i40e_count_all_filters(struct i40e_vsi *vsi) ++{ ++ struct i40e_mac_filter *f; ++ struct hlist_node *h; ++ int bkt, cnt = 0; ++ ++ hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) ++ cnt++; ++ ++ return cnt; ++} ++ ++/** ++ * i40e_count_active_filters - counts VSI MAC filters ++ * @vsi: the VSI to be searched ++ * ++ * Return: count of active MAC filters. ++ */ ++int i40e_count_active_filters(struct i40e_vsi *vsi) + { + struct i40e_mac_filter *f; + struct hlist_node *h; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 6d7a4f2c3a49b7..7f5538e2c9de5c 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -448,7 +448,7 @@ static void i40e_config_irq_link_list(struct i40e_vf *vf, u16 vsi_id, + (qtype << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) | + (pf_queue_id << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) | + BIT(I40E_QINT_RQCTL_CAUSE_ENA_SHIFT) | +- (itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT); ++ FIELD_PREP(I40E_QINT_RQCTL_ITR_INDX_MASK, itr_idx); + wr32(hw, reg_idx, reg); + } + +@@ -657,6 +657,13 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id, + + /* only set the required fields */ + tx_ctx.base = info->dma_ring_addr / 128; ++ ++ /* ring_len has to be multiple of 8 */ ++ if (!IS_ALIGNED(info->ring_len, 8) || ++ info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) { ++ ret = -EINVAL; ++ goto error_context; ++ } + tx_ctx.qlen = info->ring_len; + tx_ctx.rdylist = le16_to_cpu(vsi->info.qs_handle[0]); + tx_ctx.rdylist_act = 0; +@@ -722,6 +729,13 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id, + + /* only set the required fields */ + rx_ctx.base = info->dma_ring_addr / 128; ++ ++ /* ring_len has to be multiple of 32 */ ++ if (!IS_ALIGNED(info->ring_len, 32) || ++ info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) { ++ ret = -EINVAL; ++ goto error_param; ++ } + rx_ctx.qlen = info->ring_len; + + if (info->splithdr_enabled) { +@@ -1459,6 +1473,7 @@ static void i40e_trigger_vf_reset(struct i40e_vf *vf, bool flr) + * functions that may still be running at this point. + */ + clear_bit(I40E_VF_STATE_INIT, &vf->vf_states); ++ clear_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states); + + /* In the case of a VFLR, the HW has already reset the VF and we + * just need to clean up, so don't hit the VFRTRIG register. +@@ -2125,7 +2140,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) + size_t len = 0; + int ret; + +- if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) { ++ i40e_sync_vf_state(vf, I40E_VF_STATE_INIT); ++ ++ if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states) || ++ test_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states)) { + aq_ret = -EINVAL; + goto err; + } +@@ -2228,6 +2246,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) + vf->default_lan_addr.addr); + } + set_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states); ++ set_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states); + + err: + /* send the response back to the VF */ +@@ -2390,7 +2409,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) + } + + if (vf->adq_enabled) { +- if (idx >= ARRAY_SIZE(vf->ch)) { ++ if (idx >= vf->num_tc) { + aq_ret = -ENODEV; + goto error_param; + } +@@ -2411,7 +2430,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) + * to its appropriate VSIs based on TC mapping + */ + if (vf->adq_enabled) { +- if (idx >= ARRAY_SIZE(vf->ch)) { ++ if (idx >= vf->num_tc) { + aq_ret = -ENODEV; + goto error_param; + } +@@ -2461,8 +2480,10 @@ static int i40e_validate_queue_map(struct i40e_vf *vf, u16 vsi_id, + u16 vsi_queue_id, queue_id; + + for_each_set_bit(vsi_queue_id, &queuemap, I40E_MAX_VSI_QP) { +- if (vf->adq_enabled) { +- vsi_id = vf->ch[vsi_queue_id / I40E_MAX_VF_VSI].vsi_id; ++ u16 idx = vsi_queue_id / I40E_MAX_VF_VSI; ++ ++ if (vf->adq_enabled && idx < vf->num_tc) { ++ vsi_id = vf->ch[idx].vsi_id; + queue_id = (vsi_queue_id % I40E_DEFAULT_QUEUES_PER_VF); + } else { + queue_id = vsi_queue_id; +@@ -2850,24 +2871,6 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg) + (u8 *)&stats, sizeof(stats)); + } + +-/** +- * i40e_can_vf_change_mac +- * @vf: pointer to the VF info +- * +- * Return true if the VF is allowed to change its MAC filters, false otherwise +- */ +-static bool i40e_can_vf_change_mac(struct i40e_vf *vf) +-{ +- /* If the VF MAC address has been set administratively (via the +- * ndo_set_vf_mac command), then deny permission to the VF to +- * add/delete unicast MAC addresses, unless the VF is trusted +- */ +- if (vf->pf_set_mac && !vf->trusted) +- return false; +- +- return true; +-} +- + #define I40E_MAX_MACVLAN_PER_HW 3072 + #define I40E_MAX_MACVLAN_PER_PF(num_ports) (I40E_MAX_MACVLAN_PER_HW / \ + (num_ports)) +@@ -2906,8 +2909,10 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, + struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx]; + struct i40e_hw *hw = &pf->hw; +- int mac2add_cnt = 0; +- int i; ++ int i, mac_add_max, mac_add_cnt = 0; ++ bool vf_trusted; ++ ++ vf_trusted = test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps); + + for (i = 0; i < al->num_elements; i++) { + struct i40e_mac_filter *f; +@@ -2927,9 +2932,8 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, + * The VF may request to set the MAC address filter already + * assigned to it so do not return an error in that case. + */ +- if (!i40e_can_vf_change_mac(vf) && +- !is_multicast_ether_addr(addr) && +- !ether_addr_equal(addr, vf->default_lan_addr.addr)) { ++ if (!vf_trusted && !is_multicast_ether_addr(addr) && ++ vf->pf_set_mac && !ether_addr_equal(addr, vf->default_lan_addr.addr)) { + dev_err(&pf->pdev->dev, + "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n"); + return -EPERM; +@@ -2938,29 +2942,33 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, + /*count filters that really will be added*/ + f = i40e_find_mac(vsi, addr); + if (!f) +- ++mac2add_cnt; ++ ++mac_add_cnt; + } + + /* If this VF is not privileged, then we can't add more than a limited +- * number of addresses. Check to make sure that the additions do not +- * push us over the limit. +- */ +- if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) { +- if ((i40e_count_filters(vsi) + mac2add_cnt) > +- I40E_VC_MAX_MAC_ADDR_PER_VF) { +- dev_err(&pf->pdev->dev, +- "Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n"); +- return -EPERM; +- } +- /* If this VF is trusted, it can use more resources than untrusted. ++ * number of addresses. ++ * ++ * If this VF is trusted, it can use more resources than untrusted. + * However to ensure that every trusted VF has appropriate number of + * resources, divide whole pool of resources per port and then across + * all VFs. + */ +- } else { +- if ((i40e_count_filters(vsi) + mac2add_cnt) > +- I40E_VC_MAX_MACVLAN_PER_TRUSTED_VF(pf->num_alloc_vfs, +- hw->num_ports)) { ++ if (!vf_trusted) ++ mac_add_max = I40E_VC_MAX_MAC_ADDR_PER_VF; ++ else ++ mac_add_max = I40E_VC_MAX_MACVLAN_PER_TRUSTED_VF(pf->num_alloc_vfs, hw->num_ports); ++ ++ /* VF can replace all its filters in one step, in this case mac_add_max ++ * will be added as active and another mac_add_max will be in ++ * a to-be-removed state. Account for that. ++ */ ++ if ((i40e_count_active_filters(vsi) + mac_add_cnt) > mac_add_max || ++ (i40e_count_all_filters(vsi) + mac_add_cnt) > 2 * mac_add_max) { ++ if (!vf_trusted) { ++ dev_err(&pf->pdev->dev, ++ "Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n"); ++ return -EPERM; ++ } else { + dev_err(&pf->pdev->dev, + "Cannot add more MAC addresses, trusted VF exhausted it's resources\n"); + return -EPERM; +@@ -3593,7 +3601,7 @@ static int i40e_validate_cloud_filter(struct i40e_vf *vf, + + /* action_meta is TC number here to which the filter is applied */ + if (!tc_filter->action_meta || +- tc_filter->action_meta > vf->num_tc) { ++ tc_filter->action_meta >= vf->num_tc) { + dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n", + vf->vf_id, tc_filter->action_meta); + goto err; +@@ -3891,6 +3899,8 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) + aq_ret); + } + ++#define I40E_MAX_VF_CLOUD_FILTER 0xFF00 ++ + /** + * i40e_vc_add_cloud_filter + * @vf: pointer to the VF info +@@ -3930,6 +3940,14 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) + goto err_out; + } + ++ if (vf->num_cloud_filters >= I40E_MAX_VF_CLOUD_FILTER) { ++ dev_warn(&pf->pdev->dev, ++ "VF %d: Max number of filters reached, can't apply cloud filter\n", ++ vf->vf_id); ++ aq_ret = -ENOSPC; ++ goto err_out; ++ } ++ + cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL); + if (!cfilter) { + aq_ret = -ENOMEM; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +index 66f95e2f3146a8..e0e797fea138ad 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +@@ -41,7 +41,8 @@ enum i40e_vf_states { + I40E_VF_STATE_MC_PROMISC, + I40E_VF_STATE_UC_PROMISC, + I40E_VF_STATE_PRE_ENABLE, +- I40E_VF_STATE_RESETTING ++ I40E_VF_STATE_RESETTING, ++ I40E_VF_STATE_RESOURCES_LOADED, + }; + + /* VF capabilities */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 6302990e9a5ff8..729d1833a829a5 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -21,8 +21,7 @@ + #include "rvu.h" + #include "lmac_common.h" + +-#define DRV_NAME "Marvell-CGX/RPM" +-#define DRV_STRING "Marvell CGX/RPM Driver" ++#define DRV_NAME "Marvell-CGX-RPM" + + #define CGX_RX_STAT_GLOBAL_INDEX 9 + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +index 46bdbee9d38adf..635cfb9a3e2c5f 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +@@ -1116,7 +1116,6 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, + + free_leaf: + otx2_tc_del_from_flow_list(flow_cfg, new_node); +- kfree_rcu(new_node, rcu); + if (new_node->is_act_police) { + mutex_lock(&nic->mbox.lock); + +@@ -1136,6 +1135,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, + + mutex_unlock(&nic->mbox.lock); + } ++ kfree_rcu(new_node, rcu); + + return rc; + } +diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c +index 2513be6d4e11d1..cfcf0f7d9d903e 100644 +--- a/drivers/net/fjes/fjes_main.c ++++ b/drivers/net/fjes/fjes_main.c +@@ -14,9 +14,7 @@ + #include "fjes.h" + #include "fjes_trace.h" + +-#define MAJ 1 +-#define MIN 2 +-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) ++#define DRV_VERSION "1.2" + #define DRV_NAME "fjes" + char fjes_driver_name[] = DRV_NAME; + char fjes_driver_version[] = DRV_VERSION; +diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c +index fb4d95a027fefa..2977b30c6d593c 100644 +--- a/drivers/net/wireless/virtual/virt_wifi.c ++++ b/drivers/net/wireless/virtual/virt_wifi.c +@@ -277,7 +277,9 @@ static void virt_wifi_connect_complete(struct work_struct *work) + priv->is_connected = true; + + /* Schedules an event that acquires the rtnl lock. */ +- cfg80211_connect_result(priv->upperdev, requested_bss, NULL, 0, NULL, 0, ++ cfg80211_connect_result(priv->upperdev, ++ priv->is_connected ? fake_router_bssid : NULL, ++ NULL, 0, NULL, 0, + status, GFP_KERNEL); + netif_carrier_on(priv->upperdev); + } +diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c +index 3f6d74832bac3b..be566ca7bae947 100644 +--- a/drivers/nfc/pn544/i2c.c ++++ b/drivers/nfc/pn544/i2c.c +@@ -126,8 +126,6 @@ struct pn544_i2c_fw_secure_blob { + #define PN544_FW_CMD_RESULT_COMMAND_REJECTED 0xE0 + #define PN544_FW_CMD_RESULT_CHUNK_ERROR 0xE6 + +-#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +- + #define PN544_FW_WRITE_BUFFER_MAX_LEN 0x9f7 + #define PN544_FW_I2C_MAX_PAYLOAD PN544_HCI_I2C_LLC_MAX_SIZE + #define PN544_FW_I2C_WRITE_FRAME_HEADER_LEN 8 +diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c +index 9569f11dec8c56..bd7323cf9a97f8 100644 +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -757,7 +757,6 @@ static union acpi_object *__call_snc_method(acpi_handle handle, char *method, + return result; + } + +-#define MIN(a, b) (a > b ? b : a) + static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, + void *buffer, size_t buflen) + { +diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c +index 6277162a028bb9..6eefa7e5f4cf6a 100644 +--- a/drivers/scsi/isci/init.c ++++ b/drivers/scsi/isci/init.c +@@ -65,11 +65,7 @@ + #include "task.h" + #include "probe_roms.h" + +-#define MAJ 1 +-#define MIN 2 +-#define BUILD 0 +-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ +- __stringify(BUILD) ++#define DRV_VERSION "1.2.0" + + MODULE_VERSION(DRV_VERSION); + +diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h +index a444ec14ff9d5b..1c17a87a85720c 100644 +--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h ++++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h +@@ -31,11 +31,6 @@ + /* A => B */ + #define IMPLIES(a, b) (!(a) || (b)) + +-/* for preprocessor and array sizing use MIN and MAX +- otherwise use min and max */ +-#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +-#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +- + #define ROUND_DIV(a, b) (((b) != 0) ? ((a) + ((b) >> 1)) / (b) : 0) + #define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0) + #define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c +index 14864cfc242238..cb8f0652a4beec 100644 +--- a/drivers/ufs/core/ufs-mcq.c ++++ b/drivers/ufs/core/ufs-mcq.c +@@ -209,7 +209,7 @@ int ufshcd_mcq_memory_alloc(struct ufs_hba *hba) + hwq->sqe_base_addr = dmam_alloc_coherent(hba->dev, utrdl_size, + &hwq->sqe_dma_addr, + GFP_KERNEL); +- if (!hwq->sqe_dma_addr) { ++ if (!hwq->sqe_base_addr) { + dev_err(hba->dev, "SQE allocation failed\n"); + return -ENOMEM; + } +@@ -218,7 +218,7 @@ int ufshcd_mcq_memory_alloc(struct ufs_hba *hba) + hwq->cqe_base_addr = dmam_alloc_coherent(hba->dev, cqe_size, + &hwq->cqe_dma_addr, + GFP_KERNEL); +- if (!hwq->cqe_dma_addr) { ++ if (!hwq->cqe_base_addr) { + dev_err(hba->dev, "CQE allocation failed\n"); + return -ENOMEM; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index bfd97cad8aa4d7..c0fd8ab3fe8fc2 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -734,7 +734,7 @@ void usb_detect_quirks(struct usb_device *udev) + udev->quirks ^= usb_detect_dynamic_quirks(udev); + + if (udev->quirks) +- dev_dbg(&udev->dev, "USB quirks for this device: %x\n", ++ dev_dbg(&udev->dev, "USB quirks for this device: 0x%x\n", + udev->quirks); + + #ifdef CONFIG_USB_DEFAULT_PERSIST +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 58eee27aa6cca9..b49f15a3442eab 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -2483,7 +2483,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, + unsigned charcount = font->charcount; + int w = font->width; + int h = font->height; +- int size; ++ int size, alloc_size; + int i, csum; + u8 *new_data, *data = font->data; + int pitch = PITCH(font->width); +@@ -2510,9 +2510,16 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, + if (fbcon_invalid_charcount(info, charcount)) + return -EINVAL; + +- size = CALC_FONTSZ(h, pitch, charcount); ++ /* Check for integer overflow in font size calculation */ ++ if (check_mul_overflow(h, pitch, &size) || ++ check_mul_overflow(size, charcount, &size)) ++ return -EINVAL; ++ ++ /* Check for overflow in allocation size calculation */ ++ if (check_add_overflow(FONT_EXTRA_WORDS * sizeof(int), size, &alloc_size)) ++ return -EINVAL; + +- new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER); ++ new_data = kmalloc(alloc_size, GFP_USER); + + if (!new_data) + return -ENOMEM; +diff --git a/fs/afs/server.c b/fs/afs/server.c +index 87381c2ffe374c..f92ce4b7d73a19 100644 +--- a/fs/afs/server.c ++++ b/fs/afs/server.c +@@ -401,13 +401,14 @@ struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_tra + void afs_put_server(struct afs_net *net, struct afs_server *server, + enum afs_server_trace reason) + { +- unsigned int a, debug_id = server->debug_id; ++ unsigned int a, debug_id; + bool zero; + int r; + + if (!server) + return; + ++ debug_id = server->debug_id; + a = atomic_read(&server->active); + zero = __refcount_dec_and_test(&server->ref, &r); + trace_afs_server(debug_id, r - 1, a, reason); +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index d49ce7768f7f5b..0d93368c1691ae 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -614,7 +614,7 @@ static int check_dir_item(struct extent_buffer *leaf, + */ + if (key->type == BTRFS_DIR_ITEM_KEY || + key->type == BTRFS_XATTR_ITEM_KEY) { +- char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; ++ char namebuf[MAX(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; + + read_extent_buffer(leaf, namebuf, + (unsigned long)(di + 1), name_len); +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index ab951fd475317c..914e850b9cbb77 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -619,14 +619,16 @@ static bool remove_inode_single_folio(struct hstate *h, struct inode *inode, + + /* + * If folio is mapped, it was faulted in after being +- * unmapped in caller. Unmap (again) while holding +- * the fault mutex. The mutex will prevent faults +- * until we finish removing the folio. ++ * unmapped in caller or hugetlb_vmdelete_list() skips ++ * unmapping it due to fail to grab lock. Unmap (again) ++ * while holding the fault mutex. The mutex will prevent ++ * faults until we finish removing the folio. Hold folio ++ * lock to guarantee no concurrent migration. + */ ++ folio_lock(folio); + if (unlikely(folio_mapped(folio))) + hugetlb_unmap_file_folio(h, mapping, folio, index); + +- folio_lock(folio); + /* + * We must remove the folio from page cache before removing + * the region/ reserve map (hugetlb_unreserve_pages). In +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 0cc80f472432ad..79641d1ee86757 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -641,7 +641,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + + tmp_rc = rc; + for (i = 0; i < num_cmds; i++) { +- char *buf = rsp_iov[i + i].iov_base; ++ char *buf = rsp_iov[i + 1].iov_base; + + if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER) + rc = server->ops->map_error(buf, false); +diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c +index 3720304d679293..504e2a1cf33b84 100644 +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -147,7 +147,7 @@ struct smb_direct_transport { + wait_queue_head_t wait_send_pending; + atomic_t send_pending; + +- struct delayed_work post_recv_credits_work; ++ struct work_struct post_recv_credits_work; + struct work_struct send_immediate_work; + struct work_struct disconnect_work; + +@@ -366,8 +366,8 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) + + spin_lock_init(&t->lock_new_recv_credits); + +- INIT_DELAYED_WORK(&t->post_recv_credits_work, +- smb_direct_post_recv_credits); ++ INIT_WORK(&t->post_recv_credits_work, ++ smb_direct_post_recv_credits); + INIT_WORK(&t->send_immediate_work, smb_direct_send_immediate_work); + INIT_WORK(&t->disconnect_work, smb_direct_disconnect_rdma_work); + +@@ -399,7 +399,7 @@ static void free_transport(struct smb_direct_transport *t) + atomic_read(&t->send_pending) == 0); + + cancel_work_sync(&t->disconnect_work); +- cancel_delayed_work_sync(&t->post_recv_credits_work); ++ cancel_work_sync(&t->post_recv_credits_work); + cancel_work_sync(&t->send_immediate_work); + + if (t->qp) { +@@ -614,8 +614,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) + wake_up_interruptible(&t->wait_send_credits); + + if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count)) +- mod_delayed_work(smb_direct_wq, +- &t->post_recv_credits_work, 0); ++ queue_work(smb_direct_wq, &t->post_recv_credits_work); + + if (data_length) { + enqueue_reassembly(t, recvmsg, (int)data_length); +@@ -772,8 +771,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, + st->count_avail_recvmsg += queue_removed; + if (is_receive_credit_post_required(st->recv_credits, st->count_avail_recvmsg)) { + spin_unlock(&st->receive_credit_lock); +- mod_delayed_work(smb_direct_wq, +- &st->post_recv_credits_work, 0); ++ queue_work(smb_direct_wq, &st->post_recv_credits_work); + } else { + spin_unlock(&st->receive_credit_lock); + } +@@ -800,7 +798,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, + static void smb_direct_post_recv_credits(struct work_struct *work) + { + struct smb_direct_transport *t = container_of(work, +- struct smb_direct_transport, post_recv_credits_work.work); ++ struct smb_direct_transport, post_recv_credits_work); + struct smb_direct_recvmsg *recvmsg; + int receive_credits, credits = 0; + int ret; +@@ -1681,7 +1679,7 @@ static int smb_direct_prepare_negotiation(struct smb_direct_transport *t) + goto out_err; + } + +- smb_direct_post_recv_credits(&t->post_recv_credits_work.work); ++ smb_direct_post_recv_credits(&t->post_recv_credits_work); + return 0; + out_err: + put_recvmsg(t, recvmsg); +diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h +index 7402bf3e037ee7..2fe6abb2ca803d 100644 +--- a/include/crypto/if_alg.h ++++ b/include/crypto/if_alg.h +@@ -150,7 +150,7 @@ struct af_alg_ctx { + size_t used; + atomic_t rcvused; + +- u32 more:1, ++ bool more:1, + merge:1, + enc:1, + write:1, +diff --git a/include/linux/compiler.h b/include/linux/compiler.h +index e84ed3a43f1f80..1d4f23ea3105d0 100644 +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -244,6 +244,15 @@ static inline void *offset_to_ptr(const int *off) + #define is_signed_type(type) (((type)(-1)) < (__force type)1) + #define is_unsigned_type(type) (!is_signed_type(type)) + ++/* ++ * Useful shorthand for "is this condition known at compile-time?" ++ * ++ * Note that the condition may involve non-constant values, ++ * but the compiler may know enough about the details of the ++ * values to determine that the condition is statically true. ++ */ ++#define statically_true(x) (__builtin_constant_p(x) && (x)) ++ + /* + * This is needed in functions which generate the stack canary, see + * arch/x86/kernel/smpboot.c::start_secondary() for an example. +diff --git a/include/linux/minmax.h b/include/linux/minmax.h +index 9c2848abc80496..eaaf5c008e4d05 100644 +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -8,13 +8,10 @@ + #include + + /* +- * min()/max()/clamp() macros must accomplish three things: ++ * min()/max()/clamp() macros must accomplish several things: + * + * - Avoid multiple evaluations of the arguments (so side-effects like + * "x++" happen only once) when non-constant. +- * - Retain result as a constant expressions when called with only +- * constant expressions (to avoid tripping VLA warnings in stack +- * allocation usage). + * - Perform signed v unsigned type-checking (to generate compile + * errors instead of nasty runtime surprises). + * - Unsigned char/short are always promoted to signed int and can be +@@ -26,19 +23,59 @@ + #define __typecheck(x, y) \ + (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) + +-/* is_signed_type() isn't a constexpr for pointer types */ +-#define __is_signed(x) \ +- __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ +- is_signed_type(typeof(x)), 0) ++/* ++ * __sign_use for integer expressions: ++ * bit #0 set if ok for unsigned comparisons ++ * bit #1 set if ok for signed comparisons ++ * ++ * In particular, statically non-negative signed integer expressions ++ * are ok for both. ++ * ++ * NOTE! Unsigned types smaller than 'int' are implicitly converted to 'int' ++ * in expressions, and are accepted for signed conversions for now. ++ * This is debatable. ++ * ++ * Note that 'x' is the original expression, and 'ux' is the unique variable ++ * that contains the value. ++ * ++ * We use 'ux' for pure type checking, and 'x' for when we need to look at the ++ * value (but without evaluating it for side effects! ++ * Careful to only ever evaluate it with sizeof() or __builtin_constant_p() etc). ++ * ++ * Pointers end up being checked by the normal C type rules at the actual ++ * comparison, and these expressions only need to be careful to not cause ++ * warnings for pointer use. ++ */ ++#define __sign_use(ux) (is_signed_type(typeof(ux)) ? \ ++ (2 + __is_nonneg(ux)) : (1 + 2 * (sizeof(ux) < 4))) ++ ++/* ++ * Check whether a signed value is always non-negative. ++ * ++ * A cast is needed to avoid any warnings from values that aren't signed ++ * integer types (in which case the result doesn't matter). ++ * ++ * On 64-bit any integer or pointer type can safely be cast to 'long long'. ++ * But on 32-bit we need to avoid warnings about casting pointers to integers ++ * of different sizes without truncating 64-bit values so 'long' or 'long long' ++ * must be used depending on the size of the value. ++ * ++ * This does not work for 128-bit signed integers since the cast would truncate ++ * them, but we do not use s128 types in the kernel (we do use 'u128', ++ * but they are handled by the !is_signed_type() case). ++ */ ++#if __SIZEOF_POINTER__ == __SIZEOF_LONG_LONG__ ++#define __is_nonneg(ux) statically_true((long long)(ux) >= 0) ++#else ++#define __is_nonneg(ux) statically_true( \ ++ (typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)))(ux) >= 0) ++#endif + +-/* True for a non-negative signed int constant */ +-#define __is_noneg_int(x) \ +- (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) ++#define __types_ok(ux, uy) \ ++ (__sign_use(ux) & __sign_use(uy)) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y) || \ +- __is_signed((x) + 0) == __is_signed((y) + 0) || \ +- __is_noneg_int(x) || __is_noneg_int(y)) ++#define __types_ok3(ux, uy, uz) \ ++ (__sign_use(ux) & __sign_use(uy) & __sign_use(uz)) + + #define __cmp_op_min < + #define __cmp_op_max > +@@ -51,34 +88,14 @@ + #define __cmp_once(op, type, x, y) \ + __cmp_once_unique(op, type, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) + +-#define __careful_cmp_once(op, x, y) ({ \ +- static_assert(__types_ok(x, y), \ +- #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ +- __cmp_once(op, __auto_type, x, y); }) +- +-#define __careful_cmp(op, x, y) \ +- __builtin_choose_expr(__is_constexpr((x) - (y)), \ +- __cmp(op, x, y), __careful_cmp_once(op, x, y)) +- +-#define __clamp(val, lo, hi) \ +- ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) +- +-#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ +- typeof(val) unique_val = (val); \ +- typeof(lo) unique_lo = (lo); \ +- typeof(hi) unique_hi = (hi); \ +- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ +- (lo) <= (hi), true), \ +- "clamp() low limit " #lo " greater than high limit " #hi); \ +- static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ +- static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ +- __clamp(unique_val, unique_lo, unique_hi); }) ++#define __careful_cmp_once(op, x, y, ux, uy) ({ \ ++ __auto_type ux = (x); __auto_type uy = (y); \ ++ BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \ ++ #op"("#x", "#y") signedness error"); \ ++ __cmp(op, ux, uy); }) + +-#define __careful_clamp(val, lo, hi) ({ \ +- __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ +- __clamp(val, lo, hi), \ +- __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \ +- __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); }) ++#define __careful_cmp(op, x, y) \ ++ __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) + + /** + * min - return minimum of two values of the same or compatible types +@@ -111,13 +128,20 @@ + #define umax(x, y) \ + __careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) + ++#define __careful_op3(op, x, y, z, ux, uy, uz) ({ \ ++ __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ ++ BUILD_BUG_ON_MSG(!__types_ok3(ux, uy, uz), \ ++ #op"3("#x", "#y", "#z") signedness error"); \ ++ __cmp(op, ux, __cmp(op, uy, uz)); }) ++ + /** + * min3 - return minimum of three values + * @x: first value + * @y: second value + * @z: third value + */ +-#define min3(x, y, z) min((typeof(x))min(x, y), z) ++#define min3(x, y, z) \ ++ __careful_op3(min, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) + + /** + * max3 - return maximum of three values +@@ -125,7 +149,24 @@ + * @y: second value + * @z: third value + */ +-#define max3(x, y, z) max((typeof(x))max(x, y), z) ++#define max3(x, y, z) \ ++ __careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) ++ ++/** ++ * min_t - return minimum of two values, using the specified type ++ * @type: data type to use ++ * @x: first value ++ * @y: second value ++ */ ++#define min_t(type, x, y) __cmp_once(min, type, x, y) ++ ++/** ++ * max_t - return maximum of two values, using the specified type ++ * @type: data type to use ++ * @x: first value ++ * @y: second value ++ */ ++#define max_t(type, x, y) __cmp_once(max, type, x, y) + + /** + * min_not_zero - return the minimum that is _not_ zero, unless both are zero +@@ -137,39 +178,57 @@ + typeof(y) __y = (y); \ + __x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); }) + ++#define __clamp(val, lo, hi) \ ++ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) ++ ++#define __clamp_once(type, val, lo, hi, uval, ulo, uhi) ({ \ ++ type uval = (val); \ ++ type ulo = (lo); \ ++ type uhi = (hi); \ ++ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ ++ "clamp() low limit " #lo " greater than high limit " #hi); \ ++ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ ++ "clamp("#val", "#lo", "#hi") signedness error"); \ ++ __clamp(uval, ulo, uhi); }) ++ ++#define __careful_clamp(type, val, lo, hi) \ ++ __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) ++ + /** +- * clamp - return a value clamped to a given range with strict typechecking ++ * clamp - return a value clamped to a given range with typechecking + * @val: current value + * @lo: lowest allowable value + * @hi: highest allowable value + * +- * This macro does strict typechecking of @lo/@hi to make sure they are of the +- * same type as @val. See the unnecessary pointer comparisons. +- */ +-#define clamp(val, lo, hi) __careful_clamp(val, lo, hi) +- +-/* +- * ..and if you can't take the strict +- * types, you can specify one yourself. +- * +- * Or not use min/max/clamp at all, of course. ++ * This macro checks @val/@lo/@hi to make sure they have compatible ++ * signedness. + */ ++#define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi) + + /** +- * min_t - return minimum of two values, using the specified type +- * @type: data type to use +- * @x: first value +- * @y: second value ++ * clamp_t - return a value clamped to a given range using a given type ++ * @type: the type of variable to use ++ * @val: current value ++ * @lo: minimum allowable value ++ * @hi: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of type ++ * @type to make all the comparisons. + */ +-#define min_t(type, x, y) __cmp_once(min, type, x, y) ++#define clamp_t(type, val, lo, hi) __careful_clamp(type, val, lo, hi) + + /** +- * max_t - return maximum of two values, using the specified type +- * @type: data type to use +- * @x: first value +- * @y: second value ++ * clamp_val - return a value clamped to a given range using val's type ++ * @val: current value ++ * @lo: minimum allowable value ++ * @hi: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of whatever ++ * type the input argument @val is. This is useful when @val is an unsigned ++ * type and @lo and @hi are literals that will otherwise be assigned a signed ++ * integer type. + */ +-#define max_t(type, x, y) __cmp_once(max, type, x, y) ++#define clamp_val(val, lo, hi) __careful_clamp(typeof(val), val, lo, hi) + + /* + * Do not check the array parameter using __must_be_array(). +@@ -214,31 +273,6 @@ + */ + #define max_array(array, len) __minmax_array(max, array, len) + +-/** +- * clamp_t - return a value clamped to a given range using a given type +- * @type: the type of variable to use +- * @val: current value +- * @lo: minimum allowable value +- * @hi: maximum allowable value +- * +- * This macro does no typechecking and uses temporary variables of type +- * @type to make all the comparisons. +- */ +-#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi)) +- +-/** +- * clamp_val - return a value clamped to a given range using val's type +- * @val: current value +- * @lo: minimum allowable value +- * @hi: maximum allowable value +- * +- * This macro does no typechecking and uses temporary variables of whatever +- * type the input argument @val is. This is useful when @val is an unsigned +- * type and @lo and @hi are literals that will otherwise be assigned a signed +- * integer type. +- */ +-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi) +- + static inline bool in_range64(u64 val, u64 start, u64 len) + { + return (val - start) < len; +@@ -277,7 +311,9 @@ static inline bool in_range32(u32 val, u32 start, u32 len) + * Use these carefully: no type checking, and uses the arguments + * multiple times. Use for obvious constants only. + */ +-#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b)) +-#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b)) ++#define MIN(a, b) __cmp(min, a, b) ++#define MAX(a, b) __cmp(max, a, b) ++#define MIN_T(type, a, b) __cmp(min, (type)(a), (type)(b)) ++#define MAX_T(type, a, b) __cmp(max, (type)(a), (type)(b)) + + #endif /* _LINUX_MINMAX_H */ +diff --git a/include/linux/mm.h b/include/linux/mm.h +index b97d8a691b28bf..ba77f08900ca2e 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -2156,6 +2156,61 @@ static inline int folio_estimated_sharers(struct folio *folio) + return page_mapcount(folio_page(folio, 0)); + } + ++/** ++ * folio_expected_ref_count - calculate the expected folio refcount ++ * @folio: the folio ++ * ++ * Calculate the expected folio refcount, taking references from the pagecache, ++ * swapcache, PG_private and page table mappings into account. Useful in ++ * combination with folio_ref_count() to detect unexpected references (e.g., ++ * GUP or other temporary references). ++ * ++ * Does currently not consider references from the LRU cache. If the folio ++ * was isolated from the LRU (which is the case during migration or split), ++ * the LRU cache does not apply. ++ * ++ * Calling this function on an unmapped folio -- !folio_mapped() -- that is ++ * locked will return a stable result. ++ * ++ * Calling this function on a mapped folio will not result in a stable result, ++ * because nothing stops additional page table mappings from coming (e.g., ++ * fork()) or going (e.g., munmap()). ++ * ++ * Calling this function without the folio lock will also not result in a ++ * stable result: for example, the folio might get dropped from the swapcache ++ * concurrently. ++ * ++ * However, even when called without the folio lock or on a mapped folio, ++ * this function can be used to detect unexpected references early (for example, ++ * if it makes sense to even lock the folio and unmap it). ++ * ++ * The caller must add any reference (e.g., from folio_try_get()) it might be ++ * holding itself to the result. ++ * ++ * Returns the expected folio refcount. ++ */ ++static inline int folio_expected_ref_count(struct folio *folio) ++{ ++ const int order = folio_order(folio); ++ int ref_count = 0; ++ ++ if (WARN_ON_ONCE(folio_test_slab(folio))) ++ return 0; ++ ++ if (folio_test_anon(folio)) { ++ /* One reference per page from the swapcache. */ ++ ref_count += folio_test_swapcache(folio) << order; ++ } else if (!((unsigned long)folio->mapping & PAGE_MAPPING_FLAGS)) { ++ /* One reference per page from the pagecache. */ ++ ref_count += !!folio->mapping << order; ++ /* One reference from PG_private. */ ++ ref_count += folio_test_private(folio); ++ } ++ ++ /* One reference per page table mapping. */ ++ return ref_count + folio_mapcount(folio); ++} ++ + #ifndef HAVE_ARCH_MAKE_PAGE_ACCESSIBLE + static inline int arch_make_page_accessible(struct page *page) + { +diff --git a/include/linux/swap.h b/include/linux/swap.h +index cb25db2a93dd1b..d7a5b7817987d8 100644 +--- a/include/linux/swap.h ++++ b/include/linux/swap.h +@@ -375,6 +375,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *); + void mark_page_accessed(struct page *); + void folio_mark_accessed(struct folio *); + ++static inline bool folio_may_be_lru_cached(struct folio *folio) ++{ ++ /* ++ * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. ++ * Holding small numbers of low-order mTHP folios in per-CPU LRU cache ++ * will be sensible, but nobody has implemented and tested that yet. ++ */ ++ return !folio_test_large(folio); ++} ++ + extern atomic_t lru_disable_count; + + static inline bool lru_cache_disabled(void) +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 4f067599e6e9e0..62135b7782f5be 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1169,6 +1169,27 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, + return NULL; + } + ++static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev, ++ __u8 type, __u8 role, ++ bdaddr_t *ba) ++{ ++ struct hci_conn_hash *h = &hdev->conn_hash; ++ struct hci_conn *c; ++ ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(c, &h->list, list) { ++ if (c->type == type && c->role == role && !bacmp(&c->dst, ba)) { ++ rcu_read_unlock(); ++ return c; ++ } ++ } ++ ++ rcu_read_unlock(); ++ ++ return NULL; ++} ++ + static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev, + bdaddr_t *ba, + __u8 ba_type) +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 7d6ee41f4b4f4f..a6f825b7fbe6cd 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -7546,6 +7546,10 @@ static int process_timer_func(struct bpf_verifier_env *env, int regno, + verbose(env, "verifier bug. Two map pointers in a timer helper\n"); + return -EFAULT; + } ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ verbose(env, "bpf_timer cannot be used for PREEMPT_RT.\n"); ++ return -EOPNOTSUPP; ++ } + meta->map_uid = reg->map_uid; + meta->map_ptr = map; + return 0; +diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c +index cba8b1a6a4cc27..7e43839ca7b05c 100644 +--- a/kernel/futex/requeue.c ++++ b/kernel/futex/requeue.c +@@ -223,18 +223,20 @@ static inline + void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, + struct futex_hash_bucket *hb) + { +- q->key = *key; ++ struct task_struct *task; + ++ q->key = *key; + __futex_unqueue(q); + + WARN_ON(!q->rt_waiter); + q->rt_waiter = NULL; + + q->lock_ptr = &hb->lock; ++ task = READ_ONCE(q->task); + + /* Signal locked state to the waiter */ + futex_requeue_pi_complete(q, 1); +- wake_up_state(q->task, TASK_NORMAL); ++ wake_up_state(task, TASK_NORMAL); + } + + /** +diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c +index 8af92dbe98f07b..acb0c971a4082a 100644 +--- a/kernel/trace/preemptirq_delay_test.c ++++ b/kernel/trace/preemptirq_delay_test.c +@@ -34,8 +34,6 @@ MODULE_PARM_DESC(cpu_affinity, "Cpu num test is running on"); + + static struct completion done; + +-#define MIN(x, y) ((x) < (y) ? (x) : (y)) +- + static void busy_wait(ulong time) + { + u64 start, end; +diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c +index c9b0533407edeb..76737492e750e3 100644 +--- a/kernel/trace/trace_dynevent.c ++++ b/kernel/trace/trace_dynevent.c +@@ -239,6 +239,10 @@ static int dyn_event_open(struct inode *inode, struct file *file) + { + int ret; + ++ ret = security_locked_down(LOCKDOWN_TRACEFS); ++ if (ret) ++ return ret; ++ + ret = tracing_check_open_get_tr(NULL); + if (ret) + return ret; +diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c +index 8800f5acc00717..5a2116356428f8 100644 +--- a/kernel/vhost_task.c ++++ b/kernel/vhost_task.c +@@ -100,6 +100,7 @@ void vhost_task_stop(struct vhost_task *vtsk) + * freeing it below. + */ + wait_for_completion(&vtsk->exited); ++ put_task_struct(vtsk->task); + kfree(vtsk); + } + EXPORT_SYMBOL_GPL(vhost_task_stop); +@@ -148,7 +149,7 @@ struct vhost_task *vhost_task_create(bool (*fn)(void *), + return NULL; + } + +- vtsk->task = tsk; ++ vtsk->task = get_task_struct(tsk); + return vtsk; + } + EXPORT_SYMBOL_GPL(vhost_task_create); +diff --git a/lib/btree.c b/lib/btree.c +index 49420cae3a8330..bb81d3393ac5c5 100644 +--- a/lib/btree.c ++++ b/lib/btree.c +@@ -43,7 +43,6 @@ + #include + #include + +-#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define NODESIZE MAX(L1_CACHE_BYTES, 128) + + struct btree_geo { +diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c +index 20a858031f12b7..9d34d35908daa8 100644 +--- a/lib/decompress_unlzma.c ++++ b/lib/decompress_unlzma.c +@@ -37,7 +37,9 @@ + + #include + ++#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++#endif + + static long long INIT read_int(unsigned char *ptr, int size) + { +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 2aa408441cd3e7..f4ab2750cfc129 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1079,7 +1079,7 @@ char *resource_string(char *buf, char *end, struct resource *res, + #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) + #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") + #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") +- char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, ++ char sym[MAX(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, + 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; + + char *p = sym, *pend = sym + sizeof(sym); +diff --git a/mm/gup.c b/mm/gup.c +index 29c719b3ab31e1..53154b63295ab6 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -1946,14 +1946,14 @@ struct page *get_dump_page(unsigned long addr) + /* + * Returns the number of collected pages. Return value is always >= 0. + */ +-static void collect_longterm_unpinnable_pages( ++static unsigned long collect_longterm_unpinnable_pages( + struct list_head *movable_page_list, + unsigned long nr_pages, + struct page **pages) + { ++ unsigned long i, collected = 0; + struct folio *prev_folio = NULL; +- bool drain_allow = true; +- unsigned long i; ++ int drained = 0; + + for (i = 0; i < nr_pages; i++) { + struct folio *folio = page_folio(pages[i]); +@@ -1965,6 +1965,8 @@ static void collect_longterm_unpinnable_pages( + if (folio_is_longterm_pinnable(folio)) + continue; + ++ collected++; ++ + if (folio_is_device_coherent(folio)) + continue; + +@@ -1973,9 +1975,17 @@ static void collect_longterm_unpinnable_pages( + continue; + } + +- if (!folio_test_lru(folio) && drain_allow) { ++ if (drained == 0 && folio_may_be_lru_cached(folio) && ++ folio_ref_count(folio) != ++ folio_expected_ref_count(folio) + 1) { ++ lru_add_drain(); ++ drained = 1; ++ } ++ if (drained == 1 && folio_may_be_lru_cached(folio) && ++ folio_ref_count(folio) != ++ folio_expected_ref_count(folio) + 1) { + lru_add_drain_all(); +- drain_allow = false; ++ drained = 2; + } + + if (!folio_isolate_lru(folio)) +@@ -1986,6 +1996,8 @@ static void collect_longterm_unpinnable_pages( + NR_ISOLATED_ANON + folio_is_file_lru(folio), + folio_nr_pages(folio)); + } ++ ++ return collected; + } + + /* +@@ -2078,10 +2090,12 @@ static int migrate_longterm_unpinnable_pages( + static long check_and_migrate_movable_pages(unsigned long nr_pages, + struct page **pages) + { ++ unsigned long collected; + LIST_HEAD(movable_page_list); + +- collect_longterm_unpinnable_pages(&movable_page_list, nr_pages, pages); +- if (list_empty(&movable_page_list)) ++ collected = collect_longterm_unpinnable_pages(&movable_page_list, ++ nr_pages, pages); ++ if (!collected) + return 0; + + return migrate_longterm_unpinnable_pages(&movable_page_list, nr_pages, +diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c +index 38a3bff23e8d00..38155d6982152a 100644 +--- a/mm/kmsan/core.c ++++ b/mm/kmsan/core.c +@@ -262,7 +262,8 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b, + u32 origin, bool checked) + { + u64 address = (u64)addr; +- u32 *shadow_start, *origin_start; ++ void *shadow_start; ++ u32 *aligned_shadow, *origin_start; + size_t pad = 0; + + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(addr, size)); +@@ -281,9 +282,12 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b, + } + __memset(shadow_start, b, size); + +- if (!IS_ALIGNED(address, KMSAN_ORIGIN_SIZE)) { ++ if (IS_ALIGNED(address, KMSAN_ORIGIN_SIZE)) { ++ aligned_shadow = shadow_start; ++ } else { + pad = address % KMSAN_ORIGIN_SIZE; + address -= pad; ++ aligned_shadow = shadow_start - pad; + size += pad; + } + size = ALIGN(size, KMSAN_ORIGIN_SIZE); +@@ -297,7 +301,7 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b, + * corresponding shadow slot is zero. + */ + for (int i = 0; i < size / KMSAN_ORIGIN_SIZE; i++) { +- if (origin || !shadow_start[i]) ++ if (origin || !aligned_shadow[i]) + origin_start[i] = origin; + } + } +diff --git a/mm/kmsan/kmsan_test.c b/mm/kmsan/kmsan_test.c +index 312989aa2865c4..e98c89d3a73aa4 100644 +--- a/mm/kmsan/kmsan_test.c ++++ b/mm/kmsan/kmsan_test.c +@@ -523,6 +523,21 @@ DEFINE_TEST_MEMSETXX(16) + DEFINE_TEST_MEMSETXX(32) + DEFINE_TEST_MEMSETXX(64) + ++/* Test case: ensure that KMSAN does not access shadow memory out of bounds. */ ++static void test_memset_on_guarded_buffer(struct kunit *test) ++{ ++ void *buf = vmalloc(PAGE_SIZE); ++ ++ kunit_info(test, ++ "memset() on ends of guarded buffer should not crash\n"); ++ ++ for (size_t size = 0; size <= 128; size++) { ++ memset(buf, 0xff, size); ++ memset(buf + PAGE_SIZE - size, 0xff, size); ++ } ++ vfree(buf); ++} ++ + static noinline void fibonacci(int *array, int size, int start) + { + if (start < 2 || (start == size)) +@@ -602,6 +617,7 @@ static struct kunit_case kmsan_test_cases[] = { + KUNIT_CASE(test_memset16), + KUNIT_CASE(test_memset32), + KUNIT_CASE(test_memset64), ++ KUNIT_CASE(test_memset_on_guarded_buffer), + KUNIT_CASE(test_long_origin_chain), + KUNIT_CASE(test_stackdepot_roundtrip), + {}, +diff --git a/mm/migrate_device.c b/mm/migrate_device.c +index 8ac1f79f754a29..f209dc512d8216 100644 +--- a/mm/migrate_device.c ++++ b/mm/migrate_device.c +@@ -814,42 +814,40 @@ void migrate_device_finalize(unsigned long *src_pfns, + unsigned long i; + + for (i = 0; i < npages; i++) { +- struct folio *dst, *src; ++ struct folio *dst = NULL, *src = NULL; + struct page *newpage = migrate_pfn_to_page(dst_pfns[i]); + struct page *page = migrate_pfn_to_page(src_pfns[i]); + ++ if (newpage) ++ dst = page_folio(newpage); ++ + if (!page) { +- if (newpage) { +- unlock_page(newpage); +- put_page(newpage); ++ if (dst) { ++ folio_unlock(dst); ++ folio_put(dst); + } + continue; + } + +- if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE) || !newpage) { +- if (newpage) { +- unlock_page(newpage); +- put_page(newpage); ++ src = page_folio(page); ++ ++ if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE) || !dst) { ++ if (dst) { ++ folio_unlock(dst); ++ folio_put(dst); + } +- newpage = page; ++ dst = src; + } + +- src = page_folio(page); +- dst = page_folio(newpage); ++ if (!folio_is_zone_device(dst)) ++ folio_add_lru(dst); + remove_migration_ptes(src, dst, false); + folio_unlock(src); ++ folio_put(src); + +- if (is_zone_device_page(page)) +- put_page(page); +- else +- putback_lru_page(page); +- +- if (newpage != page) { +- unlock_page(newpage); +- if (is_zone_device_page(newpage)) +- put_page(newpage); +- else +- putback_lru_page(newpage); ++ if (dst != src) { ++ folio_unlock(dst); ++ folio_put(dst); + } + } + } +diff --git a/mm/mlock.c b/mm/mlock.c +index 06bdfab83b58af..6858095c20dd9c 100644 +--- a/mm/mlock.c ++++ b/mm/mlock.c +@@ -256,7 +256,7 @@ void mlock_folio(struct folio *folio) + + folio_get(folio); + if (!folio_batch_add(fbatch, mlock_lru(folio)) || +- folio_test_large(folio) || lru_cache_disabled()) ++ !folio_may_be_lru_cached(folio) || lru_cache_disabled()) + mlock_folio_batch(fbatch); + local_unlock(&mlock_fbatch.lock); + } +@@ -279,7 +279,7 @@ void mlock_new_folio(struct folio *folio) + + folio_get(folio); + if (!folio_batch_add(fbatch, mlock_new(folio)) || +- folio_test_large(folio) || lru_cache_disabled()) ++ !folio_may_be_lru_cached(folio) || lru_cache_disabled()) + mlock_folio_batch(fbatch); + local_unlock(&mlock_fbatch.lock); + } +@@ -300,7 +300,7 @@ void munlock_folio(struct folio *folio) + */ + folio_get(folio); + if (!folio_batch_add(fbatch, folio) || +- folio_test_large(folio) || lru_cache_disabled()) ++ !folio_may_be_lru_cached(folio) || lru_cache_disabled()) + mlock_folio_batch(fbatch); + local_unlock(&mlock_fbatch.lock); + } +diff --git a/mm/swap.c b/mm/swap.c +index 42082eba42de3e..8fde1a27aa4825 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -220,8 +220,8 @@ static void folio_batch_move_lru(struct folio_batch *fbatch, move_fn_t move_fn) + static void folio_batch_add_and_move(struct folio_batch *fbatch, + struct folio *folio, move_fn_t move_fn) + { +- if (folio_batch_add(fbatch, folio) && !folio_test_large(folio) && +- !lru_cache_disabled()) ++ if (folio_batch_add(fbatch, folio) && ++ folio_may_be_lru_cached(folio) && !lru_cache_disabled()) + return; + folio_batch_move_lru(fbatch, move_fn); + } +diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c +index c82070167d8aa8..14327fc34aa713 100644 +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -119,8 +119,6 @@ + #define ISOLATED_BITS 5 + #define MAGIC_VAL_BITS 8 + +-#define MAX(a, b) ((a) >= (b) ? (a) : (b)) +- + #define ZS_MAX_PAGES_PER_ZSPAGE (_AC(CONFIG_ZSMALLOC_CHAIN_SIZE, UL)) + + /* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 5eed23b8d6c332..7bda00dcb0b2f0 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -3048,8 +3048,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, + + hci_dev_lock(hdev); + ++ /* Check for existing connection: ++ * ++ * 1. If it doesn't exist then it must be receiver/slave role. ++ * 2. If it does exist confirm that it is connecting/BT_CONNECT in case ++ * of initiator/master role since there could be a collision where ++ * either side is attempting to connect or something like a fuzzing ++ * testing is trying to play tricks to destroy the hcon object before ++ * it even attempts to connect (e.g. hcon->state == BT_OPEN). ++ */ + conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); +- if (!conn) { ++ if (!conn || ++ (conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { + /* In case of error status and there is no connection pending + * just unlock as there is nothing to cleanup. + */ +@@ -5615,8 +5625,18 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, + */ + hci_dev_clear_flag(hdev, HCI_LE_ADV); + +- conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); +- if (!conn) { ++ /* Check for existing connection: ++ * ++ * 1. If it doesn't exist then use the role to create a new object. ++ * 2. If it does exist confirm that it is connecting/BT_CONNECT in case ++ * of initiator/master role since there could be a collision where ++ * either side is attempting to connect or something like a fuzzing ++ * testing is trying to play tricks to destroy the hcon object before ++ * it even attempts to connect (e.g. hcon->state == BT_OPEN). ++ */ ++ conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr); ++ if (!conn || ++ (conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { + /* In case of error status and there is no connection pending + * just unlock as there is nothing to cleanup. + */ +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 7f3f700faebc24..dc9209f9f1a6a3 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -2639,6 +2639,13 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev) + hci_remove_ext_adv_instance_sync(hdev, adv->instance, + NULL); + } ++ ++ /* If current advertising instance is set to instance 0x00 ++ * then we need to re-enable it. ++ */ ++ if (!hdev->cur_adv_instance) ++ err = hci_enable_ext_advertising_sync(hdev, ++ hdev->cur_adv_instance); + } else { + /* Schedule for most recent instance to be restarted and begin + * the software rotation loop +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 21a83e26f004bb..867832f8bbaea9 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -6330,7 +6330,7 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len, + return NULL; + + while (data_len) { +- if (nr_frags == MAX_SKB_FRAGS - 1) ++ if (nr_frags == MAX_SKB_FRAGS) + goto failure; + while (order && PAGE_ALIGN(data_len) < (PAGE_SIZE << order)) + order--; +diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c +index 8d41b039421976..fab550633ec9f3 100644 +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -2136,6 +2136,13 @@ static int replace_nexthop_single(struct net *net, struct nexthop *old, + return -EINVAL; + } + ++ if (!list_empty(&old->grp_list) && ++ rtnl_dereference(new->nh_info)->fdb_nh != ++ rtnl_dereference(old->nh_info)->fdb_nh) { ++ NL_SET_ERR_MSG(extack, "Cannot change nexthop FDB status while in a group"); ++ return -EINVAL; ++ } ++ + err = call_nexthop_notifiers(net, NEXTHOP_EVENT_REPLACE, new, extack); + if (err) + return err; +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index acfbe1f013d1b8..ded559f5576754 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -2296,6 +2296,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high, + + for (h = 0; h < range; h++) { + u32 spi = (low == high) ? low : get_random_u32_inclusive(low, high); ++ if (spi == 0) ++ goto next; + newspi = htonl(spi); + + spin_lock_bh(&net->xfrm.xfrm_state_lock); +@@ -2311,6 +2313,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high, + xfrm_state_put(x0); + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + ++next: + if (signal_pending(current)) { + err = -ERESTARTSYS; + goto unlock; +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 68c82e344d3baf..270a0be672b7ec 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -16,6 +16,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -76,7 +77,8 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, + cval->idx_off = idx_off; + + /* get_min_max() is called only for integer volumes later, +- * so provide a short-cut for booleans */ ++ * so provide a short-cut for booleans ++ */ + cval->min = 0; + cval->max = 1; + cval->res = 0; +@@ -125,7 +127,7 @@ static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, + { + int err; + +- while (t->name != NULL) { ++ while (t->name) { + err = snd_create_std_mono_ctl(mixer, t->unitid, t->control, + t->cmask, t->val_type, t->name, t->tlv_callback); + if (err < 0) +@@ -207,7 +209,6 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb) + if (code == rc->mute_code) + snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id); + mixer->rc_code = code; +- wmb(); + wake_up(&mixer->rc_waitq); + } + +@@ -375,10 +376,10 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) + struct snd_kcontrol_new knew; + + /* USB X-Fi S51 doesn't have a CMSS LED */ +- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) ++ if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042) && i == 0) + continue; + /* USB X-Fi S51 Pro doesn't have one either */ +- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0) ++ if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df) && i == 0) + continue; + if (i > 1 && /* Live24ext has 2 LEDs only */ + (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || +@@ -527,6 +528,265 @@ static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) + &snd_emu0204_control, NULL); + } + ++#if IS_REACHABLE(CONFIG_INPUT) ++/* ++ * Sony DualSense controller (PS5) jack detection ++ * ++ * Since this is an UAC 1 device, it doesn't support jack detection. ++ * However, the controller hid-playstation driver reports HP & MIC ++ * insert events through a dedicated input device. ++ */ ++ ++#define SND_DUALSENSE_JACK_OUT_TERM_ID 3 ++#define SND_DUALSENSE_JACK_IN_TERM_ID 4 ++ ++struct dualsense_mixer_elem_info { ++ struct usb_mixer_elem_info info; ++ struct input_handler ih; ++ struct input_device_id id_table[2]; ++ bool connected; ++}; ++ ++static void snd_dualsense_ih_event(struct input_handle *handle, ++ unsigned int type, unsigned int code, ++ int value) ++{ ++ struct dualsense_mixer_elem_info *mei; ++ struct usb_mixer_elem_list *me; ++ ++ if (type != EV_SW) ++ return; ++ ++ mei = container_of(handle->handler, struct dualsense_mixer_elem_info, ih); ++ me = &mei->info.head; ++ ++ if ((me->id == SND_DUALSENSE_JACK_OUT_TERM_ID && code == SW_HEADPHONE_INSERT) || ++ (me->id == SND_DUALSENSE_JACK_IN_TERM_ID && code == SW_MICROPHONE_INSERT)) { ++ mei->connected = !!value; ++ snd_ctl_notify(me->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, ++ &me->kctl->id); ++ } ++} ++ ++static bool snd_dualsense_ih_match(struct input_handler *handler, ++ struct input_dev *dev) ++{ ++ struct dualsense_mixer_elem_info *mei; ++ struct usb_device *snd_dev; ++ char *input_dev_path, *usb_dev_path; ++ size_t usb_dev_path_len; ++ bool match = false; ++ ++ mei = container_of(handler, struct dualsense_mixer_elem_info, ih); ++ snd_dev = mei->info.head.mixer->chip->dev; ++ ++ input_dev_path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); ++ if (!input_dev_path) { ++ dev_warn(&snd_dev->dev, "Failed to get input dev path\n"); ++ return false; ++ } ++ ++ usb_dev_path = kobject_get_path(&snd_dev->dev.kobj, GFP_KERNEL); ++ if (!usb_dev_path) { ++ dev_warn(&snd_dev->dev, "Failed to get USB dev path\n"); ++ goto free_paths; ++ } ++ ++ /* ++ * Ensure the VID:PID matched input device supposedly owned by the ++ * hid-playstation driver belongs to the actual hardware handled by ++ * the current USB audio device, which implies input_dev_path being ++ * a subpath of usb_dev_path. ++ * ++ * This verification is necessary when there is more than one identical ++ * controller attached to the host system. ++ */ ++ usb_dev_path_len = strlen(usb_dev_path); ++ if (usb_dev_path_len >= strlen(input_dev_path)) ++ goto free_paths; ++ ++ usb_dev_path[usb_dev_path_len] = '/'; ++ match = !memcmp(input_dev_path, usb_dev_path, usb_dev_path_len + 1); ++ ++free_paths: ++ kfree(input_dev_path); ++ kfree(usb_dev_path); ++ ++ return match; ++} ++ ++static int snd_dualsense_ih_connect(struct input_handler *handler, ++ struct input_dev *dev, ++ const struct input_device_id *id) ++{ ++ struct input_handle *handle; ++ int err; ++ ++ handle = kzalloc(sizeof(*handle), GFP_KERNEL); ++ if (!handle) ++ return -ENOMEM; ++ ++ handle->dev = dev; ++ handle->handler = handler; ++ handle->name = handler->name; ++ ++ err = input_register_handle(handle); ++ if (err) ++ goto err_free; ++ ++ err = input_open_device(handle); ++ if (err) ++ goto err_unregister; ++ ++ return 0; ++ ++err_unregister: ++ input_unregister_handle(handle); ++err_free: ++ kfree(handle); ++ return err; ++} ++ ++static void snd_dualsense_ih_disconnect(struct input_handle *handle) ++{ ++ input_close_device(handle); ++ input_unregister_handle(handle); ++ kfree(handle); ++} ++ ++static void snd_dualsense_ih_start(struct input_handle *handle) ++{ ++ struct dualsense_mixer_elem_info *mei; ++ struct usb_mixer_elem_list *me; ++ int status = -1; ++ ++ mei = container_of(handle->handler, struct dualsense_mixer_elem_info, ih); ++ me = &mei->info.head; ++ ++ if (me->id == SND_DUALSENSE_JACK_OUT_TERM_ID && ++ test_bit(SW_HEADPHONE_INSERT, handle->dev->swbit)) ++ status = test_bit(SW_HEADPHONE_INSERT, handle->dev->sw); ++ else if (me->id == SND_DUALSENSE_JACK_IN_TERM_ID && ++ test_bit(SW_MICROPHONE_INSERT, handle->dev->swbit)) ++ status = test_bit(SW_MICROPHONE_INSERT, handle->dev->sw); ++ ++ if (status >= 0) { ++ mei->connected = !!status; ++ snd_ctl_notify(me->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, ++ &me->kctl->id); ++ } ++} ++ ++static int snd_dualsense_jack_get(struct snd_kcontrol *kctl, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct dualsense_mixer_elem_info *mei = snd_kcontrol_chip(kctl); ++ ++ ucontrol->value.integer.value[0] = mei->connected; ++ ++ return 0; ++} ++ ++static const struct snd_kcontrol_new snd_dualsense_jack_control = { ++ .iface = SNDRV_CTL_ELEM_IFACE_CARD, ++ .access = SNDRV_CTL_ELEM_ACCESS_READ, ++ .info = snd_ctl_boolean_mono_info, ++ .get = snd_dualsense_jack_get, ++}; ++ ++static int snd_dualsense_resume_jack(struct usb_mixer_elem_list *list) ++{ ++ snd_ctl_notify(list->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, ++ &list->kctl->id); ++ return 0; ++} ++ ++static void snd_dualsense_mixer_elem_free(struct snd_kcontrol *kctl) ++{ ++ struct dualsense_mixer_elem_info *mei = snd_kcontrol_chip(kctl); ++ ++ if (mei->ih.event) ++ input_unregister_handler(&mei->ih); ++ ++ snd_usb_mixer_elem_free(kctl); ++} ++ ++static int snd_dualsense_jack_create(struct usb_mixer_interface *mixer, ++ const char *name, bool is_output) ++{ ++ struct dualsense_mixer_elem_info *mei; ++ struct input_device_id *idev_id; ++ struct snd_kcontrol *kctl; ++ int err; ++ ++ mei = kzalloc(sizeof(*mei), GFP_KERNEL); ++ if (!mei) ++ return -ENOMEM; ++ ++ snd_usb_mixer_elem_init_std(&mei->info.head, mixer, ++ is_output ? SND_DUALSENSE_JACK_OUT_TERM_ID : ++ SND_DUALSENSE_JACK_IN_TERM_ID); ++ ++ mei->info.head.resume = snd_dualsense_resume_jack; ++ mei->info.val_type = USB_MIXER_BOOLEAN; ++ mei->info.channels = 1; ++ mei->info.min = 0; ++ mei->info.max = 1; ++ ++ kctl = snd_ctl_new1(&snd_dualsense_jack_control, mei); ++ if (!kctl) { ++ kfree(mei); ++ return -ENOMEM; ++ } ++ ++ strscpy(kctl->id.name, name, sizeof(kctl->id.name)); ++ kctl->private_free = snd_dualsense_mixer_elem_free; ++ ++ err = snd_usb_mixer_add_control(&mei->info.head, kctl); ++ if (err) ++ return err; ++ ++ idev_id = &mei->id_table[0]; ++ idev_id->flags = INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT | ++ INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT; ++ idev_id->vendor = USB_ID_VENDOR(mixer->chip->usb_id); ++ idev_id->product = USB_ID_PRODUCT(mixer->chip->usb_id); ++ idev_id->evbit[BIT_WORD(EV_SW)] = BIT_MASK(EV_SW); ++ if (is_output) ++ idev_id->swbit[BIT_WORD(SW_HEADPHONE_INSERT)] = BIT_MASK(SW_HEADPHONE_INSERT); ++ else ++ idev_id->swbit[BIT_WORD(SW_MICROPHONE_INSERT)] = BIT_MASK(SW_MICROPHONE_INSERT); ++ ++ mei->ih.event = snd_dualsense_ih_event; ++ mei->ih.match = snd_dualsense_ih_match; ++ mei->ih.connect = snd_dualsense_ih_connect; ++ mei->ih.disconnect = snd_dualsense_ih_disconnect; ++ mei->ih.start = snd_dualsense_ih_start; ++ mei->ih.name = name; ++ mei->ih.id_table = mei->id_table; ++ ++ err = input_register_handler(&mei->ih); ++ if (err) { ++ dev_warn(&mixer->chip->dev->dev, ++ "Could not register input handler: %d\n", err); ++ mei->ih.event = NULL; ++ } ++ ++ return 0; ++} ++ ++static int snd_dualsense_controls_create(struct usb_mixer_interface *mixer) ++{ ++ int err; ++ ++ err = snd_dualsense_jack_create(mixer, "Headphone Jack", true); ++ if (err < 0) ++ return err; ++ ++ return snd_dualsense_jack_create(mixer, "Headset Mic Jack", false); ++} ++#endif /* IS_REACHABLE(CONFIG_INPUT) */ ++ + /* ASUS Xonar U1 / U3 controls */ + + static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, +@@ -1733,7 +1993,8 @@ static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, + unsigned int pval, pval_old; + int err; + +- pval = pval_old = kcontrol->private_value; ++ pval = kcontrol->private_value; ++ pval_old = pval; + pval &= 0xfffff0f0; + pval |= (ucontrol->value.iec958.status[1] & 0x0f) << 8; + pval |= (ucontrol->value.iec958.status[0] & 0x0f); +@@ -3271,7 +3532,7 @@ static int snd_djm_controls_update(struct usb_mixer_interface *mixer, + int err; + const struct snd_djm_device *device = &snd_djm_devices[device_idx]; + +- if ((group >= device->ncontrols) || value >= device->controls[group].noptions) ++ if (group >= device->ncontrols || value >= device->controls[group].noptions) + return -EINVAL; + + err = snd_usb_lock_shutdown(mixer->chip); +@@ -3389,6 +3650,13 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) + err = snd_emu0204_controls_create(mixer); + break; + ++#if IS_REACHABLE(CONFIG_INPUT) ++ case USB_ID(0x054c, 0x0ce6): /* Sony DualSense controller (PS5) */ ++ case USB_ID(0x054c, 0x0df2): /* Sony DualSense Edge controller (PS5) */ ++ err = snd_dualsense_controls_create(mixer); ++ break; ++#endif /* IS_REACHABLE(CONFIG_INPUT) */ ++ + case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ + case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */ + err = snd_c400_create_mixer(mixer); +@@ -3546,7 +3814,8 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, + struct snd_kcontrol *kctl) + { + /* Approximation using 10 ranges based on output measurement on hw v1.2. +- * This seems close to the cubic mapping e.g. alsamixer uses. */ ++ * This seems close to the cubic mapping e.g. alsamixer uses. ++ */ + static const DECLARE_TLV_DB_RANGE(scale, + 0, 1, TLV_DB_MINMAX_ITEM(-5300, -4970), + 2, 5, TLV_DB_MINMAX_ITEM(-4710, -4160), +@@ -3630,16 +3899,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, + if (unitid == 7 && cval->control == UAC_FU_VOLUME) + snd_dragonfly_quirk_db_scale(mixer, cval, kctl); + break; ++ } ++ + /* lowest playback value is muted on some devices */ +- case USB_ID(0x0572, 0x1b09): /* Conexant Systems (Rockwell), Inc. */ +- case USB_ID(0x0d8c, 0x000c): /* C-Media */ +- case USB_ID(0x0d8c, 0x0014): /* C-Media */ +- case USB_ID(0x19f7, 0x0003): /* RODE NT-USB */ +- case USB_ID(0x2d99, 0x0026): /* HECATE G2 GAMING HEADSET */ ++ if (mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_MIN_MUTE) + if (strstr(kctl->id.name, "Playback")) + cval->min_mute = 1; +- break; +- } + + /* ALSA-ify some Plantronics headset control names */ + if (USB_ID_VENDOR(mixer->chip->usb_id) == 0x047f && +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index f19c808444c97a..7d747677b58da8 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2096,6 +2096,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_SET_IFACE_FIRST), + DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x0572, 0x1b08, /* Conexant Systems (Rockwell), Inc. */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), ++ DEVICE_FLG(0x0572, 0x1b09, /* Conexant Systems (Rockwell), Inc. */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x05a3, 0x9420, /* ELP HD USB Camera */ + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x05a7, 0x1020, /* Bose Companion 5 */ +@@ -2138,12 +2142,16 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x0bda, 0x498a, /* Realtek Semiconductor Corp. */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */ + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x0c45, 0x636b, /* Microdia JP001 USB Camera */ + QUIRK_FLAG_GET_SAMPLE_RATE), +- DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */ +- QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x0d8c, 0x000c, /* C-Media */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), ++ DEVICE_FLG(0x0d8c, 0x0014, /* C-Media */ ++ QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ + QUIRK_FLAG_FIXED_RATE), + DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ +@@ -2152,6 +2160,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), + DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x12d1, 0x3a07, /* Huawei Technologies Co., Ltd. */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ + QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16), + DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ +@@ -2190,6 +2200,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x19f7, 0x0003, /* RODE NT-USB */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */ + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1bcf, 0x2281, /* HD Webcam */ +@@ -2240,6 +2252,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */ +@@ -2250,10 +2264,14 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x2d99, 0x0026, /* HECATE G2 GAMING HEADSET */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), ++ DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */ ++ QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */ +@@ -2305,6 +2323,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2d87, /* Cayin device */ + QUIRK_FLAG_DSD_RAW), ++ VENDOR_FLG(0x2fc6, /* Comture-inc devices */ ++ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x3336, /* HEM devices */ + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x3353, /* Khadas devices */ +diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h +index ddfbe045e7a941..3c927316bc9929 100644 +--- a/sound/usb/usbaudio.h ++++ b/sound/usb/usbaudio.h +@@ -184,6 +184,9 @@ extern bool snd_usb_skip_validation; + * for the given endpoint. + * QUIRK_FLAG_MIC_RES_16 and QUIRK_FLAG_MIC_RES_384 + * Set the fixed resolution for Mic Capture Volume (mostly for webcams) ++ * QUIRK_FLAG_MIXER_MIN_MUTE ++ * Set minimum volume control value as mute for devices where the lowest ++ * playback value represents muted state instead of minimum audible volume + */ + + #define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0) +@@ -210,5 +213,6 @@ extern bool snd_usb_skip_validation; + #define QUIRK_FLAG_FIXED_RATE (1U << 21) + #define QUIRK_FLAG_MIC_RES_16 (1U << 22) + #define QUIRK_FLAG_MIC_RES_384 (1U << 23) ++#define QUIRK_FLAG_MIXER_MIN_MUTE (1U << 24) + + #endif /* __USBAUDIO_H */ +diff --git a/tools/testing/selftests/mm/mremap_test.c b/tools/testing/selftests/mm/mremap_test.c +index 5c3773de9f0f78..944645f9d2b3d7 100644 +--- a/tools/testing/selftests/mm/mremap_test.c ++++ b/tools/testing/selftests/mm/mremap_test.c +@@ -22,7 +22,9 @@ + #define VALIDATION_DEFAULT_THRESHOLD 4 /* 4MB */ + #define VALIDATION_NO_THRESHOLD 0 /* Verify the entire region */ + ++#ifndef MIN + #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) ++#endif + + struct config { + unsigned long long src_alignment; +diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh +index a6f2c0b9555d12..e2e4fffd87e39a 100755 +--- a/tools/testing/selftests/net/fib_nexthops.sh ++++ b/tools/testing/selftests/net/fib_nexthops.sh +@@ -464,8 +464,8 @@ ipv6_fdb_grp_fcnal() + log_test $? 0 "Get Fdb nexthop group by id" + + # fdb nexthop group can only contain fdb nexthops +- run_cmd "$IP nexthop add id 63 via 2001:db8:91::4" +- run_cmd "$IP nexthop add id 64 via 2001:db8:91::5" ++ run_cmd "$IP nexthop add id 63 via 2001:db8:91::4 dev veth1" ++ run_cmd "$IP nexthop add id 64 via 2001:db8:91::5 dev veth1" + run_cmd "$IP nexthop add id 103 group 63/64 fdb" + log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" + +@@ -544,15 +544,15 @@ ipv4_fdb_grp_fcnal() + log_test $? 0 "Get Fdb nexthop group by id" + + # fdb nexthop group can only contain fdb nexthops +- run_cmd "$IP nexthop add id 14 via 172.16.1.2" +- run_cmd "$IP nexthop add id 15 via 172.16.1.3" ++ run_cmd "$IP nexthop add id 14 via 172.16.1.2 dev veth1" ++ run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1" + run_cmd "$IP nexthop add id 103 group 14/15 fdb" + log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" + + # Non fdb nexthop group can not contain fdb nexthops + run_cmd "$IP nexthop add id 16 via 172.16.1.2 fdb" + run_cmd "$IP nexthop add id 17 via 172.16.1.3 fdb" +- run_cmd "$IP nexthop add id 104 group 14/15" ++ run_cmd "$IP nexthop add id 104 group 16/17" + log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops" + + # fdb nexthop cannot have blackhole +@@ -579,7 +579,7 @@ ipv4_fdb_grp_fcnal() + run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self" + log_test $? 255 "Fdb mac add with nexthop" + +- run_cmd "$IP ro add 172.16.0.0/22 nhid 15" ++ run_cmd "$IP ro add 172.16.0.0/22 nhid 16" + log_test $? 2 "Route add with fdb nexthop" + + run_cmd "$IP ro add 172.16.0.0/22 nhid 103" +diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c +index 15325ca35f1e2b..4390965c84c422 100644 +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -60,7 +60,9 @@ + #define SKIP(s, ...) XFAIL(s, ##__VA_ARGS__) + #endif + ++#ifndef MIN + #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) ++#endif + + #ifndef PR_SET_PTRACER + # define PR_SET_PTRACER 0x59616d61 diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.109-110.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.109-110.patch new file mode 100644 index 000000000..09637783c --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.109-110.patch @@ -0,0 +1,327 @@ +diff --git a/Makefile b/Makefile +index afeacf5efc9553..196343089737f3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 109 ++SUBLEVEL = 110 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c +index 486c8ec0fa60d9..ab53c5b02c48df 100644 +--- a/drivers/media/pci/b2c2/flexcop-pci.c ++++ b/drivers/media/pci/b2c2/flexcop-pci.c +@@ -411,7 +411,7 @@ static void flexcop_pci_remove(struct pci_dev *pdev) + struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); + + if (irq_chk_intv > 0) +- cancel_delayed_work(&fc_pci->irq_check_work); ++ cancel_delayed_work_sync(&fc_pci->irq_check_work); + + flexcop_pci_dma_exit(fc_pci); + flexcop_device_exit(fc_pci->fc_dev); +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index e5590a708f1c5d..f4deca8894e0f7 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -536,7 +536,9 @@ static int display_open(struct inode *inode, struct file *file) + + mutex_lock(&ictx->lock); + +- if (!ictx->display_supported) { ++ if (ictx->disconnected) { ++ retval = -ENODEV; ++ } else if (!ictx->display_supported) { + pr_err("display not supported by device\n"); + retval = -ENODEV; + } else if (ictx->display_isopen) { +@@ -598,6 +600,9 @@ static int send_packet(struct imon_context *ictx) + int retval = 0; + struct usb_ctrlrequest *control_req = NULL; + ++ if (ictx->disconnected) ++ return -ENODEV; ++ + /* Check if we need to use control or interrupt urb */ + if (!ictx->tx_control) { + pipe = usb_sndintpipe(ictx->usbdev_intf0, +@@ -949,12 +954,14 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, + static const unsigned char vfd_packet6[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; + +- if (ictx->disconnected) +- return -ENODEV; +- + if (mutex_lock_interruptible(&ictx->lock)) + return -ERESTARTSYS; + ++ if (ictx->disconnected) { ++ retval = -ENODEV; ++ goto exit; ++ } ++ + if (!ictx->dev_present_intf0) { + pr_err_ratelimited("no iMON device present\n"); + retval = -ENODEV; +@@ -1029,11 +1036,13 @@ static ssize_t lcd_write(struct file *file, const char __user *buf, + int retval = 0; + struct imon_context *ictx = file->private_data; + +- if (ictx->disconnected) +- return -ENODEV; +- + mutex_lock(&ictx->lock); + ++ if (ictx->disconnected) { ++ retval = -ENODEV; ++ goto exit; ++ } ++ + if (!ictx->display_supported) { + pr_err_ratelimited("no iMON display present\n"); + retval = -ENODEV; +@@ -2499,7 +2508,11 @@ static void imon_disconnect(struct usb_interface *interface) + int ifnum; + + ictx = usb_get_intfdata(interface); ++ ++ mutex_lock(&ictx->lock); + ictx->disconnected = true; ++ mutex_unlock(&ictx->lock); ++ + dev = ictx->dev; + ifnum = interface->cur_altsetting->desc.bInterfaceNumber; + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 09753993068a95..c7cee6b185264d 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -135,6 +135,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id) + { + struct uvc_entity *entity; + ++ if (id == UVC_INVALID_ENTITY_ID) ++ return NULL; ++ + list_for_each_entry(entity, &dev->entities, list) { + if (entity->id == id) + return entity; +@@ -778,14 +781,27 @@ static const u8 uvc_media_transport_input_guid[16] = + UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; + static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; + +-static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, +- unsigned int num_pads, unsigned int extra_size) ++static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, ++ u16 id, unsigned int num_pads, ++ unsigned int extra_size) + { + struct uvc_entity *entity; + unsigned int num_inputs; + unsigned int size; + unsigned int i; + ++ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ ++ if (id == 0) { ++ dev_err(&dev->intf->dev, "Found Unit with invalid ID 0\n"); ++ id = UVC_INVALID_ENTITY_ID; ++ } ++ ++ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ ++ if (uvc_entity_by_id(dev, id)) { ++ dev_err(&dev->intf->dev, "Found multiple Units with ID %u\n", id); ++ id = UVC_INVALID_ENTITY_ID; ++ } ++ + extra_size = roundup(extra_size, sizeof(*entity->pads)); + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; +@@ -795,7 +811,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, + + num_inputs; + entity = kzalloc(size, GFP_KERNEL); + if (entity == NULL) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + entity->id = id; + entity->type = type; +@@ -907,10 +923,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + break; + } + +- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], +- p + 1, 2*n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT, ++ buffer[3], p + 1, 2 * n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1019,10 +1035,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], +- 1, n + p); +- if (term == NULL) +- return -ENOMEM; ++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT, ++ buffer[3], 1, n + p); ++ if (IS_ERR(term)) ++ return PTR_ERR(term); + + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { + term->camera.bControlSize = n; +@@ -1078,10 +1094,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return 0; + } + +- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], +- 1, 0); +- if (term == NULL) +- return -ENOMEM; ++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT, ++ buffer[3], 1, 0); ++ if (IS_ERR(term)) ++ return PTR_ERR(term); + + memcpy(term->baSourceID, &buffer[7], 1); + +@@ -1100,9 +1116,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], ++ p + 1, 0); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->baSourceID, &buffer[5], p); + +@@ -1122,9 +1139,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->baSourceID, &buffer[4], 1); + unit->processing.wMaxMultiplier = +@@ -1151,9 +1168,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], ++ p + 1, n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1293,9 +1311,10 @@ static int uvc_gpio_parse(struct uvc_device *dev) + return dev_err_probe(&dev->intf->dev, irq, + "No IRQ for privacy GPIO\n"); + +- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); +- if (!unit) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, ++ UVC_EXT_GPIO_UNIT_ID, 0, 1); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + unit->gpio.gpio_privacy = gpio_privacy; + unit->gpio.irq = irq; +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index e99bfaa622669b..cbb5ce963cd097 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -41,6 +41,8 @@ + #define UVC_EXT_GPIO_UNIT 0x7ffe + #define UVC_EXT_GPIO_UNIT_ID 0x100 + ++#define UVC_INVALID_ENTITY_ID 0xffff ++ + /* ------------------------------------------------------------------------ + * Driver specific constants. + */ +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 9a88774836c9db..eddcfd09c05b86 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2738,7 +2738,7 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + config_item_name(&dev->dev_group.cg_item)); + cur_len++; /* Extra byte for NULL terminator */ + +- if ((cur_len + len) > PAGE_SIZE) { ++ if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" + "_members buffer\n"); + break; +diff --git a/include/crypto/sha256_base.h b/include/crypto/sha256_base.h +index ab904d82236fb8..0f5f3a6f79f0cf 100644 +--- a/include/crypto/sha256_base.h ++++ b/include/crypto/sha256_base.h +@@ -44,7 +44,7 @@ static inline int lib_sha256_base_do_update(struct sha256_state *sctx, + sctx->count += len; + + if (unlikely((partial + len) >= SHA256_BLOCK_SIZE)) { +- int blocks; ++ unsigned int blocks; + + if (partial) { + int p = SHA256_BLOCK_SIZE - partial; +diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h +index 90e83d62adb547..de1e4c927cbc76 100644 +--- a/scripts/gcc-plugins/gcc-common.h ++++ b/scripts/gcc-plugins/gcc-common.h +@@ -196,10 +196,17 @@ inline bool is_a_helper::test(const_gimple gs) + } + #endif + ++#if BUILDING_GCC_VERSION < 16000 + #define TODO_verify_ssa TODO_verify_il + #define TODO_verify_flow TODO_verify_il + #define TODO_verify_stmts TODO_verify_il + #define TODO_verify_rtl_sharing TODO_verify_il ++#else ++#define TODO_verify_ssa 0 ++#define TODO_verify_flow 0 ++#define TODO_verify_stmts 0 ++#define TODO_verify_rtl_sharing 0 ++#endif + + #define INSN_DELETED_P(insn) (insn)->deleted() + +diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c +index 70572c83e1017d..d4c3bc85fb3562 100644 +--- a/sound/soc/qcom/qdsp6/topology.c ++++ b/sound/soc/qcom/qdsp6/topology.c +@@ -586,8 +586,8 @@ static int audioreach_widget_load_module_common(struct snd_soc_component *compon + return PTR_ERR(cont); + + mod = audioreach_parse_common_tokens(apm, cont, &tplg_w->priv, w); +- if (IS_ERR(mod)) +- return PTR_ERR(mod); ++ if (IS_ERR_OR_NULL(mod)) ++ return mod ? PTR_ERR(mod) : -ENODEV; + + dobj = &w->dobj; + dobj->private = mod; diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.110-111.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.110-111.patch new file mode 100644 index 000000000..c7965c371 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.110-111.patch @@ -0,0 +1,860 @@ +diff --git a/Makefile b/Makefile +index 196343089737f3..9531c465e9c240 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 110 ++SUBLEVEL = 111 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c +index d0d836448a76b2..83827384982e49 100644 +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -1873,13 +1873,17 @@ static void fpsimd_flush_cpu_state(void) + */ + void fpsimd_save_and_flush_cpu_state(void) + { ++ unsigned long flags; ++ + if (!system_supports_fpsimd()) + return; + WARN_ON(preemptible()); +- get_cpu_fpsimd_context(); ++ local_irq_save(flags); ++ __get_cpu_fpsimd_context(); + fpsimd_save(); + fpsimd_flush_cpu_state(); +- put_cpu_fpsimd_context(); ++ __put_cpu_fpsimd_context(); ++ local_irq_restore(flags); + } + + #ifdef CONFIG_KERNEL_MODE_NEON +diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h +index 4f6af8c6cfa060..4747277983ad1a 100644 +--- a/arch/riscv/include/asm/processor.h ++++ b/arch/riscv/include/asm/processor.h +@@ -13,42 +13,19 @@ + + #include + +-#ifdef CONFIG_64BIT +-#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1)) +-#define STACK_TOP_MAX TASK_SIZE +- + #define arch_get_mmap_end(addr, len, flags) \ + ({ \ +- unsigned long mmap_end; \ +- typeof(addr) _addr = (addr); \ +- if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \ +- mmap_end = STACK_TOP_MAX; \ +- else if ((_addr) >= VA_USER_SV57) \ +- mmap_end = STACK_TOP_MAX; \ +- else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \ +- mmap_end = VA_USER_SV48; \ +- else \ +- mmap_end = VA_USER_SV39; \ +- mmap_end; \ ++ STACK_TOP_MAX; \ + }) + + #define arch_get_mmap_base(addr, base) \ + ({ \ +- unsigned long mmap_base; \ +- typeof(addr) _addr = (addr); \ +- typeof(base) _base = (base); \ +- unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \ +- if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \ +- mmap_base = (_base); \ +- else if (((_addr) >= VA_USER_SV57) && (VA_BITS >= VA_BITS_SV57)) \ +- mmap_base = VA_USER_SV57 - rnd_gap; \ +- else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \ +- mmap_base = VA_USER_SV48 - rnd_gap; \ +- else \ +- mmap_base = VA_USER_SV39 - rnd_gap; \ +- mmap_base; \ ++ base; \ + }) + ++#ifdef CONFIG_64BIT ++#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1)) ++#define STACK_TOP_MAX TASK_SIZE + #else + #define DEFAULT_MAP_WINDOW TASK_SIZE + #define STACK_TOP_MAX TASK_SIZE +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 2673cd5c46cb48..313cb2ffd6aae6 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -5134,12 +5134,11 @@ void init_decode_cache(struct x86_emulate_ctxt *ctxt) + ctxt->mem_read.end = 0; + } + +-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ++int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, bool check_intercepts) + { + const struct x86_emulate_ops *ops = ctxt->ops; + int rc = X86EMUL_CONTINUE; + int saved_dst_type = ctxt->dst.type; +- bool is_guest_mode = ctxt->ops->is_guest_mode(ctxt); + + ctxt->mem_read.pos = 0; + +@@ -5187,7 +5186,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) + fetch_possible_mmx_operand(&ctxt->dst); + } + +- if (unlikely(is_guest_mode) && ctxt->intercept) { ++ if (unlikely(check_intercepts) && ctxt->intercept) { + rc = emulator_check_intercept(ctxt, ctxt->intercept, + X86_ICPT_PRE_EXCEPT); + if (rc != X86EMUL_CONTINUE) +@@ -5216,7 +5215,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) + goto done; + } + +- if (unlikely(is_guest_mode) && (ctxt->d & Intercept)) { ++ if (unlikely(check_intercepts) && (ctxt->d & Intercept)) { + rc = emulator_check_intercept(ctxt, ctxt->intercept, + X86_ICPT_POST_EXCEPT); + if (rc != X86EMUL_CONTINUE) +@@ -5270,7 +5269,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) + + special_insn: + +- if (unlikely(is_guest_mode) && (ctxt->d & Intercept)) { ++ if (unlikely(check_intercepts) && (ctxt->d & Intercept)) { + rc = emulator_check_intercept(ctxt, ctxt->intercept, + X86_ICPT_POST_MEMACCESS); + if (rc != X86EMUL_CONTINUE) +diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h +index be7aeb9b8ea3b1..b940ee604bd849 100644 +--- a/arch/x86/kvm/kvm_emulate.h ++++ b/arch/x86/kvm/kvm_emulate.h +@@ -220,7 +220,6 @@ struct x86_emulate_ops { + void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked); + + bool (*is_smm)(struct x86_emulate_ctxt *ctxt); +- bool (*is_guest_mode)(struct x86_emulate_ctxt *ctxt); + int (*leave_smm)(struct x86_emulate_ctxt *ctxt); + void (*triple_fault)(struct x86_emulate_ctxt *ctxt); + int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr); +@@ -498,7 +497,7 @@ bool x86_page_table_writing_insn(struct x86_emulate_ctxt *ctxt); + #define EMULATION_RESTART 1 + #define EMULATION_INTERCEPTED 2 + void init_decode_cache(struct x86_emulate_ctxt *ctxt); +-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt); ++int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, bool check_intercepts); + int emulator_task_switch(struct x86_emulate_ctxt *ctxt, + u16 tss_selector, int idt_index, int reason, + bool has_error_code, u32 error_code); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 7238686a49bb5a..71d60d4e991fd3 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -8308,11 +8308,6 @@ static bool emulator_is_smm(struct x86_emulate_ctxt *ctxt) + return is_smm(emul_to_vcpu(ctxt)); + } + +-static bool emulator_is_guest_mode(struct x86_emulate_ctxt *ctxt) +-{ +- return is_guest_mode(emul_to_vcpu(ctxt)); +-} +- + #ifndef CONFIG_KVM_SMM + static int emulator_leave_smm(struct x86_emulate_ctxt *ctxt) + { +@@ -8379,7 +8374,6 @@ static const struct x86_emulate_ops emulate_ops = { + .guest_has_rdpid = emulator_guest_has_rdpid, + .set_nmi_mask = emulator_set_nmi_mask, + .is_smm = emulator_is_smm, +- .is_guest_mode = emulator_is_guest_mode, + .leave_smm = emulator_leave_smm, + .triple_fault = emulator_triple_fault, + .set_xcr = emulator_set_xcr, +@@ -8999,7 +8993,14 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, + ctxt->exception.address = 0; + } + +- r = x86_emulate_insn(ctxt); ++ /* ++ * Check L1's instruction intercepts when emulating instructions for ++ * L2, unless KVM is re-emulating a previously decoded instruction, ++ * e.g. to complete userspace I/O, in which case KVM has already ++ * checked the intercepts. ++ */ ++ r = x86_emulate_insn(ctxt, is_guest_mode(vcpu) && ++ !(emulation_type & EMULTYPE_NO_DECODE)); + + if (r == EMULATION_INTERCEPTED) + return 1; +diff --git a/crypto/rng.c b/crypto/rng.c +index 279dffdebf5981..e462031fef68c6 100644 +--- a/crypto/rng.c ++++ b/crypto/rng.c +@@ -197,6 +197,11 @@ int crypto_del_default_rng(void) + EXPORT_SYMBOL_GPL(crypto_del_default_rng); + #endif + ++static void rng_default_set_ent(struct crypto_rng *tfm, const u8 *data, ++ unsigned int len) ++{ ++} ++ + int crypto_register_rng(struct rng_alg *alg) + { + struct crypto_istat_rng *istat = rng_get_stat(alg); +@@ -212,6 +217,9 @@ int crypto_register_rng(struct rng_alg *alg) + if (IS_ENABLED(CONFIG_CRYPTO_STATS)) + memset(istat, 0, sizeof(*istat)); + ++ if (!alg->set_ent) ++ alg->set_ent = rng_default_set_ent; ++ + return crypto_register_alg(base); + } + EXPORT_SYMBOL_GPL(crypto_register_rng); +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index a985301a4135f5..d2d413c829f44a 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -814,6 +814,10 @@ static int mcp2221_raw_event(struct hid_device *hdev, + } + if (data[2] == MCP2221_I2C_READ_COMPL || + data[2] == MCP2221_I2C_READ_PARTIAL) { ++ if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) { ++ mcp->status = -EINVAL; ++ break; ++ } + buf = mcp->rxbuf; + memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]); + mcp->rxbuf_idx = mcp->rxbuf_idx + data[3]; +diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c +index 0bd76f8d4dc6b8..6442d41622eff9 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -129,7 +129,7 @@ struct journal_sector { + commit_id_t commit_id; + }; + +-#define MAX_TAG_SIZE (JOURNAL_SECTOR_DATA - JOURNAL_MAC_PER_SECTOR - offsetof(struct journal_entry, last_bytes[MAX_SECTORS_PER_BLOCK])) ++#define MAX_TAG_SIZE 255 + + #define METADATA_PADDING_SECTORS 8 + +diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c +index 8a1a33862ba712..4b6ad85cf261de 100644 +--- a/drivers/media/i2c/tc358743.c ++++ b/drivers/media/i2c/tc358743.c +@@ -2180,10 +2180,10 @@ static int tc358743_probe(struct i2c_client *client) + err_work_queues: + cec_unregister_adapter(state->cec_adap); + if (!state->i2c_client->irq) { +- del_timer(&state->timer); ++ timer_delete_sync(&state->timer); + flush_work(&state->work_i2c_poll); + } +- cancel_delayed_work(&state->delayed_work_enable_hotplug); ++ cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); + mutex_destroy(&state->confctl_mutex); + err_hdl: + media_entity_cleanup(&sd->entity); +diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c +index 2182e5b7b6064c..ec9a3cd4784e1f 100644 +--- a/drivers/media/tuners/xc5000.c ++++ b/drivers/media/tuners/xc5000.c +@@ -58,7 +58,7 @@ struct xc5000_priv { + struct dvb_frontend *fe; + struct delayed_work timer_sleep; + +- const struct firmware *firmware; ++ bool inited; + }; + + /* Misc Defines */ +@@ -1110,23 +1110,19 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) + if (!force && xc5000_is_firmware_loaded(fe) == 0) + return 0; + +- if (!priv->firmware) { +- ret = request_firmware(&fw, desired_fw->name, +- priv->i2c_props.adap->dev.parent); +- if (ret) { +- pr_err("xc5000: Upload failed. rc %d\n", ret); +- return ret; +- } +- dprintk(1, "firmware read %zu bytes.\n", fw->size); ++ ret = request_firmware(&fw, desired_fw->name, ++ priv->i2c_props.adap->dev.parent); ++ if (ret) { ++ pr_err("xc5000: Upload failed. rc %d\n", ret); ++ return ret; ++ } ++ dprintk(1, "firmware read %zu bytes.\n", fw->size); + +- if (fw->size != desired_fw->size) { +- pr_err("xc5000: Firmware file with incorrect size\n"); +- release_firmware(fw); +- return -EINVAL; +- } +- priv->firmware = fw; +- } else +- fw = priv->firmware; ++ if (fw->size != desired_fw->size) { ++ pr_err("xc5000: Firmware file with incorrect size\n"); ++ release_firmware(fw); ++ return -EINVAL; ++ } + + /* Try up to 5 times to load firmware */ + for (i = 0; i < 5; i++) { +@@ -1204,6 +1200,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) + } + + err: ++ release_firmware(fw); + if (!ret) + printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n", + desired_fw->name); +@@ -1274,7 +1271,7 @@ static int xc5000_resume(struct dvb_frontend *fe) + + /* suspended before firmware is loaded. + Avoid firmware load in resume path. */ +- if (!priv->firmware) ++ if (!priv->inited) + return 0; + + return xc5000_set_params(fe); +@@ -1293,6 +1290,8 @@ static int xc5000_init(struct dvb_frontend *fe) + if (debug) + xc_debug_dump(priv); + ++ priv->inited = true; ++ + return 0; + } + +@@ -1305,11 +1304,7 @@ static void xc5000_release(struct dvb_frontend *fe) + mutex_lock(&xc5000_list_mutex); + + if (priv) { +- cancel_delayed_work(&priv->timer_sleep); +- if (priv->firmware) { +- release_firmware(priv->firmware); +- priv->firmware = NULL; +- } ++ cancel_delayed_work_sync(&priv->timer_sleep); + hybrid_tuner_release_state(priv); + } + +diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c +index e501b55678d1dc..ae4ebcee607792 100644 +--- a/drivers/net/can/rcar/rcar_canfd.c ++++ b/drivers/net/can/rcar/rcar_canfd.c +@@ -738,9 +738,6 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) + /* Reset Global error flags */ + rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0); + +- /* Set the controller into appropriate mode */ +- rcar_canfd_set_mode(gpriv); +- + /* Transition all Channels to reset mode */ + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + rcar_canfd_clear_bit(gpriv->base, +@@ -760,6 +757,10 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) + return err; + } + } ++ ++ /* Set the controller into appropriate mode */ ++ rcar_canfd_set_mode(gpriv); ++ + return 0; + } + +diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c +index 57ea7dfe8a596f..1acd4fc7adc8bf 100644 +--- a/drivers/net/can/spi/hi311x.c ++++ b/drivers/net/can/spi/hi311x.c +@@ -545,8 +545,6 @@ static int hi3110_stop(struct net_device *net) + + priv->force_quit = 1; + free_irq(spi->irq, priv); +- destroy_workqueue(priv->wq); +- priv->wq = NULL; + + mutex_lock(&priv->hi3110_lock); + +@@ -771,34 +769,23 @@ static int hi3110_open(struct net_device *net) + goto out_close; + } + +- priv->wq = alloc_workqueue("hi3110_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM, +- 0); +- if (!priv->wq) { +- ret = -ENOMEM; +- goto out_free_irq; +- } +- INIT_WORK(&priv->tx_work, hi3110_tx_work_handler); +- INIT_WORK(&priv->restart_work, hi3110_restart_work_handler); +- + ret = hi3110_hw_reset(spi); + if (ret) +- goto out_free_wq; ++ goto out_free_irq; + + ret = hi3110_setup(net); + if (ret) +- goto out_free_wq; ++ goto out_free_irq; + + ret = hi3110_set_normal_mode(spi); + if (ret) +- goto out_free_wq; ++ goto out_free_irq; + + netif_wake_queue(net); + mutex_unlock(&priv->hi3110_lock); + + return 0; + +- out_free_wq: +- destroy_workqueue(priv->wq); + out_free_irq: + free_irq(spi->irq, priv); + hi3110_hw_sleep(spi); +@@ -915,6 +902,15 @@ static int hi3110_can_probe(struct spi_device *spi) + if (ret) + goto out_clk; + ++ priv->wq = alloc_workqueue("hi3110_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM, ++ 0); ++ if (!priv->wq) { ++ ret = -ENOMEM; ++ goto out_clk; ++ } ++ INIT_WORK(&priv->tx_work, hi3110_tx_work_handler); ++ INIT_WORK(&priv->restart_work, hi3110_restart_work_handler); ++ + priv->spi = spi; + mutex_init(&priv->hi3110_lock); + +@@ -950,6 +946,8 @@ static int hi3110_can_probe(struct spi_device *spi) + return 0; + + error_probe: ++ destroy_workqueue(priv->wq); ++ priv->wq = NULL; + hi3110_power_enable(priv->power, 0); + + out_clk: +@@ -970,6 +968,9 @@ static void hi3110_can_remove(struct spi_device *spi) + + hi3110_power_enable(priv->power, 0); + ++ destroy_workqueue(priv->wq); ++ priv->wq = NULL; ++ + clk_disable_unprepare(priv->clk); + + free_candev(net); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +index e6403d4c937c8c..a0c0932a85d1e9 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +@@ -294,7 +294,6 @@ static const struct usb_device_id rtl8192c_usb_ids[] = { + {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ + {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ + {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ +- {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ + {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0846, 0x9043, rtl92cu_hal_cfg)}, /*NG WNA1000Mv2*/ +diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c +index 6f5437d210a617..9fd2829ee2ab48 100644 +--- a/drivers/platform/x86/amd/pmc/pmc-quirks.c ++++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c +@@ -233,6 +233,14 @@ static const struct dmi_system_id fwbug_list[] = { + DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"), + } + }, ++ { ++ .ident = "MECHREVO Yilong15Pro Series GM5HG7A", ++ .driver_data = &quirk_spurious_8042, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MECHREVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Yilong15Pro Series GM5HG7A"), ++ } ++ }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=220116 */ + { + .ident = "PCSpecialist Lafite Pro V 14M", +@@ -242,6 +250,13 @@ static const struct dmi_system_id fwbug_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Lafite Pro V 14M"), + } + }, ++ { ++ .ident = "TUXEDO Stellaris Slim 15 AMD Gen6", ++ .driver_data = &quirk_spurious_8042, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), ++ } ++ }, + { + .ident = "TUXEDO InfinityBook Pro 14/15 AMD Gen10", + .driver_data = &quirk_spurious_8042, +diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c +index f667b3b62f1883..4c38eeda53c4e7 100644 +--- a/drivers/staging/axis-fifo/axis-fifo.c ++++ b/drivers/staging/axis-fifo/axis-fifo.c +@@ -42,7 +42,6 @@ + #define DRIVER_NAME "axis_fifo" + + #define READ_BUF_SIZE 128U /* read buffer length in words */ +-#define WRITE_BUF_SIZE 128U /* write buffer length in words */ + + /* ---------------------------- + * IP register offsets +@@ -397,6 +396,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, + } + + bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET); ++ words_available = bytes_available / sizeof(u32); + if (!bytes_available) { + dev_err(fifo->dt_device, "received a packet of length 0\n"); + ret = -EIO; +@@ -407,7 +407,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, + dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n", + bytes_available, len); + ret = -EINVAL; +- goto end_unlock; ++ goto err_flush_rx; + } + + if (bytes_available % sizeof(u32)) { +@@ -416,11 +416,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, + */ + dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n"); + ret = -EIO; +- goto end_unlock; ++ goto err_flush_rx; + } + +- words_available = bytes_available / sizeof(u32); +- + /* read data into an intermediate buffer, copying the contents + * to userspace when the buffer is full + */ +@@ -432,18 +430,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, + tmp_buf[i] = ioread32(fifo->base_addr + + XLLF_RDFD_OFFSET); + } ++ words_available -= copy; + + if (copy_to_user(buf + copied * sizeof(u32), tmp_buf, + copy * sizeof(u32))) { + ret = -EFAULT; +- goto end_unlock; ++ goto err_flush_rx; + } + + copied += copy; +- words_available -= copy; + } ++ mutex_unlock(&fifo->read_lock); ++ ++ return bytes_available; + +- ret = bytes_available; ++err_flush_rx: ++ while (words_available--) ++ ioread32(fifo->base_addr + XLLF_RDFD_OFFSET); + + end_unlock: + mutex_unlock(&fifo->read_lock); +@@ -471,11 +474,8 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, + { + struct axis_fifo *fifo = (struct axis_fifo *)f->private_data; + unsigned int words_to_write; +- unsigned int copied; +- unsigned int copy; +- unsigned int i; ++ u32 *txbuf; + int ret; +- u32 tmp_buf[WRITE_BUF_SIZE]; + + if (len % sizeof(u32)) { + dev_err(fifo->dt_device, +@@ -491,11 +491,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, + return -EINVAL; + } + +- if (words_to_write > fifo->tx_fifo_depth) { +- dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n", +- words_to_write, fifo->tx_fifo_depth); ++ /* ++ * In 'Store-and-Forward' mode, the maximum packet that can be ++ * transmitted is limited by the size of the FIFO, which is ++ * (C_TX_FIFO_DEPTH–4)*(data interface width/8) bytes. ++ * ++ * Do not attempt to send a packet larger than 'tx_fifo_depth - 4', ++ * otherwise a 'Transmit Packet Overrun Error' interrupt will be ++ * raised, which requires a reset of the TX circuit to recover. ++ */ ++ if (words_to_write > (fifo->tx_fifo_depth - 4)) + return -EINVAL; +- } + + if (fifo->write_flags & O_NONBLOCK) { + /* +@@ -534,32 +540,20 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, + } + } + +- /* write data from an intermediate buffer into the fifo IP, refilling +- * the buffer with userspace data as needed +- */ +- copied = 0; +- while (words_to_write > 0) { +- copy = min(words_to_write, WRITE_BUF_SIZE); +- +- if (copy_from_user(tmp_buf, buf + copied * sizeof(u32), +- copy * sizeof(u32))) { +- ret = -EFAULT; +- goto end_unlock; +- } +- +- for (i = 0; i < copy; i++) +- iowrite32(tmp_buf[i], fifo->base_addr + +- XLLF_TDFD_OFFSET); +- +- copied += copy; +- words_to_write -= copy; ++ txbuf = vmemdup_user(buf, len); ++ if (IS_ERR(txbuf)) { ++ ret = PTR_ERR(txbuf); ++ goto end_unlock; + } + +- ret = copied * sizeof(u32); ++ for (int i = 0; i < words_to_write; ++i) ++ iowrite32(txbuf[i], fifo->base_addr + XLLF_TDFD_OFFSET); + + /* write packet size to fifo */ +- iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET); ++ iowrite32(len, fifo->base_addr + XLLF_TLR_OFFSET); + ++ ret = len; ++ kvfree(txbuf); + end_unlock: + mutex_unlock(&fifo->write_lock); + +diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig +index bdc568a4ab6693..4f57833e3ec742 100644 +--- a/drivers/tty/serial/Kconfig ++++ b/drivers/tty/serial/Kconfig +@@ -1405,7 +1405,7 @@ config SERIAL_STM32 + + config SERIAL_STM32_CONSOLE + bool "Support for console on STM32" +- depends on SERIAL_STM32=y ++ depends on SERIAL_STM32 + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index ef546f660b9927..dca610369ca94a 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2114,6 +2114,12 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */ + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */ + .driver_info = RSVD(7) }, ++ { USB_DEVICE(0x1e0e, 0x9071), /* Simcom SIM8230 RMNET mode */ ++ .driver_info = RSVD(3) | RSVD(4) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9078, 0xff), /* Simcom SIM8230 ECM mode */ ++ .driver_info = RSVD(5) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x907b, 0xff), /* Simcom SIM8230 RNDIS mode */ ++ .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9205, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT+ECM mode */ + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9206, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT-only mode */ + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), +diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c +index 28ac7995716e04..b8122582d75556 100644 +--- a/fs/btrfs/ref-verify.c ++++ b/fs/btrfs/ref-verify.c +@@ -990,11 +990,18 @@ int btrfs_build_ref_tree(struct btrfs_fs_info *fs_info) + if (!btrfs_test_opt(fs_info, REF_VERIFY)) + return 0; + ++ extent_root = btrfs_extent_root(fs_info, 0); ++ /* If the extent tree is damaged we cannot ignore it (IGNOREBADROOTS). */ ++ if (IS_ERR(extent_root)) { ++ btrfs_warn(fs_info, "ref-verify: extent tree not available, disabling"); ++ btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); ++ return 0; ++ } ++ + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + +- extent_root = btrfs_extent_root(fs_info, 0); + eb = btrfs_read_lock_root_node(extent_root); + level = btrfs_header_level(eb); + path->nodes[level] = eb; +diff --git a/include/linux/device.h b/include/linux/device.h +index 3627b26b243e61..e5f1a773dc5470 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -968,6 +968,9 @@ static inline bool device_pm_not_required(struct device *dev) + static inline void device_set_pm_not_required(struct device *dev) + { + dev->power.no_pm = true; ++#ifdef CONFIG_PM ++ dev->power.no_callbacks = true; ++#endif + } + + static inline void dev_pm_syscore_device(struct device *dev, bool val) +diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c +index d0eb03ada704dc..a1e3cb48621a90 100644 +--- a/net/9p/trans_fd.c ++++ b/net/9p/trans_fd.c +@@ -719,10 +719,10 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) + p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); + + spin_lock(&m->req_lock); +- /* Ignore cancelled request if message has been received +- * before lock. +- */ +- if (req->status == REQ_STATUS_RCVD) { ++ /* Ignore cancelled request if status changed since the request was ++ * processed in p9_client_flush() ++ */ ++ if (req->status != REQ_STATUS_SENT) { + spin_unlock(&m->req_lock); + return 0; + } +diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h +index d6cfae6ec5f74a..3f1761755b8660 100644 +--- a/sound/soc/amd/acp/amd.h ++++ b/sound/soc/amd/acp/amd.h +@@ -116,7 +116,7 @@ + #define PDM_DMA_INTR_MASK 0x10000 + #define PDM_DEC_64 0x2 + #define PDM_CLK_FREQ_MASK 0x07 +-#define PDM_MISC_CTRL_MASK 0x10 ++#define PDM_MISC_CTRL_MASK 0x18 + #define PDM_ENABLE 0x01 + #define PDM_DISABLE 0x00 + #define DMA_EN_MASK 0x02 +diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c +index 92c647d439ec7f..89de427c19e793 100644 +--- a/sound/soc/codecs/rt5682s.c ++++ b/sound/soc/codecs/rt5682s.c +@@ -653,14 +653,15 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode + switch (mode) { + case SAR_PWR_SAVING: + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3, +- RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_DIS); ++ RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_EN); + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, +- RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, +- RT5682S_CTRL_MB1_REG | RT5682S_CTRL_MB2_REG); ++ RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK | ++ RT5682S_VREF_POW_MASK, RT5682S_CTRL_MB1_FSM | ++ RT5682S_CTRL_MB2_FSM | RT5682S_VREF_POW_FSM); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | +- RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); ++ RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU); + usleep_range(5000, 5500); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK, RT5682S_SAR_BUTDET_EN); +@@ -688,7 +689,7 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | +- RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); ++ RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU); + break; + default: + dev_err(component->dev, "Invalid SAR Power mode: %d\n", mode); +@@ -725,7 +726,7 @@ static void rt5682s_disable_push_button_irq(struct snd_soc_component *component) + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | +- RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); ++ RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU); + } + + /** +@@ -786,7 +787,7 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ + jack_type = SND_JACK_HEADSET; + snd_soc_component_write(component, RT5682S_SAR_IL_CMD_3, 0x024c); + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, +- RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_EN); ++ RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_DIS); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT); + rt5682s_enable_push_button_irq(component); +@@ -966,7 +967,7 @@ static int rt5682s_set_jack_detect(struct snd_soc_component *component, + RT5682S_EMB_JD_MASK | RT5682S_DET_TYPE | + RT5682S_POL_FAST_OFF_MASK | RT5682S_MIC_CAP_MASK, + RT5682S_EMB_JD_EN | RT5682S_DET_TYPE | +- RT5682S_POL_FAST_OFF_HIGH | RT5682S_MIC_CAP_HS); ++ RT5682S_POL_FAST_OFF_LOW | RT5682S_MIC_CAP_HS); + regmap_update_bits(rt5682s->regmap, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_POW_MASK, RT5682S_SAR_POW_EN); + regmap_update_bits(rt5682s->regmap, RT5682S_GPIO_CTRL_1, +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index 3059f814eb5c2d..fdf69917d19cc8 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1522,12 +1522,12 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi) + { + int i; + ++ if (!umidi->disconnected) ++ snd_usbmidi_disconnect(&umidi->list); ++ + for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { + struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; +- if (ep->out) +- snd_usbmidi_out_endpoint_delete(ep->out); +- if (ep->in) +- snd_usbmidi_in_endpoint_delete(ep->in); ++ kfree(ep->out); + } + mutex_destroy(&umidi->mutex); + kfree(umidi); +@@ -1553,7 +1553,7 @@ void snd_usbmidi_disconnect(struct list_head *p) + spin_unlock_irq(&umidi->disc_lock); + up_write(&umidi->disc_rwsem); + +- del_timer_sync(&umidi->error_timer); ++ timer_shutdown_sync(&umidi->error_timer); + + for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { + struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; +diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c +index 9ef569492560ef..ddaeb4eb3e2497 100644 +--- a/tools/lib/subcmd/help.c ++++ b/tools/lib/subcmd/help.c +@@ -75,6 +75,9 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) + size_t ci, cj, ei; + int cmp; + ++ if (!excludes->cnt) ++ return; ++ + ci = cj = ei = 0; + while (ci < cmds->cnt && ei < excludes->cnt) { + cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name); diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.111-112.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.111-112.patch new file mode 100644 index 000000000..3197a64c4 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.111-112.patch @@ -0,0 +1,6153 @@ +diff --git a/Documentation/trace/histogram-design.rst b/Documentation/trace/histogram-design.rst +index 5765eb3e9efa78..a30f4bed11b4ee 100644 +--- a/Documentation/trace/histogram-design.rst ++++ b/Documentation/trace/histogram-design.rst +@@ -380,7 +380,9 @@ entry, ts0, corresponding to the ts0 variable in the sched_waking + trigger above. + + sched_waking histogram +-----------------------:: ++---------------------- ++ ++.. code-block:: + + +------------------+ + | hist_data |<-------------------------------------------------------+ +diff --git a/Makefile b/Makefile +index 9531c465e9c240..64d76baa0e0c9b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 111 ++SUBLEVEL = 112 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/boot/dts/renesas/r8a7791-porter.dts b/arch/arm/boot/dts/renesas/r8a7791-porter.dts +index fcc9a2313e1dfd..0cd08f7b8d8e06 100644 +--- a/arch/arm/boot/dts/renesas/r8a7791-porter.dts ++++ b/arch/arm/boot/dts/renesas/r8a7791-porter.dts +@@ -266,7 +266,7 @@ vin0_pins: vin0 { + }; + + can0_pins: can0 { +- groups = "can0_data"; ++ groups = "can0_data_b"; + function = "can0"; + }; + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi +index c14d5b70c72f6c..56f704082f94a5 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi ++++ b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi +@@ -270,7 +270,7 @@ &tps { + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + +- ti,en-ck32k-xtal = <1>; ++ ti,en-ck32k-xtal; + + regulators { + vrtc_reg: regulator@0 { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts b/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts +index 72990e7ffe10ee..44718a4cec474c 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts +@@ -483,8 +483,6 @@ &mcasp1 { + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; +- /* 16 serializers */ +- num-serializer = <16>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 + >; +diff --git a/arch/arm/boot/dts/ti/omap/omap3-devkit8000-lcd-common.dtsi b/arch/arm/boot/dts/ti/omap/omap3-devkit8000-lcd-common.dtsi +index a7f99ae0c1fe9a..78c657429f6410 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-devkit8000-lcd-common.dtsi ++++ b/arch/arm/boot/dts/ti/omap/omap3-devkit8000-lcd-common.dtsi +@@ -65,7 +65,7 @@ ads7846@0 { + ti,debounce-max = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <5>; + ti,debounce-rep = /bits/ 16 <1>; +- ti,keep-vref-on = <1>; ++ ti,keep-vref-on; + ti,settle-delay-usec = /bits/ 16 <150>; + + wakeup-source; +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index e5869cca5e7916..94dece1839af34 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -872,7 +872,7 @@ e_done: + /** + * at91_mckx_ps_restore: restore MCK1..4 settings + * +- * Side effects: overwrites tmp1, tmp2 ++ * Side effects: overwrites tmp1, tmp2 and tmp3 + */ + .macro at91_mckx_ps_restore + #ifdef CONFIG_SOC_SAMA7 +@@ -916,7 +916,7 @@ r_ps: + bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK + orr tmp3, tmp3, tmp1 + orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD +- str tmp2, [pmc, #AT91_PMC_MCR_V2] ++ str tmp3, [pmc, #AT91_PMC_MCR_V2] + + wait_mckrdy tmp1 + +diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts +index 152f95fd49a211..7089ccf3ce5566 100644 +--- a/arch/arm64/boot/dts/apple/t8103-j457.dts ++++ b/arch/arm64/boot/dts/apple/t8103-j457.dts +@@ -21,6 +21,14 @@ aliases { + }; + }; + ++/* ++ * Adjust pcie0's iommu-map to account for the disabled port01. ++ */ ++&pcie0 { ++ iommu-map = <0x100 &pcie0_dart_0 1 1>, ++ <0x200 &pcie0_dart_2 1 1>; ++}; ++ + &bluetooth0 { + brcm,board-type = "apple,santorini"; + }; +@@ -36,10 +44,10 @@ &wifi0 { + */ + + &port02 { +- bus-range = <3 3>; ++ bus-range = <2 2>; + status = "okay"; + ethernet0: ethernet@0,0 { +- reg = <0x30000 0x0 0x0 0x0 0x0>; ++ reg = <0x20000 0x0 0x0 0x0 0x0>; + /* To be filled by the loader */ + local-mac-address = [00 10 18 00 00 00]; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt6331.dtsi b/arch/arm64/boot/dts/mediatek/mt6331.dtsi +index d89858c73ab1b0..243afbffa21fd7 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6331.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt6331.dtsi +@@ -6,12 +6,12 @@ + #include + + &pwrap { +- pmic: mt6331 { ++ pmic: pmic { + compatible = "mediatek,mt6331"; + interrupt-controller; + #interrupt-cells = <2>; + +- mt6331regulator: mt6331regulator { ++ mt6331regulator: regulators { + compatible = "mediatek,mt6331-regulator"; + + mt6331_vdvfs11_reg: buck-vdvfs11 { +@@ -258,7 +258,7 @@ mt6331_vrtc_reg: ldo-vrtc { + }; + + mt6331_vdig18_reg: ldo-vdig18 { +- regulator-name = "dvdd18_dig"; ++ regulator-name = "vdig18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <0>; +@@ -266,11 +266,11 @@ mt6331_vdig18_reg: ldo-vdig18 { + }; + }; + +- mt6331rtc: mt6331rtc { ++ mt6331rtc: rtc { + compatible = "mediatek,mt6331-rtc"; + }; + +- mt6331keys: mt6331keys { ++ mt6331keys: keys { + compatible = "mediatek,mt6331-keys"; + power { + linux,keycodes = ; +diff --git a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts +index b5746e6d0b15a5..110fae4ec11c95 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts ++++ b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts +@@ -136,7 +136,7 @@ proximity@48 { + + &mmc0 { + /* eMMC controller */ +- mediatek,latch-ck = <0x14>; /* hs400 */ ++ mediatek,latch-ck = <4>; /* hs400 */ + mediatek,hs200-cmd-int-delay = <1>; + mediatek,hs400-cmd-int-delay = <1>; + mediatek,hs400-ds-dly3 = <0x1a>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 22604d3abde3bd..4b701afe995e2f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -1524,9 +1524,6 @@ pcie0: pcie@112f0000 { + + power-domains = <&spm MT8195_POWER_DOMAIN_PCIE_MAC_P0>; + +- resets = <&infracfg_ao MT8195_INFRA_RST2_PCIE_P0_SWRST>; +- reset-names = "mac"; +- + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, +diff --git a/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts +index cce642c5381280..3d3db33a64dc66 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts +@@ -11,7 +11,7 @@ + + / { + model = "Pumpkin MT8516"; +- compatible = "mediatek,mt8516"; ++ compatible = "mediatek,mt8516-pumpkin", "mediatek,mt8516"; + + memory@40000000 { + device_type = "memory"; +diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +index 40a8506553ef5d..4051a7660eb063 100644 +--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +@@ -1107,6 +1107,7 @@ usb_dwc3: usb@4e00000 { + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; ++ snps,parkmode-disable-ss-quirk; + maximum-speed = "super-speed"; + dr_mode = "otg"; + }; +diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi +index 83fce96a25752e..0234dbe95413cd 100644 +--- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi ++++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi +@@ -38,7 +38,10 @@ hdmi_con_out: endpoint { + #if (SW_SCIF_CAN || SW_RSPI_CAN) + &canfd { + pinctrl-0 = <&can1_pins>; +- /delete-node/ channel@0; ++ ++ channel0 { ++ status = "disabled"; ++ }; + }; + #else + &canfd { +diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c +index 0eddd4a66b8745..1432bb214e3f49 100644 +--- a/arch/loongarch/kernel/relocate.c ++++ b/arch/loongarch/kernel/relocate.c +@@ -124,6 +124,10 @@ static inline __init bool kaslr_disabled(void) + if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) + return true; + ++ str = strstr(boot_command_line, "kexec_file"); ++ if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) ++ return true; ++ + return false; + } + +diff --git a/arch/sparc/lib/M7memcpy.S b/arch/sparc/lib/M7memcpy.S +index cbd42ea7c3f7c2..99357bfa8e82ad 100644 +--- a/arch/sparc/lib/M7memcpy.S ++++ b/arch/sparc/lib/M7memcpy.S +@@ -696,16 +696,16 @@ FUNC_NAME: + EX_LD_FP(LOAD(ldd, %o4+40, %f26), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f24, %f26, %f10 + EX_ST_FP(STORE(std, %f6, %o0+24), memcpy_retl_o2_plus_o5_plus_40) +- EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_40) ++ EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_32) + faligndata %f26, %f28, %f12 +- EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_40) ++ EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_32) + add %o4, 64, %o4 +- EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_40) ++ EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_24) + faligndata %f28, %f30, %f14 +- EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_40) +- EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_40) ++ EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_24) ++ EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_16) + add %o0, 64, %o0 +- EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_40) ++ EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_8) + fsrc2 %f30, %f14 + bgu,pt %xcc, .Lunalign_sloop + prefetch [%o4 + (8 * BLOCK_SIZE)], 20 +@@ -728,7 +728,7 @@ FUNC_NAME: + add %o4, 8, %o4 + faligndata %f0, %f2, %f16 + subcc %o5, 8, %o5 +- EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5) ++ EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5_plus_8) + fsrc2 %f2, %f0 + bgu,pt %xcc, .Lunalign_by8 + add %o0, 8, %o0 +@@ -772,7 +772,7 @@ FUNC_NAME: + subcc %o5, 0x20, %o5 + EX_ST(STORE(stx, %o3, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) +- EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) ++ EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_16) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) + bne,pt %xcc, 1b + add %o0, 0x20, %o0 +@@ -804,12 +804,12 @@ FUNC_NAME: + brz,pt %o3, 2f + sub %o2, %o3, %o2 + +-1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) ++1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_o3) + add %o1, 1, %o1 + subcc %o3, 1, %o3 + add %o0, 1, %o0 + bne,pt %xcc, 1b +- EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) ++ EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_o3_plus_1) + 2: + and %o1, 0x7, %o3 + brz,pn %o3, .Lmedium_noprefetch_cp +diff --git a/arch/sparc/lib/Memcpy_utils.S b/arch/sparc/lib/Memcpy_utils.S +index 64fbac28b3db18..207343367bb2da 100644 +--- a/arch/sparc/lib/Memcpy_utils.S ++++ b/arch/sparc/lib/Memcpy_utils.S +@@ -137,6 +137,15 @@ ENTRY(memcpy_retl_o2_plus_63_8) + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 + ENDPROC(memcpy_retl_o2_plus_63_8) ++ENTRY(memcpy_retl_o2_plus_o3) ++ ba,pt %xcc, __restore_asi ++ add %o2, %o3, %o0 ++ENDPROC(memcpy_retl_o2_plus_o3) ++ENTRY(memcpy_retl_o2_plus_o3_plus_1) ++ add %o3, 1, %o3 ++ ba,pt %xcc, __restore_asi ++ add %o2, %o3, %o0 ++ENDPROC(memcpy_retl_o2_plus_o3_plus_1) + ENTRY(memcpy_retl_o2_plus_o5) + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S +index 7ad58ebe0d0096..df0ec1bd194892 100644 +--- a/arch/sparc/lib/NG4memcpy.S ++++ b/arch/sparc/lib/NG4memcpy.S +@@ -281,7 +281,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + subcc %o5, 0x20, %o5 + EX_ST(STORE(stx, %g1, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) +- EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) ++ EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_16) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) + bne,pt %icc, 1b + add %o0, 0x20, %o0 +diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S +index ee51c12306894e..bbd3ea0a64822c 100644 +--- a/arch/sparc/lib/NGmemcpy.S ++++ b/arch/sparc/lib/NGmemcpy.S +@@ -79,8 +79,8 @@ + #ifndef EX_RETVAL + #define EX_RETVAL(x) x + __restore_asi: +- ret + wr %g0, ASI_AIUS, %asi ++ ret + restore + ENTRY(NG_ret_i2_plus_i4_plus_1) + ba,pt %xcc, __restore_asi +@@ -125,15 +125,16 @@ ENTRY(NG_ret_i2_plus_g1_minus_56) + ba,pt %xcc, __restore_asi + add %i2, %g1, %i0 + ENDPROC(NG_ret_i2_plus_g1_minus_56) +-ENTRY(NG_ret_i2_plus_i4) ++ENTRY(NG_ret_i2_plus_i4_plus_16) ++ add %i4, 16, %i4 + ba,pt %xcc, __restore_asi + add %i2, %i4, %i0 +-ENDPROC(NG_ret_i2_plus_i4) +-ENTRY(NG_ret_i2_plus_i4_minus_8) +- sub %i4, 8, %i4 ++ENDPROC(NG_ret_i2_plus_i4_plus_16) ++ENTRY(NG_ret_i2_plus_i4_plus_8) ++ add %i4, 8, %i4 + ba,pt %xcc, __restore_asi + add %i2, %i4, %i0 +-ENDPROC(NG_ret_i2_plus_i4_minus_8) ++ENDPROC(NG_ret_i2_plus_i4_plus_8) + ENTRY(NG_ret_i2_plus_8) + ba,pt %xcc, __restore_asi + add %i2, 8, %i0 +@@ -160,6 +161,12 @@ ENTRY(NG_ret_i2_and_7_plus_i4) + ba,pt %xcc, __restore_asi + add %i2, %i4, %i0 + ENDPROC(NG_ret_i2_and_7_plus_i4) ++ENTRY(NG_ret_i2_and_7_plus_i4_plus_8) ++ and %i2, 7, %i2 ++ add %i4, 8, %i4 ++ ba,pt %xcc, __restore_asi ++ add %i2, %i4, %i0 ++ENDPROC(NG_ret_i2_and_7_plus_i4) + #endif + + .align 64 +@@ -405,13 +412,13 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ + andn %i2, 0xf, %i4 + and %i2, 0xf, %i2 + 1: subcc %i4, 0x10, %i4 +- EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4) ++ EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4_plus_16) + add %i1, 0x08, %i1 +- EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4) ++ EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4_plus_16) + sub %i1, 0x08, %i1 +- EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4) ++ EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4_plus_16) + add %i1, 0x8, %i1 +- EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8) ++ EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_plus_8) + bgu,pt %XCC, 1b + add %i1, 0x8, %i1 + 73: andcc %i2, 0x8, %g0 +@@ -468,7 +475,7 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ + subcc %i4, 0x8, %i4 + srlx %g3, %i3, %i5 + or %i5, %g2, %i5 +- EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4) ++ EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4_plus_8) + add %o0, 0x8, %o0 + bgu,pt %icc, 1b + sllx %g3, %g1, %g2 +diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S +index 635398ec7540ee..154fbd35400ca8 100644 +--- a/arch/sparc/lib/U1memcpy.S ++++ b/arch/sparc/lib/U1memcpy.S +@@ -164,17 +164,18 @@ ENTRY(U1_gs_40_fp) + retl + add %o0, %o2, %o0 + ENDPROC(U1_gs_40_fp) +-ENTRY(U1_g3_0_fp) +- VISExitHalf +- retl +- add %g3, %o2, %o0 +-ENDPROC(U1_g3_0_fp) + ENTRY(U1_g3_8_fp) + VISExitHalf + add %g3, 8, %g3 + retl + add %g3, %o2, %o0 + ENDPROC(U1_g3_8_fp) ++ENTRY(U1_g3_16_fp) ++ VISExitHalf ++ add %g3, 16, %g3 ++ retl ++ add %g3, %o2, %o0 ++ENDPROC(U1_g3_16_fp) + ENTRY(U1_o2_0_fp) + VISExitHalf + retl +@@ -547,18 +548,18 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + 62: FINISH_VISCHUNK(o0, f44, f46) + 63: UNEVEN_VISCHUNK_LAST(o0, f46, f0) + +-93: EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_0_fp) ++93: EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_8_fp) + add %o1, 8, %o1 + subcc %g3, 8, %g3 + faligndata %f0, %f2, %f8 +- EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp) ++ EX_ST_FP(STORE(std, %f8, %o0), U1_g3_16_fp) + bl,pn %xcc, 95f + add %o0, 8, %o0 +- EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_0_fp) ++ EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_8_fp) + add %o1, 8, %o1 + subcc %g3, 8, %g3 + faligndata %f2, %f0, %f8 +- EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp) ++ EX_ST_FP(STORE(std, %f8, %o0), U1_g3_16_fp) + bge,pt %xcc, 93b + add %o0, 8, %o0 + +diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S +index 9248d59c734ce2..bace3a18f836f1 100644 +--- a/arch/sparc/lib/U3memcpy.S ++++ b/arch/sparc/lib/U3memcpy.S +@@ -267,6 +267,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + faligndata %f10, %f12, %f26 + EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2) + ++ and %o2, 0x3f, %o2 + subcc GLOBAL_SPARE, 0x80, GLOBAL_SPARE + add %o1, 0x40, %o1 + bgu,pt %XCC, 1f +@@ -336,7 +337,6 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + * Also notice how this code is careful not to perform a + * load past the end of the src buffer. + */ +- and %o2, 0x3f, %o2 + andcc %o2, 0x38, %g2 + be,pn %XCC, 2f + subcc %g2, 0x8, %g2 +diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h +index 9d6411c6592050..00cefbb59fa98c 100644 +--- a/arch/x86/include/asm/segment.h ++++ b/arch/x86/include/asm/segment.h +@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node) + + static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) + { +- unsigned int p; ++ unsigned long p; + + /* + * Load CPU and node number from the GDT. LSL is faster than RDTSCP +@@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) + * + * If RDPID is available, use it. + */ +- alternative_io ("lsl %[seg],%[p]", +- ".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */ ++ alternative_io ("lsl %[seg],%k[p]", ++ "rdpid %[p]", + X86_FEATURE_RDPID, +- [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); ++ [p] "=r" (p), [seg] "r" (__CPUNODE_SEG)); + + if (cpu) + *cpu = (p & VDSO_CPUNODE_MASK); +diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c +index 156e9bb07abf1a..2fb234ab467b16 100644 +--- a/block/blk-mq-sysfs.c ++++ b/block/blk-mq-sysfs.c +@@ -150,9 +150,11 @@ static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx) + return; + + hctx_for_each_ctx(hctx, ctx, i) +- kobject_del(&ctx->kobj); ++ if (ctx->kobj.state_in_sysfs) ++ kobject_del(&ctx->kobj); + +- kobject_del(&hctx->kobj); ++ if (hctx->kobj.state_in_sysfs) ++ kobject_del(&hctx->kobj); + } + + static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) +diff --git a/block/blk-settings.c b/block/blk-settings.c +index 021994f6d2d829..a891f27ff834d0 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -553,7 +553,8 @@ static unsigned int blk_round_down_sectors(unsigned int sectors, unsigned int lb + int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, + sector_t start) + { +- unsigned int top, bottom, alignment, ret = 0; ++ unsigned int top, bottom, alignment; ++ int ret = 0; + + t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); + t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); +diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c +index 0a7049b470c181..5201f47e31d8b0 100644 +--- a/crypto/asymmetric_keys/x509_cert_parser.c ++++ b/crypto/asymmetric_keys/x509_cert_parser.c +@@ -618,11 +618,14 @@ int x509_process_extension(void *context, size_t hdrlen, + /* + * Get hold of the basicConstraints + * v[1] is the encoding size +- * (Expect 0x2 or greater, making it 1 or more bytes) ++ * (Expect 0x00 for empty SEQUENCE with CA:FALSE, or ++ * 0x03 or greater for non-empty SEQUENCE) + * v[2] is the encoding type + * (Expect an ASN1_BOOL for the CA) +- * v[3] is the contents of the ASN1_BOOL +- * (Expect 1 if the CA is TRUE) ++ * v[3] is the length of the ASN1_BOOL ++ * (Expect 1 for a single byte boolean) ++ * v[4] is the contents of the ASN1_BOOL ++ * (Expect 0xFF if the CA is TRUE) + * vlen should match the entire extension size + */ + if (v[0] != (ASN1_CONS_BIT | ASN1_SEQ)) +@@ -631,8 +634,13 @@ int x509_process_extension(void *context, size_t hdrlen, + return -EBADMSG; + if (v[1] != vlen - 2) + return -EBADMSG; +- if (vlen >= 4 && v[1] != 0 && v[2] == ASN1_BOOL && v[3] == 1) ++ /* Empty SEQUENCE means CA:FALSE (default value omitted per DER) */ ++ if (v[1] == 0) ++ return 0; ++ if (vlen >= 5 && v[2] == ASN1_BOOL && v[3] == 1 && v[4] == 0xFF) + ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_CA; ++ else ++ return -EBADMSG; + return 0; + } + +diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h +index 82563b44af3514..261dc8f87556df 100644 +--- a/drivers/acpi/acpica/aclocal.h ++++ b/drivers/acpi/acpica/aclocal.h +@@ -1139,7 +1139,7 @@ struct acpi_port_info { + #define ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION 0x91 + #define ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG 0x92 + #define ACPI_RESOURCE_NAME_CLOCK_INPUT 0x93 +-#define ACPI_RESOURCE_NAME_LARGE_MAX 0x94 ++#define ACPI_RESOURCE_NAME_LARGE_MAX 0x93 + + /***************************************************************************** + * +diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c +index a466ad6e5d93a9..5a1ced5bf7f6fa 100644 +--- a/drivers/acpi/nfit/core.c ++++ b/drivers/acpi/nfit/core.c +@@ -2643,7 +2643,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, + if (ndr_desc->target_node == NUMA_NO_NODE) { + ndr_desc->target_node = phys_to_target_node(spa->address); + dev_info(acpi_desc->dev, "changing target node from %d to %d for nfit region [%pa-%pa]", +- NUMA_NO_NODE, ndr_desc->numa_node, &res.start, &res.end); ++ NUMA_NO_NODE, ndr_desc->target_node, &res.start, &res.end); + } + + /* +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 0888e4d618d53a..b524cf27213d4f 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -1410,6 +1410,9 @@ int acpi_processor_power_init(struct acpi_processor *pr) + if (retval) { + if (acpi_processor_registered == 0) + cpuidle_unregister_driver(&acpi_idle_driver); ++ ++ per_cpu(acpi_cpuidle_device, pr->id) = NULL; ++ kfree(dev); + return retval; + } + acpi_processor_registered++; +diff --git a/drivers/base/node.c b/drivers/base/node.c +index 4d588f4658c85c..47960a34305d3f 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -878,6 +878,10 @@ int __register_one_node(int nid) + node_devices[nid] = node; + + error = register_node(node_devices[nid], nid); ++ if (error) { ++ node_devices[nid] = NULL; ++ return error; ++ } + + /* link cpu under this node */ + for_each_present_cpu(cpu) { +diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c +index baa31194cf20d5..ef5157fc8dcc51 100644 +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -600,8 +600,20 @@ static void __device_resume_noirq(struct device *dev, pm_message_t state, bool a + if (dev->power.syscore || dev->power.direct_complete) + goto Out; + +- if (!dev->power.is_noirq_suspended) ++ if (!dev->power.is_noirq_suspended) { ++ /* ++ * This means that system suspend has been aborted in the noirq ++ * phase before invoking the noirq suspend callback for the ++ * device, so if device_suspend_late() has left it in suspend, ++ * device_resume_early() should leave it in suspend either in ++ * case the early resume of it depends on the noirq resume that ++ * has not run. ++ */ ++ if (dev_pm_skip_suspend(dev)) ++ dev->power.must_resume = false; ++ + goto Out; ++ } + + if (!dpm_wait_for_superior(dev, async)) + goto Out; +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 1209e01f8c7f97..9603c28a3ed823 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -827,7 +827,7 @@ struct regmap *__regmap_init(struct device *dev, + map->read_flag_mask = bus->read_flag_mask; + } + +- if (config && config->read && config->write) { ++ if (config->read && config->write) { + map->reg_read = _regmap_bus_read; + if (config->reg_update_bits) + map->reg_update_bits = config->reg_update_bits; +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 3742ddf46c55ae..27a05b1521f693 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -1128,6 +1128,14 @@ static struct socket *nbd_get_socket(struct nbd_device *nbd, unsigned long fd, + if (!sock) + return NULL; + ++ if (!sk_is_tcp(sock->sk) && ++ !sk_is_stream_unix(sock->sk)) { ++ dev_err(disk_to_dev(nbd->disk), "Unsupported socket: should be TCP or UNIX.\n"); ++ *err = -EINVAL; ++ sockfd_put(sock); ++ return NULL; ++ } ++ + if (sock->ops->shutdown == sock_no_shutdown) { + dev_err(disk_to_dev(nbd->disk), "Unsupported socket: shutdown callout must be supported.\n"); + *err = -EINVAL; +diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c +index 97ed3bd9707f41..2dd254c720f5fa 100644 +--- a/drivers/block/null_blk/main.c ++++ b/drivers/block/null_blk/main.c +@@ -211,7 +211,7 @@ MODULE_PARM_DESC(discard, "Support discard operations (requires memory-backed nu + + static unsigned long g_cache_size; + module_param_named(cache_size, g_cache_size, ulong, 0444); +-MODULE_PARM_DESC(mbps, "Cache size in MiB for memory-backed device. Default: 0 (none)"); ++MODULE_PARM_DESC(cache_size, "Cache size in MiB for memory-backed device. Default: 0 (none)"); + + static unsigned int g_mbps; + module_param_named(mbps, g_mbps, uint, 0444); +diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c +index 350e7b24ee2b09..03642df2df0bbf 100644 +--- a/drivers/bus/fsl-mc/fsl-mc-bus.c ++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c +@@ -1103,6 +1103,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) + * Get physical address of MC portal for the root DPRC: + */ + plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!plat_res) ++ return -EINVAL; ++ + mc_portal_phys_addr = plat_res->start; + mc_portal_size = resource_size(plat_res); + mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff; +diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig +index 8de74dcfa18cf5..ece2d794174d40 100644 +--- a/drivers/char/hw_random/Kconfig ++++ b/drivers/char/hw_random/Kconfig +@@ -286,6 +286,7 @@ config HW_RANDOM_INGENIC_TRNG + config HW_RANDOM_NOMADIK + tristate "ST-Ericsson Nomadik Random Number Generator support" + depends on ARCH_NOMADIK || COMPILE_TEST ++ depends on ARM_AMBA + default HW_RANDOM + help + This driver provides kernel-side support for the Random Number +diff --git a/drivers/char/hw_random/ks-sa-rng.c b/drivers/char/hw_random/ks-sa-rng.c +index 2f2f21f1b659e0..d7b42888f25c28 100644 +--- a/drivers/char/hw_random/ks-sa-rng.c ++++ b/drivers/char/hw_random/ks-sa-rng.c +@@ -240,6 +240,10 @@ static int ks_sa_rng_probe(struct platform_device *pdev) + return -EINVAL; + } + ++ ks_sa_rng->clk = devm_clk_get_enabled(dev, NULL); ++ if (IS_ERR(ks_sa_rng->clk)) ++ return dev_err_probe(dev, PTR_ERR(ks_sa_rng->clk), "Failed to get clock\n"); ++ + pm_runtime_enable(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { +diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c +index 6ff77003a96eac..68325ebd56fe37 100644 +--- a/drivers/cpufreq/scmi-cpufreq.c ++++ b/drivers/cpufreq/scmi-cpufreq.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -330,6 +331,15 @@ static bool scmi_dev_used_by_cpus(struct device *scmi_dev) + return true; + } + ++ /* ++ * Older Broadcom STB chips had a "clocks" property for CPU node(s) ++ * that did not match the SCMI performance protocol node, if we got ++ * there, it means we had such an older Device Tree, therefore return ++ * true to preserve backwards compatibility. ++ */ ++ if (of_machine_is_compatible("brcm,brcmstb")) ++ return true; ++ + return false; + } + +diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c +index 1fc9968eae1996..b6b06a510fd866 100644 +--- a/drivers/cpuidle/cpuidle-qcom-spm.c ++++ b/drivers/cpuidle/cpuidle-qcom-spm.c +@@ -96,20 +96,23 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu) + return -ENODEV; + + saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); ++ of_node_put(cpu_node); + if (!saw_node) + return -ENODEV; + + pdev = of_find_device_by_node(saw_node); + of_node_put(saw_node); +- of_node_put(cpu_node); + if (!pdev) + return -ENODEV; + + data = devm_kzalloc(cpuidle_dev, sizeof(*data), GFP_KERNEL); +- if (!data) ++ if (!data) { ++ put_device(&pdev->dev); + return -ENOMEM; ++ } + + data->spm = dev_get_drvdata(&pdev->dev); ++ put_device(&pdev->dev); + if (!data->spm) + return -EINVAL; + +diff --git a/drivers/crypto/hisilicon/debugfs.c b/drivers/crypto/hisilicon/debugfs.c +index bd205f1f2279e4..573c0033a5afe3 100644 +--- a/drivers/crypto/hisilicon/debugfs.c ++++ b/drivers/crypto/hisilicon/debugfs.c +@@ -865,6 +865,7 @@ static int qm_diff_regs_init(struct hisi_qm *qm, + dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); + ret = PTR_ERR(qm->debug.acc_diff_regs); + qm->debug.acc_diff_regs = NULL; ++ qm->debug.qm_diff_regs = NULL; + return ret; + } + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index 762a2a54ca8219..e3d113334d4e48 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -689,6 +689,7 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) + + /* Config data buffer pasid needed by Kunpeng 920 */ + hpre_config_pasid(qm); ++ hpre_open_sva_prefetch(qm); + + hpre_enable_clock_gate(qm); + +@@ -1366,8 +1367,6 @@ static int hpre_pf_probe_init(struct hpre *hpre) + if (ret) + return ret; + +- hpre_open_sva_prefetch(qm); +- + hisi_qm_dev_err_init(qm); + ret = hpre_show_last_regs_init(qm); + if (ret) +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 7921409791fb03..203240e78f6adb 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3748,6 +3748,10 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, + } + + pdev = container_of(dev, struct pci_dev, dev); ++ if (pci_physfn(pdev) != qm->pdev) { ++ pci_err(qm->pdev, "the pdev input does not match the pf!\n"); ++ return -EINVAL; ++ } + + *fun_index = pdev->devfn; + +@@ -4363,9 +4367,6 @@ static void qm_restart_prepare(struct hisi_qm *qm) + { + u32 value; + +- if (qm->err_ini->open_sva_prefetch) +- qm->err_ini->open_sva_prefetch(qm); +- + if (qm->ver >= QM_HW_V3) + return; + +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index 6aaaaf784ddc03..064fbc8db16fc8 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -436,6 +436,45 @@ static void sec_set_endian(struct hisi_qm *qm) + writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG); + } + ++static void sec_close_sva_prefetch(struct hisi_qm *qm) ++{ ++ u32 val; ++ int ret; ++ ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) ++ return; ++ ++ val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); ++ val |= SEC_PREFETCH_DISABLE; ++ writel(val, qm->io_base + SEC_PREFETCH_CFG); ++ ++ ret = readl_relaxed_poll_timeout(qm->io_base + SEC_SVA_TRANS, ++ val, !(val & SEC_SVA_DISABLE_READY), ++ SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US); ++ if (ret) ++ pci_err(qm->pdev, "failed to close sva prefetch\n"); ++} ++ ++static void sec_open_sva_prefetch(struct hisi_qm *qm) ++{ ++ u32 val; ++ int ret; ++ ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) ++ return; ++ ++ /* Enable prefetch */ ++ val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); ++ val &= SEC_PREFETCH_ENABLE; ++ writel(val, qm->io_base + SEC_PREFETCH_CFG); ++ ++ ret = readl_relaxed_poll_timeout(qm->io_base + SEC_PREFETCH_CFG, ++ val, !(val & SEC_PREFETCH_DISABLE), ++ SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US); ++ if (ret) ++ pci_err(qm->pdev, "failed to open sva prefetch\n"); ++} ++ + static void sec_engine_sva_config(struct hisi_qm *qm) + { + u32 reg; +@@ -469,45 +508,7 @@ static void sec_engine_sva_config(struct hisi_qm *qm) + writel_relaxed(reg, qm->io_base + + SEC_INTERFACE_USER_CTRL1_REG); + } +-} +- +-static void sec_open_sva_prefetch(struct hisi_qm *qm) +-{ +- u32 val; +- int ret; +- +- if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) +- return; +- +- /* Enable prefetch */ +- val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); +- val &= SEC_PREFETCH_ENABLE; +- writel(val, qm->io_base + SEC_PREFETCH_CFG); +- +- ret = readl_relaxed_poll_timeout(qm->io_base + SEC_PREFETCH_CFG, +- val, !(val & SEC_PREFETCH_DISABLE), +- SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US); +- if (ret) +- pci_err(qm->pdev, "failed to open sva prefetch\n"); +-} +- +-static void sec_close_sva_prefetch(struct hisi_qm *qm) +-{ +- u32 val; +- int ret; +- +- if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) +- return; +- +- val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); +- val |= SEC_PREFETCH_DISABLE; +- writel(val, qm->io_base + SEC_PREFETCH_CFG); +- +- ret = readl_relaxed_poll_timeout(qm->io_base + SEC_SVA_TRANS, +- val, !(val & SEC_SVA_DISABLE_READY), +- SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US); +- if (ret) +- pci_err(qm->pdev, "failed to close sva prefetch\n"); ++ sec_open_sva_prefetch(qm); + } + + static void sec_enable_clock_gate(struct hisi_qm *qm) +@@ -1090,7 +1091,6 @@ static int sec_pf_probe_init(struct sec_dev *sec) + if (ret) + return ret; + +- sec_open_sva_prefetch(qm); + hisi_qm_dev_err_init(qm); + sec_debug_regs_clear(qm); + ret = sec_show_last_regs_init(qm); +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index 66e553115adfd5..b70aa6032874e1 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -469,10 +469,9 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) + return false; + } + +-static int hisi_zip_set_high_perf(struct hisi_qm *qm) ++static void hisi_zip_set_high_perf(struct hisi_qm *qm) + { + u32 val; +- int ret; + + val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET); + if (perf_mode == HZIP_HIGH_COMP_PERF) +@@ -482,13 +481,6 @@ static int hisi_zip_set_high_perf(struct hisi_qm *qm) + + /* Set perf mode */ + writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET); +- ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET, +- val, val == perf_mode, HZIP_DELAY_1_US, +- HZIP_POLL_TIMEOUT_US); +- if (ret) +- pci_err(qm->pdev, "failed to set perf mode\n"); +- +- return ret; + } + + static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) +@@ -585,6 +577,7 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) + writel(AXUSER_BASE, base + HZIP_DATA_WUSER_32_63); + writel(AXUSER_BASE, base + HZIP_SGL_RUSER_32_63); + } ++ hisi_zip_open_sva_prefetch(qm); + + /* let's open all compression/decompression cores */ + dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; +@@ -596,6 +589,7 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) + CQC_CACHE_WB_ENABLE | FIELD_PREP(SQC_CACHE_WB_THRD, 1) | + FIELD_PREP(CQC_CACHE_WB_THRD, 1), base + QM_CACHE_CTL); + ++ hisi_zip_set_high_perf(qm); + hisi_zip_enable_clock_gate(qm); + + return 0; +@@ -1180,11 +1174,6 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) + if (ret) + return ret; + +- ret = hisi_zip_set_high_perf(qm); +- if (ret) +- return ret; +- +- hisi_zip_open_sva_prefetch(qm); + hisi_qm_dev_err_init(qm); + hisi_zip_debug_regs_clear(qm); + +diff --git a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c +index b7322230353998..3b5d5b64e14142 100644 +--- a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c ++++ b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c +@@ -232,7 +232,7 @@ static int kmb_ocs_dma_prepare(struct ahash_request *req) + struct device *dev = rctx->hcu_dev->dev; + unsigned int remainder = 0; + unsigned int total; +- size_t nents; ++ int nents; + size_t count; + int rc; + int i; +@@ -253,6 +253,9 @@ static int kmb_ocs_dma_prepare(struct ahash_request *req) + /* Determine the number of scatter gather list entries to process. */ + nents = sg_nents_for_len(req->src, rctx->sg_data_total - remainder); + ++ if (nents < 0) ++ return nents; ++ + /* If there are entries to process, map them. */ + if (nents) { + rctx->sg_dma_nents = dma_map_sg(dev, req->src, nents, +diff --git a/drivers/devfreq/mtk-cci-devfreq.c b/drivers/devfreq/mtk-cci-devfreq.c +index 83a73f0ccd803b..eff9b2c06aef4d 100644 +--- a/drivers/devfreq/mtk-cci-devfreq.c ++++ b/drivers/devfreq/mtk-cci-devfreq.c +@@ -385,7 +385,8 @@ static int mtk_ccifreq_probe(struct platform_device *pdev) + out_free_resources: + if (regulator_is_enabled(drv->proc_reg)) + regulator_disable(drv->proc_reg); +- if (drv->sram_reg && regulator_is_enabled(drv->sram_reg)) ++ if (!IS_ERR_OR_NULL(drv->sram_reg) && ++ regulator_is_enabled(drv->sram_reg)) + regulator_disable(drv->sram_reg); + + return ret; +diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c +index 068597e8fce95a..3c70d860749757 100644 +--- a/drivers/edac/i10nm_base.c ++++ b/drivers/edac/i10nm_base.c +@@ -970,6 +970,15 @@ static bool i10nm_check_ecc(struct skx_imc *imc, int chan) + return !!GET_BITFIELD(mcmtr, 2, 2); + } + ++static bool i10nm_channel_disabled(struct skx_imc *imc, int chan) ++{ ++ u32 mcmtr = I10NM_GET_MCMTR(imc, chan); ++ ++ edac_dbg(1, "mc%d ch%d mcmtr reg %x\n", imc->mc, chan, mcmtr); ++ ++ return (mcmtr == ~0 || GET_BITFIELD(mcmtr, 18, 18)); ++} ++ + static int i10nm_get_dimm_config(struct mem_ctl_info *mci, + struct res_config *cfg) + { +@@ -983,6 +992,11 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci, + if (!imc->mbase) + continue; + ++ if (i10nm_channel_disabled(imc, i)) { ++ edac_dbg(1, "mc%d ch%d is disabled.\n", imc->mc, i); ++ continue; ++ } ++ + ndimms = 0; + amap = I10NM_GET_AMAP(imc, i); + +diff --git a/drivers/firmware/meson/Kconfig b/drivers/firmware/meson/Kconfig +index f2fdd375664822..179f5d46d8ddff 100644 +--- a/drivers/firmware/meson/Kconfig ++++ b/drivers/firmware/meson/Kconfig +@@ -5,7 +5,7 @@ + config MESON_SM + tristate "Amlogic Secure Monitor driver" + depends on ARCH_MESON || COMPILE_TEST +- default y ++ default ARCH_MESON + depends on ARM64_4K_PAGES + help + Say y here to enable the Amlogic secure monitor driver +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c +index 5534c769b65508..1e0189f90fd6ac 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c +@@ -625,7 +625,22 @@ static void uvd_v3_1_enable_mgcg(struct amdgpu_device *adev, + * + * @handle: handle used to pass amdgpu_device pointer + * +- * Initialize the hardware, boot up the VCPU and do some testing ++ * Initialize the hardware, boot up the VCPU and do some testing. ++ * ++ * On SI, the UVD is meant to be used in a specific power state, ++ * or alternatively the driver can manually enable its clock. ++ * In amdgpu we use the dedicated UVD power state when DPM is enabled. ++ * Calling amdgpu_dpm_enable_uvd makes DPM select the UVD power state ++ * for the SMU and afterwards enables the UVD clock. ++ * This is automatically done by amdgpu_uvd_ring_begin_use when work ++ * is submitted to the UVD ring. Here, we have to call it manually ++ * in order to power up UVD before firmware validation. ++ * ++ * Note that we must not disable the UVD clock here, as that would ++ * cause the ring test to fail. However, UVD is powered off ++ * automatically after the ring test: amdgpu_uvd_ring_end_use calls ++ * the UVD idle work handler which will disable the UVD clock when ++ * all fences are signalled. + */ + static int uvd_v3_1_hw_init(void *handle) + { +@@ -635,6 +650,15 @@ static int uvd_v3_1_hw_init(void *handle) + int r; + + uvd_v3_1_mc_resume(adev); ++ uvd_v3_1_enable_mgcg(adev, true); ++ ++ /* Make sure UVD is powered during FW validation. ++ * It's going to be automatically powered off after the ring test. ++ */ ++ if (adev->pm.dpm_enabled) ++ amdgpu_dpm_enable_uvd(adev, true); ++ else ++ amdgpu_asic_set_uvd_clocks(adev, 53300, 40000); + + r = uvd_v3_1_fw_validate(adev); + if (r) { +@@ -642,9 +666,6 @@ static int uvd_v3_1_hw_init(void *handle) + return r; + } + +- uvd_v3_1_enable_mgcg(adev, true); +- amdgpu_asic_set_uvd_clocks(adev, 53300, 40000); +- + uvd_v3_1_start(adev); + + r = amdgpu_ring_test_helper(ring); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index b77b4723323164..3168d6fb11e76b 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -4142,7 +4142,7 @@ svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start, + r = svm_range_get_attr(p, mm, start, size, nattrs, attrs); + break; + default: +- r = EINVAL; ++ r = -EINVAL; + break; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c +index 9ba6cb67655f4a..6c75aa82327ac1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c +@@ -139,7 +139,6 @@ void dml32_rq_dlg_get_rq_reg(display_rq_regs_st *rq_regs, + if (dual_plane) { + unsigned int p1_pte_row_height_linear = get_dpte_row_height_linear_c(mode_lib, e2e_pipe_param, + num_pipes, pipe_idx); +- ; + if (src->sw_mode == dm_sw_linear) + ASSERT(p1_pte_row_height_linear >= 8); + +diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c +index 42efe838fa85c5..2d2d2d5e676341 100644 +--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c ++++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c +@@ -66,6 +66,13 @@ u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) + (amdgpu_crtc->v_border * 2)); + + vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock; ++ ++ /* we have issues with mclk switching with ++ * refresh rates over 120 hz on the non-DC code. ++ */ ++ if (drm_mode_vrefresh(&amdgpu_crtc->hw_mode) > 120) ++ vblank_time_us = 0; ++ + break; + } + } +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +index e7b1fa2feb9288..2863dc65ffc6fb 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +@@ -3066,7 +3066,13 @@ static bool si_dpm_vblank_too_short(void *handle) + /* we never hit the non-gddr5 limit so disable it */ + u32 switch_limit = adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0; + +- if (vblank_time < switch_limit) ++ /* Consider zero vblank time too short and disable MCLK switching. ++ * Note that the vblank time is set to maximum when no displays are attached, ++ * so we'll still enable MCLK switching in that case. ++ */ ++ if (vblank_time == 0) ++ return true; ++ else if (vblank_time < switch_limit) + return true; + else + return false; +@@ -3424,12 +3430,14 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, + { + struct si_ps *ps = si_get_ps(rps); + struct amdgpu_clock_and_voltage_limits *max_limits; ++ struct amdgpu_connector *conn; + bool disable_mclk_switching = false; + bool disable_sclk_switching = false; + u32 mclk, sclk; + u16 vddc, vddci, min_vce_voltage = 0; + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; + u32 max_sclk = 0, max_mclk = 0; ++ u32 high_pixelclock_count = 0; + int i; + + if (adev->asic_type == CHIP_HAINAN) { +@@ -3457,6 +3465,35 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, + } + } + ++ /* We define "high pixelclock" for SI as higher than necessary for 4K 30Hz. ++ * For example, 4K 60Hz and 1080p 144Hz fall into this category. ++ * Find number of such displays connected. ++ */ ++ for (i = 0; i < adev->mode_info.num_crtc; i++) { ++ if (!(adev->pm.dpm.new_active_crtcs & (1 << i)) || ++ !adev->mode_info.crtcs[i]->enabled) ++ continue; ++ ++ conn = to_amdgpu_connector(adev->mode_info.crtcs[i]->connector); ++ ++ if (conn->pixelclock_for_modeset > 297000) ++ high_pixelclock_count++; ++ } ++ ++ /* These are some ad-hoc fixes to some issues observed with SI GPUs. ++ * They are necessary because we don't have something like dce_calcs ++ * for these GPUs to calculate bandwidth requirements. ++ */ ++ if (high_pixelclock_count) { ++ /* On Oland, we observe some flickering when two 4K 60Hz ++ * displays are connected, possibly because voltage is too low. ++ * Raise the voltage by requiring a higher SCLK. ++ * (Voltage cannot be adjusted independently without also SCLK.) ++ */ ++ if (high_pixelclock_count > 1 && adev->asic_type == CHIP_OLAND) ++ disable_sclk_switching = true; ++ } ++ + if (rps->vce_active) { + rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk; + rps->ecclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].ecclk; +@@ -5617,14 +5654,10 @@ static int si_populate_smc_t(struct amdgpu_device *adev, + + static int si_disable_ulv(struct amdgpu_device *adev) + { +- struct si_power_info *si_pi = si_get_pi(adev); +- struct si_ulv_param *ulv = &si_pi->ulv; +- +- if (ulv->supported) +- return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableULV) == PPSMC_Result_OK) ? +- 0 : -EINVAL; ++ PPSMC_Result r; + +- return 0; ++ r = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableULV); ++ return (r == PPSMC_Result_OK) ? 0 : -EINVAL; + } + + static bool si_is_state_ulv_compatible(struct amdgpu_device *adev, +@@ -5797,9 +5830,9 @@ static int si_upload_smc_data(struct amdgpu_device *adev) + { + struct amdgpu_crtc *amdgpu_crtc = NULL; + int i; +- +- if (adev->pm.dpm.new_active_crtc_count == 0) +- return 0; ++ u32 crtc_index = 0; ++ u32 mclk_change_block_cp_min = 0; ++ u32 mclk_change_block_cp_max = 0; + + for (i = 0; i < adev->mode_info.num_crtc; i++) { + if (adev->pm.dpm.new_active_crtcs & (1 << i)) { +@@ -5808,26 +5841,31 @@ static int si_upload_smc_data(struct amdgpu_device *adev) + } + } + +- if (amdgpu_crtc == NULL) +- return 0; ++ /* When a display is plugged in, program these so that the SMC ++ * performs MCLK switching when it doesn't cause flickering. ++ * When no display is plugged in, there is no need to restrict ++ * MCLK switching, so program them to zero. ++ */ ++ if (adev->pm.dpm.new_active_crtc_count && amdgpu_crtc) { ++ crtc_index = amdgpu_crtc->crtc_id; + +- if (amdgpu_crtc->line_time <= 0) +- return 0; ++ if (amdgpu_crtc->line_time) { ++ mclk_change_block_cp_min = 200 / amdgpu_crtc->line_time; ++ mclk_change_block_cp_max = 100 / amdgpu_crtc->line_time; ++ } ++ } + +- if (si_write_smc_soft_register(adev, +- SI_SMC_SOFT_REGISTER_crtc_index, +- amdgpu_crtc->crtc_id) != PPSMC_Result_OK) +- return 0; ++ si_write_smc_soft_register(adev, ++ SI_SMC_SOFT_REGISTER_crtc_index, ++ crtc_index); + +- if (si_write_smc_soft_register(adev, +- SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min, +- amdgpu_crtc->wm_high / amdgpu_crtc->line_time) != PPSMC_Result_OK) +- return 0; ++ si_write_smc_soft_register(adev, ++ SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min, ++ mclk_change_block_cp_min); + +- if (si_write_smc_soft_register(adev, +- SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max, +- amdgpu_crtc->wm_low / amdgpu_crtc->line_time) != PPSMC_Result_OK) +- return 0; ++ si_write_smc_soft_register(adev, ++ SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max, ++ mclk_change_block_cp_max); + + return 0; + } +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 3e6a4e2044c0eb..5a4d574b37b89f 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -85,6 +85,7 @@ config DRM_ITE_IT6505 + select EXTCON + select CRYPTO + select CRYPTO_HASH ++ select REGMAP_I2C + help + ITE IT6505 DisplayPort bridge chip driver. + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +index 0a45c546b03f2b..a5cd41c9224d75 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +@@ -433,7 +433,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout( + static int dpu_encoder_phys_wb_wait_for_commit_done( + struct dpu_encoder_phys *phys_enc) + { +- unsigned long ret; ++ int ret; + struct dpu_encoder_wait_info wait_info; + struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); + +diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35560.c b/drivers/gpu/drm/panel/panel-novatek-nt35560.c +index 5bbea734123bc0..ee04c55175bb85 100644 +--- a/drivers/gpu/drm/panel/panel-novatek-nt35560.c ++++ b/drivers/gpu/drm/panel/panel-novatek-nt35560.c +@@ -161,7 +161,7 @@ static int nt35560_set_brightness(struct backlight_device *bl) + par = 0x00; + ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, + &par, 1); +- if (ret) { ++ if (ret < 0) { + dev_err(nt->dev, "failed to disable display backlight (%d)\n", ret); + return ret; + } +diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c +index ac77d1246b9453..811265648a5828 100644 +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -1408,7 +1408,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, + unsigned block_align, unsigned height_align, unsigned base_align, + unsigned *l0_size, unsigned *mipmap_size) + { +- unsigned offset, i, level; ++ unsigned offset, i; + unsigned width, height, depth, size; + unsigned blocksize; + unsigned nbx, nby; +@@ -1420,7 +1420,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, + w0 = r600_mip_minify(w0, 0); + h0 = r600_mip_minify(h0, 0); + d0 = r600_mip_minify(d0, 0); +- for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { ++ for (i = 0, offset = 0; i < nlevels; i++) { + width = r600_mip_minify(w0, i); + nbx = r600_fmt_get_nblocksx(format, width); + +diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c +index c25a54d5b39ad5..0ba9195c9d713e 100644 +--- a/drivers/hwmon/mlxreg-fan.c ++++ b/drivers/hwmon/mlxreg-fan.c +@@ -113,8 +113,8 @@ struct mlxreg_fan { + int divider; + }; + +-static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, +- unsigned long state); ++static int _mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, ++ unsigned long state, bool thermal); + + static int + mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, +@@ -224,8 +224,9 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, + * last thermal state. + */ + if (pwm->last_hwmon_state >= pwm->last_thermal_state) +- return mlxreg_fan_set_cur_state(pwm->cdev, +- pwm->last_hwmon_state); ++ return _mlxreg_fan_set_cur_state(pwm->cdev, ++ pwm->last_hwmon_state, ++ false); + return 0; + } + return regmap_write(fan->regmap, pwm->reg, val); +@@ -357,9 +358,8 @@ static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev, + return 0; + } + +-static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, +- unsigned long state) +- ++static int _mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, ++ unsigned long state, bool thermal) + { + struct mlxreg_fan_pwm *pwm = cdev->devdata; + struct mlxreg_fan *fan = pwm->fan; +@@ -369,7 +369,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, + return -EINVAL; + + /* Save thermal state. */ +- pwm->last_thermal_state = state; ++ if (thermal) ++ pwm->last_thermal_state = state; + + state = max_t(unsigned long, state, pwm->last_hwmon_state); + err = regmap_write(fan->regmap, pwm->reg, +@@ -381,6 +382,13 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, + return 0; + } + ++static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, ++ unsigned long state) ++ ++{ ++ return _mlxreg_fan_set_cur_state(cdev, state, true); ++} ++ + static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = { + .get_max_state = mlxreg_fan_get_max_state, + .get_cur_state = mlxreg_fan_get_cur_state, +diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c +index 3b57851869eaae..a8369527372097 100644 +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -1638,8 +1638,9 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) + goto out_unlock; + } + +- if (csdev->type == CORESIGHT_DEV_TYPE_SINK || +- csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) { ++ if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || ++ csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && ++ sink_ops(csdev)->alloc_buffer) { + ret = etm_perf_add_symlink_sink(csdev); + + if (ret) { +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 05d9f87e35333c..e4d8d446ea4d32 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -481,7 +481,8 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, config->seq_rst, TRCSEQRSTEVR); + etm4x_relaxed_write32(csa, config->seq_state, TRCSEQSTR); + } +- etm4x_relaxed_write32(csa, config->ext_inp, TRCEXTINSELR); ++ if (drvdata->numextinsel) ++ etm4x_relaxed_write32(csa, config->ext_inp, TRCEXTINSELR); + for (i = 0; i < drvdata->nr_cntr; i++) { + etm4x_relaxed_write32(csa, config->cntrldvr[i], TRCCNTRLDVRn(i)); + etm4x_relaxed_write32(csa, config->cntr_ctrl[i], TRCCNTCTLRn(i)); +@@ -1323,6 +1324,7 @@ static void etm4_init_arch_data(void *info) + etmidr5 = etm4x_relaxed_read32(csa, TRCIDR5); + /* NUMEXTIN, bits[8:0] number of external inputs implemented */ + drvdata->nr_ext_inp = FIELD_GET(TRCIDR5_NUMEXTIN_MASK, etmidr5); ++ drvdata->numextinsel = FIELD_GET(TRCIDR5_NUMEXTINSEL_MASK, etmidr5); + /* TRACEIDSIZE, bits[21:16] indicates the trace ID width */ + drvdata->trcid_size = FIELD_GET(TRCIDR5_TRACEIDSIZE_MASK, etmidr5); + /* ATBTRIG, bit[22] implementation can support ATB triggers? */ +@@ -1750,7 +1752,9 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcseqrstevr = etm4x_read32(csa, TRCSEQRSTEVR); + state->trcseqstr = etm4x_read32(csa, TRCSEQSTR); + } +- state->trcextinselr = etm4x_read32(csa, TRCEXTINSELR); ++ ++ if (drvdata->numextinsel) ++ state->trcextinselr = etm4x_read32(csa, TRCEXTINSELR); + + for (i = 0; i < drvdata->nr_cntr; i++) { + state->trccntrldvr[i] = etm4x_read32(csa, TRCCNTRLDVRn(i)); +@@ -1882,7 +1886,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, state->trcseqrstevr, TRCSEQRSTEVR); + etm4x_relaxed_write32(csa, state->trcseqstr, TRCSEQSTR); + } +- etm4x_relaxed_write32(csa, state->trcextinselr, TRCEXTINSELR); ++ if (drvdata->numextinsel) ++ etm4x_relaxed_write32(csa, state->trcextinselr, TRCEXTINSELR); + + for (i = 0; i < drvdata->nr_cntr; i++) { + etm4x_relaxed_write32(csa, state->trccntrldvr[i], TRCCNTRLDVRn(i)); +@@ -2113,6 +2118,10 @@ static int etm4_probe(struct device *dev) + if (WARN_ON(!drvdata)) + return -ENOMEM; + ++ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); ++ if (IS_ERR(drvdata->atclk)) ++ return PTR_ERR(drvdata->atclk); ++ + if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE) + pm_save_enable = coresight_loses_context_with_cpu(dev) ? + PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER; +@@ -2364,8 +2373,8 @@ static int etm4_runtime_suspend(struct device *dev) + { + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); + +- if (drvdata->pclk && !IS_ERR(drvdata->pclk)) +- clk_disable_unprepare(drvdata->pclk); ++ clk_disable_unprepare(drvdata->atclk); ++ clk_disable_unprepare(drvdata->pclk); + + return 0; + } +@@ -2373,11 +2382,17 @@ static int etm4_runtime_suspend(struct device *dev) + static int etm4_runtime_resume(struct device *dev) + { + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); ++ int ret; + +- if (drvdata->pclk && !IS_ERR(drvdata->pclk)) +- clk_prepare_enable(drvdata->pclk); ++ ret = clk_prepare_enable(drvdata->pclk); ++ if (ret) ++ return ret; + +- return 0; ++ ret = clk_prepare_enable(drvdata->atclk); ++ if (ret) ++ clk_disable_unprepare(drvdata->pclk); ++ ++ return ret; + } + #endif + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h +index 6b6760e49ed357..d8b8102d790ccb 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x.h ++++ b/drivers/hwtracing/coresight/coresight-etm4x.h +@@ -162,6 +162,7 @@ + #define TRCIDR4_NUMVMIDC_MASK GENMASK(31, 28) + + #define TRCIDR5_NUMEXTIN_MASK GENMASK(8, 0) ++#define TRCIDR5_NUMEXTINSEL_MASK GENMASK(11, 9) + #define TRCIDR5_TRACEIDSIZE_MASK GENMASK(21, 16) + #define TRCIDR5_ATBTRIG BIT(22) + #define TRCIDR5_LPOVERRIDE BIT(23) +@@ -919,7 +920,8 @@ struct etmv4_save_state { + + /** + * struct etm4_drvdata - specifics associated to an ETM component +- * @pclk APB clock if present, otherwise NULL ++ * @pclk: APB clock if present, otherwise NULL ++ * @atclk: Optional clock for the core parts of the ETMv4. + * @base: Memory mapped base address for this component. + * @csdev: Component vitals needed by the framework. + * @spinlock: Only one at a time pls. +@@ -987,6 +989,7 @@ struct etmv4_save_state { + */ + struct etmv4_drvdata { + struct clk *pclk; ++ struct clk *atclk; + void __iomem *base; + struct coresight_device *csdev; + spinlock_t spinlock; +@@ -999,6 +1002,7 @@ struct etmv4_drvdata { + u8 nr_cntr; + u8 nr_ext_inp; + u8 numcidc; ++ u8 numextinsel; + u8 numvmidc; + u8 nrseqstate; + u8 nr_event; +diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c +index e20c1c6acc7315..a564bd5c8b62d3 100644 +--- a/drivers/hwtracing/coresight/coresight-trbe.c ++++ b/drivers/hwtracing/coresight/coresight-trbe.c +@@ -21,7 +21,8 @@ + #include "coresight-self-hosted-trace.h" + #include "coresight-trbe.h" + +-#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) ++#define PERF_IDX2OFF(idx, buf) \ ++ ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT)) + + /* + * A padding packet that will help the user space tools +@@ -743,12 +744,12 @@ static void *arm_trbe_alloc_buffer(struct coresight_device *csdev, + + buf = kzalloc_node(sizeof(*buf), GFP_KERNEL, trbe_alloc_node(event)); + if (!buf) +- return ERR_PTR(-ENOMEM); ++ return NULL; + + pglist = kcalloc(nr_pages, sizeof(*pglist), GFP_KERNEL); + if (!pglist) { + kfree(buf); +- return ERR_PTR(-ENOMEM); ++ return NULL; + } + + for (i = 0; i < nr_pages; i++) +@@ -758,7 +759,7 @@ static void *arm_trbe_alloc_buffer(struct coresight_device *csdev, + if (!buf->trbe_base) { + kfree(pglist); + kfree(buf); +- return ERR_PTR(-ENOMEM); ++ return NULL; + } + buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE; + buf->trbe_write = buf->trbe_base; +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index 1ebcf5673a06b2..e6fa6cb1011ab1 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -394,6 +394,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + + exit_probe: + dw_i2c_plat_pm_cleanup(dev); ++ i2c_dw_prepare_clk(dev, false); + exit_reset: + reset_control_assert(dev->rst); + return ret; +@@ -411,9 +412,11 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) + i2c_dw_disable(dev); + + pm_runtime_dont_use_autosuspend(device); +- pm_runtime_put_sync(device); ++ pm_runtime_put_noidle(device); + dw_i2c_plat_pm_cleanup(dev); + ++ i2c_dw_prepare_clk(dev, false); ++ + i2c_dw_remove_lock_support(dev); + + reset_control_assert(dev->rst); +diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c +index 1a9b5a068ef1b2..6b788bca64d54c 100644 +--- a/drivers/i2c/busses/i2c-mt65xx.c ++++ b/drivers/i2c/busses/i2c-mt65xx.c +@@ -1243,6 +1243,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, + { + int ret; + int left_num = num; ++ bool write_then_read_en = false; + struct mtk_i2c *i2c = i2c_get_adapdata(adap); + + ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); +@@ -1256,6 +1257,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, + if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) && + msgs[0].addr == msgs[1].addr) { + i2c->auto_restart = 0; ++ write_then_read_en = true; + } + } + +@@ -1280,12 +1282,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, + else + i2c->op = I2C_MASTER_WR; + +- if (!i2c->auto_restart) { +- if (num > 1) { +- /* combined two messages into one transaction */ +- i2c->op = I2C_MASTER_WRRD; +- left_num--; +- } ++ if (write_then_read_en) { ++ /* combined two messages into one transaction */ ++ i2c->op = I2C_MASTER_WRRD; ++ left_num--; + } + + /* always use DMA mode. */ +@@ -1293,7 +1293,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, + if (ret < 0) + goto err_exit; + +- msgs++; ++ if (i2c->op == I2C_MASTER_WRRD) ++ msgs += 2; ++ else ++ msgs++; + } + /* the return value is number of executed messages */ + ret = num; +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index d1630d47ef6fcf..277884b5e1ca4f 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -369,6 +369,7 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); ++ i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + +@@ -430,9 +431,24 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) + */ + writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS); + +- /* Acknowledge the incoming interrupt with the AUTOIBI mechanism */ +- writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI | +- SVC_I3C_MCTRL_IBIRESP_AUTO, ++ /* ++ * Write REQUEST_START_ADDR request to emit broadcast address for arbitration, ++ * instend of using AUTO_IBI. ++ * ++ * Using AutoIBI request may cause controller to remain in AutoIBI state when ++ * there is a glitch on SDA line (high->low->high). ++ * 1. SDA high->low, raising an interrupt to execute IBI isr. ++ * 2. SDA low->high. ++ * 3. IBI isr writes an AutoIBI request. ++ * 4. The controller will not start AutoIBI process because SDA is not low. ++ * 5. IBIWON polling times out. ++ * 6. Controller reamins in AutoIBI state and doesn't accept EmitStop request. ++ */ ++ writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | ++ SVC_I3C_MCTRL_TYPE_I3C | ++ SVC_I3C_MCTRL_IBIRESP_MANUAL | ++ SVC_I3C_MCTRL_DIR(SVC_I3C_MCTRL_DIR_WRITE) | ++ SVC_I3C_MCTRL_ADDR(I3C_BROADCAST_ADDR), + master->regs + SVC_I3C_MCTRL); + + /* Wait for IBIWON, should take approximately 100us */ +@@ -452,10 +468,15 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) + switch (ibitype) { + case SVC_I3C_MSTATUS_IBITYPE_IBI: + dev = svc_i3c_master_dev_from_addr(master, ibiaddr); +- if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI)) ++ if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI)) { + svc_i3c_master_nack_ibi(master); +- else ++ } else { ++ if (dev->info.bcr & I3C_BCR_IBI_PAYLOAD) ++ svc_i3c_master_ack_ibi(master, true); ++ else ++ svc_i3c_master_ack_ibi(master, false); + svc_i3c_master_handle_ibi(master, dev); ++ } + break; + case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN: + if (is_events_enabled(master, SVC_I3C_EVENT_HOTJOIN)) +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index 8255035ff124f3..c7b2ab78709936 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -635,7 +636,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, + { + int scale_type, scale_val, scale_val2; + int offset_type, offset_val, offset_val2; +- s64 raw64 = raw; ++ s64 denominator, raw64 = raw; + + offset_type = iio_channel_read(chan, &offset_val, &offset_val2, + IIO_CHAN_INFO_OFFSET); +@@ -670,7 +671,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, + * If no channel scaling is available apply consumer scale to + * raw value and return. + */ +- *processed = raw * scale; ++ *processed = raw64 * scale; + return 0; + } + +@@ -679,20 +680,19 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, + *processed = raw64 * scale_val * scale; + break; + case IIO_VAL_INT_PLUS_MICRO: +- if (scale_val2 < 0) +- *processed = -raw64 * scale_val * scale; +- else +- *processed = raw64 * scale_val * scale; +- *processed += div_s64(raw64 * (s64)scale_val2 * scale, +- 1000000LL); +- break; + case IIO_VAL_INT_PLUS_NANO: +- if (scale_val2 < 0) +- *processed = -raw64 * scale_val * scale; +- else +- *processed = raw64 * scale_val * scale; +- *processed += div_s64(raw64 * (s64)scale_val2 * scale, +- 1000000000LL); ++ switch (scale_type) { ++ case IIO_VAL_INT_PLUS_MICRO: ++ denominator = MICRO; ++ break; ++ case IIO_VAL_INT_PLUS_NANO: ++ denominator = NANO; ++ break; ++ } ++ *processed = raw64 * scale * abs(scale_val); ++ *processed += div_s64(raw64 * scale * abs(scale_val2), denominator); ++ if (scale_val < 0 || scale_val2 < 0) ++ *processed *= -1; + break; + case IIO_VAL_FRACTIONAL: + *processed = div_s64(raw64 * (s64)scale_val * scale, +diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c +index f20dfe70fa0e4f..8bf705921618c2 100644 +--- a/drivers/infiniband/core/addr.c ++++ b/drivers/infiniband/core/addr.c +@@ -460,14 +460,10 @@ static int addr_resolve_neigh(const struct dst_entry *dst, + { + int ret = 0; + +- if (ndev_flags & IFF_LOOPBACK) { ++ if (ndev_flags & IFF_LOOPBACK) + memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); +- } else { +- if (!(ndev_flags & IFF_NOARP)) { +- /* If the device doesn't do ARP internally */ +- ret = fetch_ha(dst, addr, dst_in, seq); +- } +- } ++ else ++ ret = fetch_ha(dst, addr, dst_in, seq); + return ret; + } + +diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c +index d45e3909dafe1d..50bb3c43f40bf6 100644 +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -1032,8 +1032,8 @@ static noinline void cm_destroy_id_wait_timeout(struct ib_cm_id *cm_id, + struct cm_id_private *cm_id_priv; + + cm_id_priv = container_of(cm_id, struct cm_id_private, id); +- pr_err("%s: cm_id=%p timed out. state %d -> %d, refcnt=%d\n", __func__, +- cm_id, old_state, cm_id->state, refcount_read(&cm_id_priv->refcount)); ++ pr_err_ratelimited("%s: cm_id=%p timed out. state %d -> %d, refcnt=%d\n", __func__, ++ cm_id, old_state, cm_id->state, refcount_read(&cm_id_priv->refcount)); + } + + static void cm_destroy_id(struct ib_cm_id *cm_id, int err) +diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c +index 8175dde60b0a84..9902bb96c74094 100644 +--- a/drivers/infiniband/core/sa_query.c ++++ b/drivers/infiniband/core/sa_query.c +@@ -1013,6 +1013,8 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, + if (timeout > IB_SA_LOCAL_SVC_TIMEOUT_MAX) + timeout = IB_SA_LOCAL_SVC_TIMEOUT_MAX; + ++ spin_lock_irqsave(&ib_nl_request_lock, flags); ++ + delta = timeout - sa_local_svc_timeout_ms; + if (delta < 0) + abs_delta = -delta; +@@ -1020,7 +1022,6 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, + abs_delta = delta; + + if (delta != 0) { +- spin_lock_irqsave(&ib_nl_request_lock, flags); + sa_local_svc_timeout_ms = timeout; + list_for_each_entry(query, &ib_nl_request_list, list) { + if (delta < 0 && abs_delta > query->timeout) +@@ -1038,9 +1039,10 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, + if (delay) + mod_delayed_work(ib_nl_wq, &ib_nl_timed_work, + (unsigned long)delay); +- spin_unlock_irqrestore(&ib_nl_request_lock, flags); + } + ++ spin_unlock_irqrestore(&ib_nl_request_lock, flags); ++ + settimeout_out: + return 0; + } +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index e922fb87286547..0adb98b8dacc87 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -1691,7 +1691,8 @@ static void deallocate_uars(struct mlx5_ib_dev *dev, + } + + static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master, +- struct mlx5_core_dev *slave) ++ struct mlx5_core_dev *slave, ++ struct mlx5_ib_lb_state *lb_state) + { + int err; + +@@ -1703,6 +1704,7 @@ static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master, + if (err) + goto out; + ++ lb_state->force_enable = true; + return 0; + + out: +@@ -1711,16 +1713,22 @@ static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master, + } + + static void mlx5_ib_disable_lb_mp(struct mlx5_core_dev *master, +- struct mlx5_core_dev *slave) ++ struct mlx5_core_dev *slave, ++ struct mlx5_ib_lb_state *lb_state) + { + mlx5_nic_vport_update_local_lb(slave, false); + mlx5_nic_vport_update_local_lb(master, false); ++ ++ lb_state->force_enable = false; + } + + int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp) + { + int err = 0; + ++ if (dev->lb.force_enable) ++ return 0; ++ + mutex_lock(&dev->lb.mutex); + if (td) + dev->lb.user_td++; +@@ -1742,6 +1750,9 @@ int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp) + + void mlx5_ib_disable_lb(struct mlx5_ib_dev *dev, bool td, bool qp) + { ++ if (dev->lb.force_enable) ++ return; ++ + mutex_lock(&dev->lb.mutex); + if (td) + dev->lb.user_td--; +@@ -3251,7 +3262,7 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev, + + lockdep_assert_held(&mlx5_ib_multiport_mutex); + +- mlx5_ib_disable_lb_mp(ibdev->mdev, mpi->mdev); ++ mlx5_ib_disable_lb_mp(ibdev->mdev, mpi->mdev, &ibdev->lb); + + mlx5_core_mp_event_replay(ibdev->mdev, + MLX5_DRIVER_EVENT_AFFILIATION_REMOVED, +@@ -3348,7 +3359,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, + MLX5_DRIVER_EVENT_AFFILIATION_DONE, + &key); + +- err = mlx5_ib_enable_lb_mp(ibdev->mdev, mpi->mdev); ++ err = mlx5_ib_enable_lb_mp(ibdev->mdev, mpi->mdev, &ibdev->lb); + if (err) + goto unbind; + +diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h +index 94678e5c59dd59..9b780f48a382b5 100644 +--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h ++++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h +@@ -1065,6 +1065,7 @@ struct mlx5_ib_lb_state { + u32 user_td; + int qps; + bool enabled; ++ bool force_enable; + }; + + struct mlx5_ib_pf_eq { +diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c +index 80332638d9e3ac..be6cd8ce4d97ec 100644 +--- a/drivers/infiniband/sw/rxe/rxe_task.c ++++ b/drivers/infiniband/sw/rxe/rxe_task.c +@@ -132,8 +132,12 @@ static void do_task(struct rxe_task *task) + * yield the cpu and reschedule the task + */ + if (!ret) { +- task->state = TASK_STATE_IDLE; +- resched = 1; ++ if (task->state != TASK_STATE_DRAINING) { ++ task->state = TASK_STATE_IDLE; ++ resched = 1; ++ } else { ++ cont = 1; ++ } + goto exit; + } + +diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c +index fdbef3254e3086..1768b8695c45ad 100644 +--- a/drivers/infiniband/sw/siw/siw_verbs.c ++++ b/drivers/infiniband/sw/siw/siw_verbs.c +@@ -761,7 +761,7 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, + struct siw_wqe *wqe = tx_wqe(qp); + + unsigned long flags; +- int rv = 0; ++ int rv = 0, imm_err = 0; + + if (wr && !rdma_is_kernel_res(&qp->base_qp.res)) { + siw_dbg_qp(qp, "wr must be empty for user mapped sq\n"); +@@ -947,9 +947,17 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, + * Send directly if SQ processing is not in progress. + * Eventual immediate errors (rv < 0) do not affect the involved + * RI resources (Verbs, 8.3.1) and thus do not prevent from SQ +- * processing, if new work is already pending. But rv must be passed +- * to caller. ++ * processing, if new work is already pending. But rv and pointer ++ * to failed work request must be passed to caller. + */ ++ if (unlikely(rv < 0)) { ++ /* ++ * Immediate error ++ */ ++ siw_dbg_qp(qp, "Immediate error %d\n", rv); ++ imm_err = rv; ++ *bad_wr = wr; ++ } + if (wqe->wr_status != SIW_WR_IDLE) { + spin_unlock_irqrestore(&qp->sq_lock, flags); + goto skip_direct_sending; +@@ -974,15 +982,10 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, + + up_read(&qp->state_lock); + +- if (rv >= 0) +- return 0; +- /* +- * Immediate error +- */ +- siw_dbg_qp(qp, "error %d\n", rv); ++ if (unlikely(imm_err)) ++ return imm_err; + +- *bad_wr = wr; +- return rv; ++ return (rv >= 0) ? 0 : rv; + } + + /* +diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c +index 2c973f15cab7da..edb62a284548b9 100644 +--- a/drivers/input/misc/uinput.c ++++ b/drivers/input/misc/uinput.c +@@ -775,6 +775,7 @@ static int uinput_ff_upload_to_user(char __user *buffer, + if (in_compat_syscall()) { + struct uinput_ff_upload_compat ff_up_compat; + ++ memset(&ff_up_compat, 0, sizeof(ff_up_compat)); + ff_up_compat.request_id = ff_up->request_id; + ff_up_compat.retval = ff_up->retval; + /* +diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c +index 20094b9899f093..176b1ab516853c 100644 +--- a/drivers/input/touchscreen/atmel_mxt_ts.c ++++ b/drivers/input/touchscreen/atmel_mxt_ts.c +@@ -3324,7 +3324,7 @@ static int mxt_probe(struct i2c_client *client) + if (data->reset_gpio) { + /* Wait a while and then de-assert the RESET GPIO line */ + msleep(MXT_RESET_GPIO_TIME); +- gpiod_set_value(data->reset_gpio, 0); ++ gpiod_set_value_cansleep(data->reset_gpio, 0); + msleep(MXT_RESET_INVALID_CHG); + } + +diff --git a/drivers/leds/flash/leds-qcom-flash.c b/drivers/leds/flash/leds-qcom-flash.c +index a619dbe0152434..07ca3e32d4becc 100644 +--- a/drivers/leds/flash/leds-qcom-flash.c ++++ b/drivers/leds/flash/leds-qcom-flash.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +@@ -114,36 +114,39 @@ enum { + REG_THERM_THRSH1, + REG_THERM_THRSH2, + REG_THERM_THRSH3, ++ REG_TORCH_CLAMP, + REG_MAX_COUNT, + }; + + static const struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = { +- REG_FIELD(0x08, 0, 7), /* status1 */ +- REG_FIELD(0x09, 0, 7), /* status2 */ +- REG_FIELD(0x0a, 0, 7), /* status3 */ +- REG_FIELD_ID(0x40, 0, 7, 3, 1), /* chan_timer */ +- REG_FIELD_ID(0x43, 0, 6, 3, 1), /* itarget */ +- REG_FIELD(0x46, 7, 7), /* module_en */ +- REG_FIELD(0x47, 0, 5), /* iresolution */ +- REG_FIELD_ID(0x49, 0, 2, 3, 1), /* chan_strobe */ +- REG_FIELD(0x4c, 0, 2), /* chan_en */ +- REG_FIELD(0x56, 0, 2), /* therm_thrsh1 */ +- REG_FIELD(0x57, 0, 2), /* therm_thrsh2 */ +- REG_FIELD(0x58, 0, 2), /* therm_thrsh3 */ ++ [REG_STATUS1] = REG_FIELD(0x08, 0, 7), ++ [REG_STATUS2] = REG_FIELD(0x09, 0, 7), ++ [REG_STATUS3] = REG_FIELD(0x0a, 0, 7), ++ [REG_CHAN_TIMER] = REG_FIELD_ID(0x40, 0, 7, 3, 1), ++ [REG_ITARGET] = REG_FIELD_ID(0x43, 0, 6, 3, 1), ++ [REG_MODULE_EN] = REG_FIELD(0x46, 7, 7), ++ [REG_IRESOLUTION] = REG_FIELD(0x47, 0, 5), ++ [REG_CHAN_STROBE] = REG_FIELD_ID(0x49, 0, 2, 3, 1), ++ [REG_CHAN_EN] = REG_FIELD(0x4c, 0, 2), ++ [REG_THERM_THRSH1] = REG_FIELD(0x56, 0, 2), ++ [REG_THERM_THRSH2] = REG_FIELD(0x57, 0, 2), ++ [REG_THERM_THRSH3] = REG_FIELD(0x58, 0, 2), ++ [REG_TORCH_CLAMP] = REG_FIELD(0xec, 0, 6), + }; + + static const struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = { +- REG_FIELD(0x06, 0, 7), /* status1 */ +- REG_FIELD(0x07, 0, 6), /* status2 */ +- REG_FIELD(0x09, 0, 7), /* status3 */ +- REG_FIELD_ID(0x3e, 0, 7, 4, 1), /* chan_timer */ +- REG_FIELD_ID(0x42, 0, 6, 4, 1), /* itarget */ +- REG_FIELD(0x46, 7, 7), /* module_en */ +- REG_FIELD(0x49, 0, 3), /* iresolution */ +- REG_FIELD_ID(0x4a, 0, 6, 4, 1), /* chan_strobe */ +- REG_FIELD(0x4e, 0, 3), /* chan_en */ +- REG_FIELD(0x7a, 0, 2), /* therm_thrsh1 */ +- REG_FIELD(0x78, 0, 2), /* therm_thrsh2 */ ++ [REG_STATUS1] = REG_FIELD(0x06, 0, 7), ++ [REG_STATUS2] = REG_FIELD(0x07, 0, 6), ++ [REG_STATUS3] = REG_FIELD(0x09, 0, 7), ++ [REG_CHAN_TIMER] = REG_FIELD_ID(0x3e, 0, 7, 4, 1), ++ [REG_ITARGET] = REG_FIELD_ID(0x42, 0, 6, 4, 1), ++ [REG_MODULE_EN] = REG_FIELD(0x46, 7, 7), ++ [REG_IRESOLUTION] = REG_FIELD(0x49, 0, 3), ++ [REG_CHAN_STROBE] = REG_FIELD_ID(0x4a, 0, 6, 4, 1), ++ [REG_CHAN_EN] = REG_FIELD(0x4e, 0, 3), ++ [REG_THERM_THRSH1] = REG_FIELD(0x7a, 0, 2), ++ [REG_THERM_THRSH2] = REG_FIELD(0x78, 0, 2), ++ [REG_TORCH_CLAMP] = REG_FIELD(0xed, 0, 6), + }; + + struct qcom_flash_data { +@@ -156,6 +159,7 @@ struct qcom_flash_data { + u8 max_channels; + u8 chan_en_bits; + u8 revision; ++ u8 torch_clamp; + }; + + struct qcom_flash_led { +@@ -702,6 +706,7 @@ static int qcom_flash_register_led_device(struct device *dev, + u32 current_ua, timeout_us; + u32 channels[4]; + int i, rc, count; ++ u8 torch_clamp; + + count = fwnode_property_count_u32(node, "led-sources"); + if (count <= 0) { +@@ -751,6 +756,12 @@ static int qcom_flash_register_led_device(struct device *dev, + current_ua = min_t(u32, current_ua, TORCH_CURRENT_MAX_UA * led->chan_count); + led->max_torch_current_ma = current_ua / UA_PER_MA; + ++ torch_clamp = (current_ua / led->chan_count) / TORCH_IRES_UA; ++ if (torch_clamp != 0) ++ torch_clamp--; ++ ++ flash_data->torch_clamp = max_t(u8, flash_data->torch_clamp, torch_clamp); ++ + if (fwnode_property_present(node, "flash-max-microamp")) { + flash->led_cdev.flags |= LED_DEV_CAP_FLASH; + +@@ -918,8 +929,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev) + flash_data->leds_count++; + } + +- return 0; +- ++ return regmap_field_write(flash_data->r_fields[REG_TORCH_CLAMP], flash_data->torch_clamp); + release: + fwnode_handle_put(child); + while (flash_data->v4l2_flash[flash_data->leds_count] && flash_data->leds_count) +diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h +index e6757a30dccad1..8a42c1590ecef7 100644 +--- a/drivers/md/dm-core.h ++++ b/drivers/md/dm-core.h +@@ -161,6 +161,7 @@ struct mapped_device { + #define DMF_SUSPENDED_INTERNALLY 7 + #define DMF_POST_SUSPENDING 8 + #define DMF_EMULATE_ZONE_APPEND 9 ++#define DMF_QUEUE_STOPPED 10 + + void disable_discard(struct mapped_device *md); + void disable_write_zeroes(struct mapped_device *md); +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 44424554e6b52a..f0c4c3553c0166 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2688,7 +2688,7 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, + { + bool do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG; + bool noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG; +- int r; ++ int r = 0; + + lockdep_assert_held(&md->suspend_lock); + +@@ -2740,8 +2740,10 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, + * Stop md->queue before flushing md->wq in case request-based + * dm defers requests to md->wq from md->queue. + */ +- if (dm_request_based(md)) ++ if (map && dm_request_based(md)) { + dm_stop_queue(md->queue); ++ set_bit(DMF_QUEUE_STOPPED, &md->flags); ++ } + + flush_workqueue(md->wq); + +@@ -2750,7 +2752,8 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, + * We call dm_wait_for_completion to wait for all existing requests + * to finish. + */ +- r = dm_wait_for_completion(md, task_state); ++ if (map) ++ r = dm_wait_for_completion(md, task_state); + if (!r) + set_bit(dmf_suspended_flag, &md->flags); + +@@ -2763,7 +2766,7 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, + if (r < 0) { + dm_queue_flush(md); + +- if (dm_request_based(md)) ++ if (test_and_clear_bit(DMF_QUEUE_STOPPED, &md->flags)) + dm_start_queue(md->queue); + + unlock_fs(md); +@@ -2847,7 +2850,7 @@ static int __dm_resume(struct mapped_device *md, struct dm_table *map) + * so that mapping of targets can work correctly. + * Request-based dm is queueing the deferred I/Os in its request_queue. + */ +- if (dm_request_based(md)) ++ if (test_and_clear_bit(DMF_QUEUE_STOPPED, &md->flags)) + dm_start_queue(md->queue); + + unlock_fs(md); +diff --git a/drivers/media/i2c/rj54n1cb0c.c b/drivers/media/i2c/rj54n1cb0c.c +index b430046f9e2a9f..09293e90025d55 100644 +--- a/drivers/media/i2c/rj54n1cb0c.c ++++ b/drivers/media/i2c/rj54n1cb0c.c +@@ -1331,10 +1331,13 @@ static int rj54n1_probe(struct i2c_client *client) + V4L2_CID_GAIN, 0, 127, 1, 66); + v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); +- rj54n1->subdev.ctrl_handler = &rj54n1->hdl; +- if (rj54n1->hdl.error) +- return rj54n1->hdl.error; + ++ if (rj54n1->hdl.error) { ++ ret = rj54n1->hdl.error; ++ goto err_free_ctrl; ++ } ++ ++ rj54n1->subdev.ctrl_handler = &rj54n1->hdl; + rj54n1->clk_div = clk_div; + rj54n1->rect.left = RJ54N1_COLUMN_SKIP; + rj54n1->rect.top = RJ54N1_ROW_SKIP; +diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h +index 56340553b28239..63592c4f9ed8c4 100644 +--- a/drivers/media/pci/zoran/zoran.h ++++ b/drivers/media/pci/zoran/zoran.h +@@ -154,12 +154,6 @@ struct zoran_jpg_settings { + + struct zoran; + +-/* zoran_fh contains per-open() settings */ +-struct zoran_fh { +- struct v4l2_fh fh; +- struct zoran *zr; +-}; +- + struct card_info { + enum card_type type; + char name[32]; +diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c +index fa672cc8bc678e..feb39854a989e6 100644 +--- a/drivers/media/pci/zoran/zoran_driver.c ++++ b/drivers/media/pci/zoran/zoran_driver.c +@@ -511,12 +511,11 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) + { + struct zoran *zr = video_drvdata(file); +- struct zoran_fh *fh = __fh; + int i; + int res = 0; + + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) +- return zoran_s_fmt_vid_out(file, fh, fmt); ++ return zoran_s_fmt_vid_out(file, __fh, fmt); + + for (i = 0; i < NUM_FORMATS; i++) + if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) +diff --git a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c +index 0533d4a083d249..a078f1107300ee 100644 +--- a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c ++++ b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c +@@ -239,7 +239,7 @@ static int delta_mjpeg_ipc_open(struct delta_ctx *pctx) + return 0; + } + +-static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au) ++static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, dma_addr_t pstart, dma_addr_t pend) + { + struct delta_dev *delta = pctx->dev; + struct delta_mjpeg_ctx *ctx = to_ctx(pctx); +@@ -256,8 +256,8 @@ static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au) + + memset(params, 0, sizeof(*params)); + +- params->picture_start_addr_p = (u32)(au->paddr); +- params->picture_end_addr_p = (u32)(au->paddr + au->size - 1); ++ params->picture_start_addr_p = pstart; ++ params->picture_end_addr_p = pend; + + /* + * !WARNING! +@@ -374,12 +374,14 @@ static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau) + struct delta_dev *delta = pctx->dev; + struct delta_mjpeg_ctx *ctx = to_ctx(pctx); + int ret; +- struct delta_au au = *pau; ++ void *au_vaddr = pau->vaddr; ++ dma_addr_t au_dma = pau->paddr; ++ size_t au_size = pau->size; + unsigned int data_offset = 0; + struct mjpeg_header *header = &ctx->header_struct; + + if (!ctx->header) { +- ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size, ++ ret = delta_mjpeg_read_header(pctx, au_vaddr, au_size, + header, &data_offset); + if (ret) { + pctx->stream_errors++; +@@ -405,17 +407,17 @@ static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau) + goto err; + } + +- ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size, ++ ret = delta_mjpeg_read_header(pctx, au_vaddr, au_size, + ctx->header, &data_offset); + if (ret) { + pctx->stream_errors++; + goto err; + } + +- au.paddr += data_offset; +- au.vaddr += data_offset; ++ au_dma += data_offset; ++ au_vaddr += data_offset; + +- ret = delta_mjpeg_ipc_decode(pctx, &au); ++ ret = delta_mjpeg_ipc_decode(pctx, au_dma, au_dma + au_size - 1); + if (ret) + goto err; + +diff --git a/drivers/mfd/rz-mtu3.c b/drivers/mfd/rz-mtu3.c +index f3dac4a29a8324..9cdfef610398f3 100644 +--- a/drivers/mfd/rz-mtu3.c ++++ b/drivers/mfd/rz-mtu3.c +@@ -32,7 +32,7 @@ static const unsigned long rz_mtu3_8bit_ch_reg_offs[][13] = { + [RZ_MTU3_CHAN_2] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202), + [RZ_MTU3_CHAN_3] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038), + [RZ_MTU3_CHAN_4] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039), +- [RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6), ++ [RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x895, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6), + [RZ_MTU3_CHAN_6] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838), + [RZ_MTU3_CHAN_7] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839), + [RZ_MTU3_CHAN_8] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403) +diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c +index eab82619ec314a..8e41942081138e 100644 +--- a/drivers/mfd/vexpress-sysreg.c ++++ b/drivers/mfd/vexpress-sysreg.c +@@ -90,6 +90,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) + struct resource *mem; + void __iomem *base; + struct gpio_chip *mmc_gpio_chip; ++ int ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) +@@ -110,7 +111,10 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) + bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI, + NULL, NULL, NULL, NULL, 0); + mmc_gpio_chip->ngpio = 2; +- devm_gpiochip_add_data(&pdev->dev, mmc_gpio_chip, NULL); ++ ++ ret = devm_gpiochip_add_data(&pdev->dev, mmc_gpio_chip, NULL); ++ if (ret) ++ return ret; + + return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, + vexpress_sysreg_cells, +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index fc021e265edc01..5e03a6ba55711a 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -362,26 +362,21 @@ static int fastrpc_map_get(struct fastrpc_map *map) + + + static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, +- struct fastrpc_map **ppmap, bool take_ref) ++ struct fastrpc_map **ppmap) + { +- struct fastrpc_session_ctx *sess = fl->sctx; + struct fastrpc_map *map = NULL; ++ struct dma_buf *buf; + int ret = -ENOENT; + ++ buf = dma_buf_get(fd); ++ if (IS_ERR(buf)) ++ return PTR_ERR(buf); ++ + spin_lock(&fl->lock); + list_for_each_entry(map, &fl->maps, node) { +- if (map->fd != fd) ++ if (map->fd != fd || map->buf != buf) + continue; + +- if (take_ref) { +- ret = fastrpc_map_get(map); +- if (ret) { +- dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n", +- __func__, fd, ret); +- break; +- } +- } +- + *ppmap = map; + ret = 0; + break; +@@ -751,7 +746,7 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = { + .release = fastrpc_release, + }; + +-static int fastrpc_map_create(struct fastrpc_user *fl, int fd, ++static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, + u64 len, u32 attr, struct fastrpc_map **ppmap) + { + struct fastrpc_session_ctx *sess = fl->sctx; +@@ -759,9 +754,6 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, + struct sg_table *table; + int err = 0; + +- if (!fastrpc_map_lookup(fl, fd, ppmap, true)) +- return 0; +- + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) + return -ENOMEM; +@@ -838,6 +830,24 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, + return err; + } + ++static int fastrpc_map_create(struct fastrpc_user *fl, int fd, ++ u64 len, u32 attr, struct fastrpc_map **ppmap) ++{ ++ struct fastrpc_session_ctx *sess = fl->sctx; ++ int err = 0; ++ ++ if (!fastrpc_map_lookup(fl, fd, ppmap)) { ++ if (!fastrpc_map_get(*ppmap)) ++ return 0; ++ dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n", ++ __func__, fd); ++ } ++ ++ err = fastrpc_map_attach(fl, fd, len, attr, ppmap); ++ ++ return err; ++} ++ + /* + * Fastrpc payload buffer with metadata looks like: + * +@@ -910,8 +920,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx) + ctx->args[i].length == 0) + continue; + +- err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, +- ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); ++ if (i < ctx->nbufs) ++ err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, ++ ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); ++ else ++ err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd, ++ ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); + if (err) { + dev_err(dev, "Error Creating map %d\n", err); + return -EINVAL; +@@ -1067,6 +1081,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, + struct fastrpc_phy_page *pages; + u64 *fdlist; + int i, inbufs, outbufs, handles; ++ int ret = 0; + + inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); + outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc); +@@ -1082,23 +1097,26 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, + u64 len = rpra[i].buf.len; + + if (!kernel) { +- if (copy_to_user((void __user *)dst, src, len)) +- return -EFAULT; ++ if (copy_to_user((void __user *)dst, src, len)) { ++ ret = -EFAULT; ++ goto cleanup_fdlist; ++ } + } else { + memcpy(dst, src, len); + } + } + } + ++cleanup_fdlist: + /* Clean up fdlist which is updated by DSP */ + for (i = 0; i < FASTRPC_MAX_FDLIST; i++) { + if (!fdlist[i]) + break; +- if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false)) ++ if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap)) + fastrpc_map_put(mmap); + } + +- return 0; ++ return ret; + } + + static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, +diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c +index 500b1feaf1f6f5..fd7d5cd50d3966 100644 +--- a/drivers/misc/genwqe/card_ddcb.c ++++ b/drivers/misc/genwqe/card_ddcb.c +@@ -923,7 +923,7 @@ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, + } + if (cmd->asv_length > DDCB_ASV_LENGTH) { + dev_err(&pci_dev->dev, "[%s] err: wrong asv_length of %d\n", +- __func__, cmd->asiv_length); ++ __func__, cmd->asv_length); + return -EINVAL; + } + rc = __genwqe_enqueue_ddcb(cd, req, f_flags); +diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c +index c5aff27ec4a895..14a09285f1551d 100644 +--- a/drivers/mtd/nand/raw/atmel/nand-controller.c ++++ b/drivers/mtd/nand/raw/atmel/nand-controller.c +@@ -1858,7 +1858,7 @@ atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller *nc) + + static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc) + { +- struct device_node *np, *nand_np; ++ struct device_node *np; + struct device *dev = nc->dev; + int ret, reg_cells; + u32 val; +@@ -1885,7 +1885,7 @@ static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc) + + reg_cells += val; + +- for_each_child_of_node(np, nand_np) { ++ for_each_child_of_node_scoped(np, nand_np) { + struct atmel_nand *nand; + + nand = atmel_nand_create(nc, nand_np, reg_cells); +diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +index d901877544445e..82a7c52fdb7210 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -752,7 +752,10 @@ static u32 ena_get_rxfh_indir_size(struct net_device *netdev) + + static u32 ena_get_rxfh_key_size(struct net_device *netdev) + { +- return ENA_HASH_KEY_SIZE; ++ struct ena_adapter *adapter = netdev_priv(netdev); ++ struct ena_rss *rss = &adapter->ena_dev->rss; ++ ++ return rss->hash_key ? ENA_HASH_KEY_SIZE : 0; + } + + static int ena_indirection_table_set(struct ena_adapter *adapter, +diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c +index f1208591ed67e3..1c3a5cf379cd03 100644 +--- a/drivers/net/ethernet/dlink/dl2k.c ++++ b/drivers/net/ethernet/dlink/dl2k.c +@@ -954,15 +954,18 @@ receive_packet (struct net_device *dev) + } else { + struct sk_buff *skb; + ++ skb = NULL; + /* Small skbuffs for short packets */ +- if (pkt_len > copy_thresh) { ++ if (pkt_len <= copy_thresh) ++ skb = netdev_alloc_skb_ip_align(dev, pkt_len); ++ if (!skb) { + dma_unmap_single(&np->pdev->dev, + desc_to_dma(desc), + np->rx_buf_sz, + DMA_FROM_DEVICE); + skb_put (skb = np->rx_skbuff[entry], pkt_len); + np->rx_skbuff[entry] = NULL; +- } else if ((skb = netdev_alloc_skb_ip_align(dev, pkt_len))) { ++ } else { + dma_sync_single_for_cpu(&np->pdev->dev, + desc_to_dma(desc), + np->rx_buf_sz, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +index 5a2126679415c7..336e0a54b3dc2e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -289,6 +289,10 @@ static void poll_timeout(struct mlx5_cmd_work_ent *ent) + return; + } + cond_resched(); ++ if (mlx5_cmd_is_down(dev)) { ++ ent->ret = -ENXIO; ++ return; ++ } + } while (time_before(jiffies, poll_end)); + + ent->ret = -ETIMEDOUT; +@@ -1059,7 +1063,7 @@ static void cmd_work_handler(struct work_struct *work) + poll_timeout(ent); + /* make sure we read the descriptor after ownership is SW */ + rmb(); +- mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, (ent->ret == -ETIMEDOUT)); ++ mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, !!ent->ret); + } + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h +index 66d276a1be836a..f4a19ffbb641c0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h +@@ -66,23 +66,11 @@ struct mlx5e_port_buffer { + struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER]; + }; + +-#ifdef CONFIG_MLX5_CORE_EN_DCB + int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, + u32 change, unsigned int mtu, + struct ieee_pfc *pfc, + u32 *buffer_size, + u8 *prio2buffer); +-#else +-static inline int +-mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, +- u32 change, unsigned int mtu, +- void *pfc, +- u32 *buffer_size, +- u8 *prio2buffer) +-{ +- return 0; +-} +-#endif + + int mlx5e_port_query_buffer(struct mlx5e_priv *priv, + struct mlx5e_port_buffer *port_buffer); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 09ba60b2e744b1..5c6f01abdcb91d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -44,7 +44,6 @@ + #include "eswitch.h" + #include "en.h" + #include "en/txrx.h" +-#include "en/port_buffer.h" + #include "en_tc.h" + #include "en_rep.h" + #include "en_accel/ipsec.h" +@@ -2723,11 +2722,9 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) + struct mlx5e_params *params = &priv->channels.params; + struct net_device *netdev = priv->netdev; + struct mlx5_core_dev *mdev = priv->mdev; +- u16 mtu, prev_mtu; ++ u16 mtu; + int err; + +- mlx5e_query_mtu(mdev, params, &prev_mtu); +- + err = mlx5e_set_mtu(mdev, params, params->sw_mtu); + if (err) + return err; +@@ -2737,18 +2734,6 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) + netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", + __func__, mtu, params->sw_mtu); + +- if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) { +- err = mlx5e_port_manual_buffer_config(priv, 0, mtu, +- NULL, NULL, NULL); +- if (err) { +- netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n", +- __func__, mtu, err, prev_mtu); +- +- mlx5e_set_mtu(mdev, params, prev_mtu); +- return err; +- } +- } +- + params->sw_mtu = mtu; + return 0; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +index 1547704c89767f..4d64d179b5dd7d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +@@ -27,6 +27,7 @@ struct mlx5_fw_reset { + struct work_struct reset_reload_work; + struct work_struct reset_now_work; + struct work_struct reset_abort_work; ++ struct delayed_work reset_timeout_work; + unsigned long reset_flags; + u8 reset_method; + struct timer_list timer; +@@ -257,6 +258,8 @@ static int mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, bool + return -EALREADY; + } + ++ if (current_work() != &fw_reset->reset_timeout_work.work) ++ cancel_delayed_work(&fw_reset->reset_timeout_work); + mlx5_stop_sync_reset_poll(dev); + if (poll_health) + mlx5_start_health_poll(dev); +@@ -327,6 +330,11 @@ static int mlx5_sync_reset_set_reset_requested(struct mlx5_core_dev *dev) + } + mlx5_stop_health_poll(dev, true); + mlx5_start_sync_reset_poll(dev); ++ ++ if (!test_bit(MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, ++ &fw_reset->reset_flags)) ++ schedule_delayed_work(&fw_reset->reset_timeout_work, ++ msecs_to_jiffies(mlx5_tout_ms(dev, PCI_SYNC_UPDATE))); + return 0; + } + +@@ -700,6 +708,19 @@ static void mlx5_sync_reset_events_handle(struct mlx5_fw_reset *fw_reset, struct + } + } + ++static void mlx5_sync_reset_timeout_work(struct work_struct *work) ++{ ++ struct delayed_work *dwork = container_of(work, struct delayed_work, ++ work); ++ struct mlx5_fw_reset *fw_reset = ++ container_of(dwork, struct mlx5_fw_reset, reset_timeout_work); ++ struct mlx5_core_dev *dev = fw_reset->dev; ++ ++ if (mlx5_sync_reset_clear_reset_requested(dev, true)) ++ return; ++ mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n"); ++} ++ + static int fw_reset_event_notifier(struct notifier_block *nb, unsigned long action, void *data) + { + struct mlx5_fw_reset *fw_reset = mlx5_nb_cof(nb, struct mlx5_fw_reset, nb); +@@ -783,6 +804,7 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev) + cancel_work_sync(&fw_reset->reset_reload_work); + cancel_work_sync(&fw_reset->reset_now_work); + cancel_work_sync(&fw_reset->reset_abort_work); ++ cancel_delayed_work(&fw_reset->reset_timeout_work); + } + + static const struct devlink_param mlx5_fw_reset_devlink_params[] = { +@@ -826,6 +848,8 @@ int mlx5_fw_reset_init(struct mlx5_core_dev *dev) + INIT_WORK(&fw_reset->reset_reload_work, mlx5_sync_reset_reload_work); + INIT_WORK(&fw_reset->reset_now_work, mlx5_sync_reset_now_event); + INIT_WORK(&fw_reset->reset_abort_work, mlx5_sync_reset_abort_event); ++ INIT_DELAYED_WORK(&fw_reset->reset_timeout_work, ++ mlx5_sync_reset_timeout_work); + + init_completion(&fw_reset->done); + return 0; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +index e0581c6f9cecd5..5df1472fe2be2f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +@@ -489,9 +489,12 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, + u32 func_id; + u32 npages; + u32 i = 0; ++ int err; + +- if (!mlx5_cmd_is_down(dev)) +- return mlx5_cmd_do(dev, in, in_size, out, out_size); ++ err = mlx5_cmd_do(dev, in, in_size, out, out_size); ++ /* If FW is gone (-ENXIO), proceed to forceful reclaim */ ++ if (err != -ENXIO) ++ return err; + + /* No hard feelings, we want our pages back! */ + npages = MLX5_GET(manage_pages_in, in, input_num_entries); +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +index e75cbb287625fc..87383f9d09ce30 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +@@ -1413,7 +1413,7 @@ static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev) + struct nfp_net *nn = netdev_priv(netdev); + + if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) +- return -EOPNOTSUPP; ++ return 0; + + return nfp_net_rss_key_sz(nn); + } +diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c +index f4340d4ef7eeab..0516ef71a64cb0 100644 +--- a/drivers/net/usb/asix_devices.c ++++ b/drivers/net/usb/asix_devices.c +@@ -625,6 +625,21 @@ static void ax88772_suspend(struct usbnet *dev) + asix_read_medium_status(dev, 1)); + } + ++/* Notes on PM callbacks and locking context: ++ * ++ * - asix_suspend()/asix_resume() are invoked for both runtime PM and ++ * system-wide suspend/resume. For struct usb_driver the ->resume() ++ * callback does not receive pm_message_t, so the resume type cannot ++ * be distinguished here. ++ * ++ * - The MAC driver must hold RTNL when calling phylink interfaces such as ++ * phylink_suspend()/resume(). Those calls will also perform MDIO I/O. ++ * ++ * - Taking RTNL and doing MDIO from a runtime-PM resume callback (while ++ * the USB PM lock is held) is fragile. Since autosuspend brings no ++ * measurable power saving here, we block it by holding a PM usage ++ * reference in ax88772_bind(). ++ */ + static int asix_suspend(struct usb_interface *intf, pm_message_t message) + { + struct usbnet *dev = usb_get_intfdata(intf); +@@ -919,6 +934,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) + if (ret) + goto initphy_err; + ++ /* Keep this interface runtime-PM active by taking a usage ref. ++ * Prevents runtime suspend while bound and avoids resume paths ++ * that could deadlock (autoresume under RTNL while USB PM lock ++ * is held, phylink/MDIO wants RTNL). ++ */ ++ pm_runtime_get_noresume(&intf->dev); ++ + return 0; + + initphy_err: +@@ -948,6 +970,8 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) + phylink_destroy(priv->phylink); + ax88772_mdio_unregister(priv); + asix_rx_fixup_common_free(dev->driver_priv); ++ /* Drop the PM usage ref taken in bind() */ ++ pm_runtime_put(&intf->dev); + } + + static void ax88178_unbind(struct usbnet *dev, struct usb_interface *intf) +@@ -1600,6 +1624,11 @@ static struct usb_driver asix_driver = { + .resume = asix_resume, + .reset_resume = asix_resume, + .disconnect = usbnet_disconnect, ++ /* usbnet enables autosuspend by default (supports_autosuspend=1). ++ * We keep runtime-PM active for AX88772* by taking a PM usage ++ * reference in ax88772_bind() (pm_runtime_get_noresume()) and ++ * dropping it in unbind(), which effectively blocks autosuspend. ++ */ + .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, + }; +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index ddff6f19ff98eb..92add3daadbb18 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -664,7 +664,6 @@ static void rtl8150_set_multicast(struct net_device *netdev) + rtl8150_t *dev = netdev_priv(netdev); + u16 rx_creg = 0x9e; + +- netif_stop_queue(netdev); + if (netdev->flags & IFF_PROMISC) { + rx_creg |= 0x0001; + dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); +@@ -678,7 +677,6 @@ static void rtl8150_set_multicast(struct net_device *netdev) + rx_creg &= 0x00fc; + } + async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg); +- netif_wake_queue(netdev); + } + + static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb, +diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c +index 818aea99f85eb3..340502c47a10d6 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -1763,33 +1763,32 @@ void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch, + + int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) + { ++ unsigned long timeout = jiffies + WMI_SERVICE_READY_TIMEOUT_HZ; + unsigned long time_left, i; + +- time_left = wait_for_completion_timeout(&ar->wmi.service_ready, +- WMI_SERVICE_READY_TIMEOUT_HZ); +- if (!time_left) { +- /* Sometimes the PCI HIF doesn't receive interrupt +- * for the service ready message even if the buffer +- * was completed. PCIe sniffer shows that it's +- * because the corresponding CE ring doesn't fires +- * it. Workaround here by polling CE rings once. +- */ +- ath10k_warn(ar, "failed to receive service ready completion, polling..\n"); +- ++ /* Sometimes the PCI HIF doesn't receive interrupt ++ * for the service ready message even if the buffer ++ * was completed. PCIe sniffer shows that it's ++ * because the corresponding CE ring doesn't fires ++ * it. Workaround here by polling CE rings. Since ++ * the message could arrive at any time, continue ++ * polling until timeout. ++ */ ++ do { + for (i = 0; i < CE_COUNT; i++) + ath10k_hif_send_complete_check(ar, i, 1); + ++ /* The 100 ms granularity is a tradeoff considering scheduler ++ * overhead and response latency ++ */ + time_left = wait_for_completion_timeout(&ar->wmi.service_ready, +- WMI_SERVICE_READY_TIMEOUT_HZ); +- if (!time_left) { +- ath10k_warn(ar, "polling timed out\n"); +- return -ETIMEDOUT; +- } +- +- ath10k_warn(ar, "service ready completion received, continuing normally\n"); +- } ++ msecs_to_jiffies(100)); ++ if (time_left) ++ return 0; ++ } while (time_before(jiffies, timeout)); + +- return 0; ++ ath10k_warn(ar, "failed to receive service ready completion\n"); ++ return -ETIMEDOUT; + } + + int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index 69eea0628e670e..df6e4a112ec48b 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -659,10 +659,9 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy, + return; + } + +- /* Don't send world or same regdom info to firmware */ +- if (strncmp(request->alpha2, "00", 2) && +- strncmp(request->alpha2, adapter->country_code, +- sizeof(request->alpha2))) { ++ /* Don't send same regdom info to firmware */ ++ if (strncmp(request->alpha2, adapter->country_code, ++ sizeof(request->alpha2)) != 0) { + memcpy(adapter->country_code, request->alpha2, + sizeof(request->alpha2)); + mwifiex_send_domain_info_cmd_fw(wiphy); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c +index ba927033bbe8c3..1206769cdc7fd9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c +@@ -48,7 +48,7 @@ mt76_wmac_probe(struct platform_device *pdev) + + return 0; + error: +- ieee80211_free_hw(mt76_hw(dev)); ++ mt76_free_device(mdev); + return ret; + } + +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +index 45165cf3e824e6..ae3e02efcc5d75 100644 +--- a/drivers/net/wireless/realtek/rtw89/ser.c ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -207,7 +207,6 @@ static void rtw89_ser_hdl_work(struct work_struct *work) + + static int ser_send_msg(struct rtw89_ser *ser, u8 event) + { +- struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + struct ser_msg *msg = NULL; + + if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) +@@ -223,7 +222,7 @@ static int ser_send_msg(struct rtw89_ser *ser, u8 event) + list_add(&msg->list, &ser->msg_q); + spin_unlock_irq(&ser->msg_q_lock); + +- ieee80211_queue_work(rtwdev->hw, &ser->ser_hdl_work); ++ schedule_work(&ser->ser_hdl_work); + return 0; + } + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 570c58d2b5a585..a15e764bae35b7 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -54,6 +54,8 @@ struct nvmet_fc_ls_req_op { /* for an LS RQST XMT */ + int ls_error; + struct list_head lsreq_list; /* tgtport->ls_req_list */ + bool req_queued; ++ ++ struct work_struct put_work; + }; + + +@@ -111,8 +113,6 @@ struct nvmet_fc_tgtport { + struct nvmet_fc_port_entry *pe; + struct kref ref; + u32 max_sg_cnt; +- +- struct work_struct put_work; + }; + + struct nvmet_fc_port_entry { +@@ -236,12 +236,13 @@ static int nvmet_fc_tgt_a_get(struct nvmet_fc_tgt_assoc *assoc); + static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); + static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); + static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); +-static void nvmet_fc_put_tgtport_work(struct work_struct *work) ++static void nvmet_fc_put_lsop_work(struct work_struct *work) + { +- struct nvmet_fc_tgtport *tgtport = +- container_of(work, struct nvmet_fc_tgtport, put_work); ++ struct nvmet_fc_ls_req_op *lsop = ++ container_of(work, struct nvmet_fc_ls_req_op, put_work); + +- nvmet_fc_tgtport_put(tgtport); ++ nvmet_fc_tgtport_put(lsop->tgtport); ++ kfree(lsop); + } + static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); + static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, +@@ -368,7 +369,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) + DMA_BIDIRECTIONAL); + + out_putwork: +- queue_work(nvmet_wq, &tgtport->put_work); ++ queue_work(nvmet_wq, &lsop->put_work); + } + + static int +@@ -389,6 +390,7 @@ __nvmet_fc_send_ls_req(struct nvmet_fc_tgtport *tgtport, + lsreq->done = done; + lsop->req_queued = false; + INIT_LIST_HEAD(&lsop->lsreq_list); ++ INIT_WORK(&lsop->put_work, nvmet_fc_put_lsop_work); + + lsreq->rqstdma = fc_dma_map_single(tgtport->dev, lsreq->rqstaddr, + lsreq->rqstlen + lsreq->rsplen, +@@ -448,8 +450,6 @@ nvmet_fc_disconnect_assoc_done(struct nvmefc_ls_req *lsreq, int status) + __nvmet_fc_finish_ls_req(lsop); + + /* fc-nvme target doesn't care about success or failure of cmd */ +- +- kfree(lsop); + } + + /* +@@ -1407,7 +1407,6 @@ nvmet_fc_register_targetport(struct nvmet_fc_port_info *pinfo, + kref_init(&newrec->ref); + ida_init(&newrec->assoc_cnt); + newrec->max_sg_cnt = template->max_sgl_segments; +- INIT_WORK(&newrec->put_work, nvmet_fc_put_tgtport_work); + + ret = nvmet_fc_alloc_ls_iodlist(newrec); + if (ret) { +diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c +index 416d6b45d1fe8d..115a21cf869ae6 100644 +--- a/drivers/pci/controller/dwc/pcie-tegra194.c ++++ b/drivers/pci/controller/dwc/pcie-tegra194.c +@@ -1734,9 +1734,9 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) + ret); + } + +- ret = tegra_pcie_bpmp_set_pll_state(pcie, false); ++ ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false); + if (ret) +- dev_err(pcie->dev, "Failed to turn off UPHY: %d\n", ret); ++ dev_err(pcie->dev, "Failed to disable controller: %d\n", ret); + + pcie->ep_state = EP_STATE_DISABLED; + dev_dbg(pcie->dev, "Uninitialization of endpoint is completed\n"); +diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c +index 038d974a318eaf..80d975dcb2ee27 100644 +--- a/drivers/pci/controller/pci-tegra.c ++++ b/drivers/pci/controller/pci-tegra.c +@@ -1343,7 +1343,7 @@ static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port) + unsigned int i; + int err; + +- port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL); ++ port->phys = devm_kcalloc(dev, port->lanes, sizeof(phy), GFP_KERNEL); + if (!port->phys) + return -ENOMEM; + +diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c +index 2bec2e3af0bd62..affa78376b6a80 100644 +--- a/drivers/perf/arm_spe_pmu.c ++++ b/drivers/perf/arm_spe_pmu.c +@@ -96,7 +96,8 @@ struct arm_spe_pmu { + #define to_spe_pmu(p) (container_of(p, struct arm_spe_pmu, pmu)) + + /* Convert a free-running index from perf into an SPE buffer offset */ +-#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) ++#define PERF_IDX2OFF(idx, buf) \ ++ ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT)) + + /* Keep track of our dynamic hotplug state */ + static enum cpuhp_state arm_spe_pmu_online; +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index 2354ce8b215943..9ef496092b7e6a 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -122,6 +122,8 @@ struct rockchip_combphy_grfcfg { + struct combphy_reg pipe_xpcs_phy_ready; + struct combphy_reg pipe_pcie1l0_sel; + struct combphy_reg pipe_pcie1l1_sel; ++ struct combphy_reg u3otg0_port_en; ++ struct combphy_reg u3otg1_port_en; + }; + + struct rockchip_combphy_cfg { +@@ -431,6 +433,14 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); ++ switch (priv->id) { ++ case 0: ++ rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true); ++ break; ++ case 1: ++ rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg1_port_en, true); ++ break; ++ } + break; + + case PHY_TYPE_SATA: +@@ -574,6 +584,8 @@ static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { + /* pipe-grf */ + .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, + .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, ++ .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, ++ .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, + }; + + static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 51408996255bd3..e2601e45935e6d 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -187,6 +187,9 @@ static const unsigned int i2c_sda_c_pins[] = { GPIODV_28 }; + static const unsigned int i2c_sck_c_dv19_pins[] = { GPIODV_19 }; + static const unsigned int i2c_sda_c_dv18_pins[] = { GPIODV_18 }; + ++static const unsigned int i2c_sck_d_pins[] = { GPIOX_11 }; ++static const unsigned int i2c_sda_d_pins[] = { GPIOX_10 }; ++ + static const unsigned int eth_mdio_pins[] = { GPIOZ_0 }; + static const unsigned int eth_mdc_pins[] = { GPIOZ_1 }; + static const unsigned int eth_clk_rx_clk_pins[] = { GPIOZ_2 }; +@@ -411,6 +414,8 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = { + GPIO_GROUP(GPIO_TEST_N), + + /* Bank X */ ++ GROUP(i2c_sda_d, 5, 5), ++ GROUP(i2c_sck_d, 5, 4), + GROUP(sdio_d0, 5, 31), + GROUP(sdio_d1, 5, 30), + GROUP(sdio_d2, 5, 29), +@@ -651,6 +656,10 @@ static const char * const i2c_c_groups[] = { + "i2c_sck_c", "i2c_sda_c", "i2c_sda_c_dv18", "i2c_sck_c_dv19", + }; + ++static const char * const i2c_d_groups[] = { ++ "i2c_sck_d", "i2c_sda_d", ++}; ++ + static const char * const eth_groups[] = { + "eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv", + "eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3", +@@ -777,6 +786,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = { + FUNCTION(i2c_a), + FUNCTION(i2c_b), + FUNCTION(i2c_c), ++ FUNCTION(i2c_d), + FUNCTION(eth), + FUNCTION(pwm_a), + FUNCTION(pwm_b), +diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c +index ab853d6c586b60..1c324d216ad773 100644 +--- a/drivers/pinctrl/pinmux.c ++++ b/drivers/pinctrl/pinmux.c +@@ -339,7 +339,7 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, + while (selector < nfuncs) { + const char *fname = ops->get_function_name(pctldev, selector); + +- if (!strcmp(function, fname)) ++ if (fname && !strcmp(function, fname)) + return selector; + + selector++; +diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c +index 4d9d58fc1356ff..852e179f9e3837 100644 +--- a/drivers/pinctrl/renesas/pinctrl.c ++++ b/drivers/pinctrl/renesas/pinctrl.c +@@ -730,7 +730,8 @@ static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + const unsigned int *pins; + unsigned int num_pins; +- unsigned int i, ret; ++ unsigned int i; ++ int ret; + + pins = pmx->pfc->info->groups[group].pins; + num_pins = pmx->pfc->info->groups[group].nr_pins; +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 99f3ccdc30a6a7..434e3233c9f8c6 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -702,8 +702,7 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, +- &cw_bat->battery_delay_work, cw_bat_work); ++ devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c +index 92d1b62ea239d7..e9389876229eaa 100644 +--- a/drivers/pps/kapi.c ++++ b/drivers/pps/kapi.c +@@ -109,16 +109,13 @@ struct pps_device *pps_register_source(struct pps_source_info *info, + if (err < 0) { + pr_err("%s: unable to create char device\n", + info->name); +- goto kfree_pps; ++ goto pps_register_source_exit; + } + + dev_dbg(&pps->dev, "new PPS source %s\n", info->name); + + return pps; + +-kfree_pps: +- kfree(pps); +- + pps_register_source_exit: + pr_err("%s: unable to register source\n", info->name); + +diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c +index e1689957736d95..9539695b337a81 100644 +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -375,6 +375,7 @@ int pps_register_cdev(struct pps_device *pps) + pps->info.name); + err = -EBUSY; + } ++ kfree(pps); + goto out_unlock; + } + pps->id = err; +@@ -384,13 +385,11 @@ int pps_register_cdev(struct pps_device *pps) + pps->dev.devt = MKDEV(pps_major, pps->id); + dev_set_drvdata(&pps->dev, pps); + dev_set_name(&pps->dev, "pps%d", pps->id); ++ pps->dev.release = pps_device_destruct; + err = device_register(&pps->dev); + if (err) + goto free_idr; + +- /* Override the release function with our own */ +- pps->dev.release = pps_device_destruct; +- + pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, + pps->id); + +diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c +index ecbfd7e954ecb8..d693b2d65cccf9 100644 +--- a/drivers/pwm/pwm-tiehrpwm.c ++++ b/drivers/pwm/pwm-tiehrpwm.c +@@ -167,7 +167,7 @@ static int set_prescale_div(unsigned long rqst_prescaler, u16 *prescale_div, + + *prescale_div = (1 << clkdiv) * + (hspclkdiv ? (hspclkdiv * 2) : 1); +- if (*prescale_div > rqst_prescaler) { ++ if (*prescale_div >= rqst_prescaler) { + *tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) | + (hspclkdiv << TBCTL_HSPCLKDIV_SHIFT); + return 0; +@@ -266,7 +266,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + pc->period_cycles[pwm->hwpwm] = period_cycles; + + /* Configure clock prescaler to support Low frequency PWM wave */ +- if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, ++ if (set_prescale_div(DIV_ROUND_UP(period_cycles, PERIOD_MAX), &ps_divval, + &tb_divval)) { + dev_err(chip->dev, "Unsupported values\n"); + return -EINVAL; +diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c +index 29ab217297d6dd..432654fbd7a126 100644 +--- a/drivers/regulator/scmi-regulator.c ++++ b/drivers/regulator/scmi-regulator.c +@@ -257,7 +257,8 @@ static int process_scmi_regulator_of_node(struct scmi_device *sdev, + struct device_node *np, + struct scmi_regulator_info *rinfo) + { +- u32 dom, ret; ++ u32 dom; ++ int ret; + + ret = of_property_read_u32(np, "reg", &dom); + if (ret) +diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c +index 327f0c7ee3d6ba..7ffbae209a31fb 100644 +--- a/drivers/remoteproc/pru_rproc.c ++++ b/drivers/remoteproc/pru_rproc.c +@@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(pru_rproc_put); + */ + int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) + { +- struct pru_rproc *pru = rproc->priv; ++ struct pru_rproc *pru; + unsigned int reg; + u32 mask, set; + u16 idx; +@@ -352,6 +352,7 @@ int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) + if (!rproc->dev.parent || !is_pru_rproc(rproc->dev.parent)) + return -ENODEV; + ++ pru = rproc->priv; + /* pointer is 16 bit and index is 8-bit so mask out the rest */ + idx_mask = (c >= PRU_C28) ? 0xFFFF : 0xFF; + +diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c +index 4ee5e67a9f03f5..769c6d6d6a7316 100644 +--- a/drivers/remoteproc/qcom_q6v5.c ++++ b/drivers/remoteproc/qcom_q6v5.c +@@ -156,9 +156,6 @@ int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout) + int ret; + + ret = wait_for_completion_timeout(&q6v5->start_done, timeout); +- if (!ret) +- disable_irq(q6v5->handover_irq); +- + return !ret ? -ETIMEDOUT : 0; + } + EXPORT_SYMBOL_GPL(qcom_q6v5_wait_for_start); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index e8a4750f6ec473..7d6e4fe31ceed8 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -991,11 +991,9 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + list_for_each_entry_safe(mpt3sas_phy, next_phy, + &mpt3sas_port->phy_list, port_siblings) { + if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) +- dev_printk(KERN_INFO, &mpt3sas_port->port->dev, +- "remove: sas_addr(0x%016llx), phy(%d)\n", +- (unsigned long long) +- mpt3sas_port->remote_identify.sas_address, +- mpt3sas_phy->phy_id); ++ ioc_info(ioc, "remove: sas_addr(0x%016llx), phy(%d)\n", ++ (unsigned long long) mpt3sas_port->remote_identify.sas_address, ++ mpt3sas_phy->phy_id); + mpt3sas_phy->phy_belongs_to_port = 0; + if (!ioc->remove_host) + sas_port_delete_phy(mpt3sas_port->port, +diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c +index e824be9d9bbb94..9075836ccc3e24 100644 +--- a/drivers/scsi/myrs.c ++++ b/drivers/scsi/myrs.c +@@ -498,14 +498,14 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, + /* Temporary dma mapping, used only in the scope of this function */ + mbox = dma_alloc_coherent(&pdev->dev, sizeof(union myrs_cmd_mbox), + &mbox_addr, GFP_KERNEL); +- if (dma_mapping_error(&pdev->dev, mbox_addr)) ++ if (!mbox) + return false; + + /* These are the base addresses for the command memory mailbox array */ + cs->cmd_mbox_size = MYRS_MAX_CMD_MBOX * sizeof(union myrs_cmd_mbox); + cmd_mbox = dma_alloc_coherent(&pdev->dev, cs->cmd_mbox_size, + &cs->cmd_mbox_addr, GFP_KERNEL); +- if (dma_mapping_error(&pdev->dev, cs->cmd_mbox_addr)) { ++ if (!cmd_mbox) { + dev_err(&pdev->dev, "Failed to map command mailbox\n"); + goto out_free; + } +@@ -520,7 +520,7 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, + cs->stat_mbox_size = MYRS_MAX_STAT_MBOX * sizeof(struct myrs_stat_mbox); + stat_mbox = dma_alloc_coherent(&pdev->dev, cs->stat_mbox_size, + &cs->stat_mbox_addr, GFP_KERNEL); +- if (dma_mapping_error(&pdev->dev, cs->stat_mbox_addr)) { ++ if (!stat_mbox) { + dev_err(&pdev->dev, "Failed to map status mailbox\n"); + goto out_free; + } +@@ -533,7 +533,7 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, + cs->fwstat_buf = dma_alloc_coherent(&pdev->dev, + sizeof(struct myrs_fwstat), + &cs->fwstat_addr, GFP_KERNEL); +- if (dma_mapping_error(&pdev->dev, cs->fwstat_addr)) { ++ if (!cs->fwstat_buf) { + dev_err(&pdev->dev, "Failed to map firmware health buffer\n"); + cs->fwstat_buf = NULL; + goto out_free; +diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c +index a9d6dac4133466..4daab8b6d67527 100644 +--- a/drivers/scsi/pm8001/pm8001_sas.c ++++ b/drivers/scsi/pm8001/pm8001_sas.c +@@ -703,6 +703,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) + unsigned long flags = 0; + struct pm8001_hba_info *pm8001_ha; + struct pm8001_device *pm8001_dev = dev->lldd_dev; ++ struct domain_device *parent_dev = dev->parent; + + pm8001_ha = pm8001_find_ha_by_dev(dev); + spin_lock_irqsave(&pm8001_ha->lock, flags); +@@ -719,7 +720,13 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) + spin_lock_irqsave(&pm8001_ha->lock, flags); + } + PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); +- pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; ++ ++ /* ++ * The phy array only contains local phys. Thus, we cannot clear ++ * phy_attached for a device behind an expander. ++ */ ++ if (!(parent_dev && dev_is_expander(parent_dev->dev_type))) ++ pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; + pm8001_free_dev(pm8001_dev); + } else { + pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n"); +diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c +index dcde55c8ee5dea..be20e2c457b8ea 100644 +--- a/drivers/scsi/qla2xxx/qla_edif.c ++++ b/drivers/scsi/qla2xxx/qla_edif.c +@@ -1797,7 +1797,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) + switch (rval) { + case QLA_SUCCESS: + break; +- case EAGAIN: ++ case -EAGAIN: + msleep(EDIF_MSLEEP_INTERVAL); + cnt++; + if (cnt < EDIF_RETRY_COUNT) +@@ -3648,7 +3648,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) + p->e.extra_rx_xchg_address, p->e.extra_control_flags, + sp->handle, sp->remap.req.len, bsg_job); + break; +- case EAGAIN: ++ case -EAGAIN: + msleep(EDIF_MSLEEP_INTERVAL); + cnt++; + if (cnt < EDIF_RETRY_COUNT) +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 5fa2727c1bea76..e881d704b45d1b 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -2059,11 +2059,11 @@ static void qla_marker_sp_done(srb_t *sp, int res) + int cnt = 5; \ + do { \ + if (_chip_gen != sp->vha->hw->chip_reset || _login_gen != sp->fcport->login_gen) {\ +- _rval = EINVAL; \ ++ _rval = -EINVAL; \ + break; \ + } \ + _rval = qla2x00_start_sp(_sp); \ +- if (_rval == EAGAIN) \ ++ if (_rval == -EAGAIN) \ + msleep(1); \ + else \ + break; \ +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 8f4cc136a9c9c4..080670cb2aa516 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -420,7 +420,7 @@ static int qla_nvme_xmt_ls_rsp(struct nvme_fc_local_port *lport, + switch (rval) { + case QLA_SUCCESS: + break; +- case EAGAIN: ++ case -EAGAIN: + msleep(PURLS_MSLEEP_INTERVAL); + cnt++; + if (cnt < PURLS_RETRY_COUNT) +diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c +index 163a58eb02e0a2..d0ec42ec0d0419 100644 +--- a/drivers/soc/qcom/rpmh-rsc.c ++++ b/drivers/soc/qcom/rpmh-rsc.c +@@ -453,13 +453,10 @@ static irqreturn_t tcs_tx_done(int irq, void *p) + + trace_rpmh_tx_done(drv, i, req); + +- /* +- * If wake tcs was re-purposed for sending active +- * votes, clear AMC trigger & enable modes and ++ /* Clear AMC trigger & enable modes and + * disable interrupt for this TCS + */ +- if (!drv->tcs[ACTIVE_TCS].num_tcs) +- __tcs_set_trigger(drv, i, false); ++ __tcs_set_trigger(drv, i, false); + skip: + /* Reclaim the TCS */ + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i, 0); +diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig +index 2c7f3f9a26ebbb..a6bb01082ec697 100644 +--- a/drivers/thermal/qcom/Kconfig ++++ b/drivers/thermal/qcom/Kconfig +@@ -34,7 +34,8 @@ config QCOM_SPMI_TEMP_ALARM + + config QCOM_LMH + tristate "Qualcomm Limits Management Hardware" +- depends on ARCH_QCOM && QCOM_SCM ++ depends on ARCH_QCOM || COMPILE_TEST ++ select QCOM_SCM + help + This enables initialization of Qualcomm limits management + hardware(LMh). LMh allows for hardware-enforced mitigation for cpus based on +diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c +index d2d49264cf83a4..7c299184c59b1c 100644 +--- a/drivers/thermal/qcom/lmh.c ++++ b/drivers/thermal/qcom/lmh.c +@@ -5,6 +5,8 @@ + */ + #include + #include ++#include ++#include + #include + #include + #include +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 8559ba1361c645..901f5c8311fbf9 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -460,6 +460,7 @@ static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg); + static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr); + static void gsmld_write_trigger(struct gsm_mux *gsm); + static void gsmld_write_task(struct work_struct *work); ++static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci); + + /** + * gsm_fcs_add - update FCS +@@ -2173,7 +2174,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) + pr_debug("DLCI %d goes open.\n", dlci->addr); + /* Send current modem state */ + if (dlci->addr) { +- gsm_modem_update(dlci, 0); ++ gsm_modem_send_initial_msc(dlci); + } else { + /* Start keep-alive control */ + gsm->ka_num = 0; +@@ -4156,6 +4157,28 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk) + return gsm_control_wait(dlci->gsm, ctrl); + } + ++/** ++ * gsm_modem_send_initial_msc - Send initial modem status message ++ * ++ * @dlci channel ++ * ++ * Send an initial MSC message after DLCI open to set the initial ++ * modem status lines. This is only done for basic mode. ++ * Does not wait for a response as we cannot block the input queue ++ * processing. ++ */ ++static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci) ++{ ++ u8 modembits[2]; ++ ++ if (dlci->adaption != 1 || dlci->gsm->encoding != GSM_BASIC_OPT) ++ return 0; ++ ++ modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */ ++ modembits[1] = (gsm_encode_modem(dlci) << 1) | EA; ++ return gsm_control_command(dlci->gsm, CMD_MSC, (const u8 *)&modembits, 2); ++} ++ + /** + * gsm_modem_update - send modem status line state + * @dlci: channel +diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c +index e339abff926d32..e10dcdeeda2d32 100644 +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -1659,6 +1659,8 @@ static int max310x_i2c_probe(struct i2c_client *client) + port_client = devm_i2c_new_dummy_device(&client->dev, + client->adapter, + port_addr); ++ if (IS_ERR(port_client)) ++ return PTR_ERR(port_client); + + regmaps[i] = devm_regmap_init_i2c(port_client, ®cfg_i2c); + } +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 17c1f85f2b7ba2..2724656bf63486 100644 +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -96,7 +96,6 @@ static void hv_uio_channel_cb(void *context) + struct hv_device *hv_dev = chan->device_obj; + struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev); + +- chan->inbound.ring_buffer->interrupt_mask = 1; + virt_mb(); + + uio_event_notify(&pdata->info); +@@ -173,8 +172,6 @@ hv_uio_new_channel(struct vmbus_channel *new_sc) + return; + } + +- /* Disable interrupts on sub channel */ +- new_sc->inbound.ring_buffer->interrupt_mask = 1; + set_channel_read_mode(new_sc, HV_CALL_ISR); + + ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr); +@@ -218,9 +215,7 @@ hv_uio_open(struct uio_info *info, struct inode *inode) + + ret = vmbus_connect_ring(dev->channel, + hv_uio_channel_cb, dev->channel); +- if (ret == 0) +- dev->channel->inbound.ring_buffer->interrupt_mask = 1; +- else ++ if (ret) + atomic_dec(&pdata->refcnt); + + return ret; +diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c +index 159c2eae26608c..b9c74c1baccb28 100644 +--- a/drivers/usb/cdns3/cdnsp-pci.c ++++ b/drivers/usb/cdns3/cdnsp-pci.c +@@ -90,7 +90,7 @@ static int cdnsp_pci_probe(struct pci_dev *pdev, + cdnsp = kzalloc(sizeof(*cdnsp), GFP_KERNEL); + if (!cdnsp) { + ret = -ENOMEM; +- goto disable_pci; ++ goto put_pci; + } + } + +@@ -173,9 +173,6 @@ static int cdnsp_pci_probe(struct pci_dev *pdev, + if (!pci_is_enabled(func)) + kfree(cdnsp); + +-disable_pci: +- pci_disable_device(pdev); +- + put_pci: + pci_dev_put(func); + +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 4c89f7629d5308..9e8af571448bfc 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -1747,6 +1747,8 @@ static int configfs_composite_bind(struct usb_gadget *gadget, + cdev->use_os_string = true; + cdev->b_vendor_code = gi->b_vendor_code; + memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN); ++ } else { ++ cdev->use_os_string = false; + } + + if (gadget_is_otg(gadget) && !otg_desc[0]) { +diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c +index cc1f579f02de1c..2d792ab271e2ae 100644 +--- a/drivers/usb/host/max3421-hcd.c ++++ b/drivers/usb/host/max3421-hcd.c +@@ -1916,7 +1916,7 @@ max3421_probe(struct spi_device *spi) + if (hcd) { + kfree(max3421_hcd->tx); + kfree(max3421_hcd->rx); +- if (max3421_hcd->spi_thread) ++ if (!IS_ERR_OR_NULL(max3421_hcd->spi_thread)) + kthread_stop(max3421_hcd->spi_thread); + usb_put_hcd(hcd); + } +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index a21ac9d80275f7..6443e11eaac045 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1224,19 +1224,16 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + * Stopped state, but it will soon change to Running. + * + * Assume this bug on unexpected Stop Endpoint failures. +- * Keep retrying until the EP starts and stops again. ++ * Keep retrying until the EP starts and stops again, on ++ * chips where this is known to help. Wait for 100ms. + */ ++ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) ++ break; + fallthrough; + case EP_STATE_RUNNING: + /* Race, HW handled stop ep cmd before ep was running */ + xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n", + GET_EP_CTX_STATE(ep_ctx)); +- /* +- * Don't retry forever if we guessed wrong or a defective HC never starts +- * the EP or says 'Running' but fails the command. We must give back TDs. +- */ +- if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) +- break; + + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); + if (!command) { +diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig +index 99b15b77dfd576..fe1b5fec1dfcab 100644 +--- a/drivers/usb/misc/Kconfig ++++ b/drivers/usb/misc/Kconfig +@@ -147,6 +147,7 @@ config USB_APPLEDISPLAY + config USB_QCOM_EUD + tristate "QCOM Embedded USB Debugger(EUD) Driver" + depends on ARCH_QCOM || COMPILE_TEST ++ select QCOM_SCM + select USB_ROLE_SWITCH + help + This module enables support for Qualcomm Technologies, Inc. +diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c +index 7f371ea1248c32..cfb195a0f6ce22 100644 +--- a/drivers/usb/misc/qcom_eud.c ++++ b/drivers/usb/misc/qcom_eud.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #define EUD_REG_INT1_EN_MASK 0x0024 + #define EUD_REG_INT_STATUS_1 0x0044 +@@ -34,7 +35,7 @@ struct eud_chip { + struct device *dev; + struct usb_role_switch *role_sw; + void __iomem *base; +- void __iomem *mode_mgr; ++ phys_addr_t mode_mgr; + unsigned int int_status; + int irq; + bool enabled; +@@ -43,18 +44,29 @@ struct eud_chip { + + static int enable_eud(struct eud_chip *priv) + { ++ int ret; ++ ++ ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); ++ if (ret) ++ return ret; ++ + writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); + writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, + priv->base + EUD_REG_INT1_EN_MASK); +- writel(1, priv->mode_mgr + EUD_REG_EUD_EN2); + + return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); + } + +-static void disable_eud(struct eud_chip *priv) ++static int disable_eud(struct eud_chip *priv) + { ++ int ret; ++ ++ ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 0); ++ if (ret) ++ return ret; ++ + writel(0, priv->base + EUD_REG_CSR_EUD_EN); +- writel(0, priv->mode_mgr + EUD_REG_EUD_EN2); ++ return 0; + } + + static ssize_t enable_show(struct device *dev, +@@ -82,11 +94,12 @@ static ssize_t enable_store(struct device *dev, + chip->enabled = enable; + else + disable_eud(chip); ++ + } else { +- disable_eud(chip); ++ ret = disable_eud(chip); + } + +- return count; ++ return ret < 0 ? ret : count; + } + + static DEVICE_ATTR_RW(enable); +@@ -178,6 +191,7 @@ static void eud_role_switch_release(void *data) + static int eud_probe(struct platform_device *pdev) + { + struct eud_chip *chip; ++ struct resource *res; + int ret; + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); +@@ -200,9 +214,10 @@ static int eud_probe(struct platform_device *pdev) + if (IS_ERR(chip->base)) + return PTR_ERR(chip->base); + +- chip->mode_mgr = devm_platform_ioremap_resource(pdev, 1); +- if (IS_ERR(chip->mode_mgr)) +- return PTR_ERR(chip->mode_mgr); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res) ++ return -ENODEV; ++ chip->mode_mgr = res->start; + + chip->irq = platform_get_irq(pdev, 0); + ret = devm_request_threaded_irq(&pdev->dev, chip->irq, handle_eud_irq, +diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c +index c3ce6b1054f1c3..292c32ccae0502 100644 +--- a/drivers/usb/phy/phy-twl6030-usb.c ++++ b/drivers/usb/phy/phy-twl6030-usb.c +@@ -328,9 +328,8 @@ static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) + + static int twl6030_usb_probe(struct platform_device *pdev) + { +- u32 ret; + struct twl6030_usb *twl; +- int status, err; ++ int status, err, ret; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + +diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c +index 01db27cbf1d10d..3559781d01a38c 100644 +--- a/drivers/usb/typec/tipd/core.c ++++ b/drivers/usb/typec/tipd/core.c +@@ -488,24 +488,23 @@ static irqreturn_t cd321x_interrupt(int irq, void *data) + if (!event) + goto err_unlock; + ++ tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event); ++ + if (!tps6598x_read_status(tps, &status)) +- goto err_clear_ints; ++ goto err_unlock; + + if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE) + if (!tps6598x_read_power_status(tps)) +- goto err_clear_ints; ++ goto err_unlock; + + if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE) + if (!tps6598x_read_data_status(tps)) +- goto err_clear_ints; ++ goto err_unlock; + + /* Handle plug insert or removal */ + if (event & APPLE_CD_REG_INT_PLUG_EVENT) + tps6598x_handle_plug_event(tps, status); + +-err_clear_ints: +- tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event); +- + err_unlock: + mutex_unlock(&tps->lock); + +@@ -552,25 +551,24 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) + if (!(event1[0] | event1[1] | event2[0] | event2[1])) + goto err_unlock; + ++ tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len); ++ tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len); ++ + if (!tps6598x_read_status(tps, &status)) +- goto err_clear_ints; ++ goto err_unlock; + + if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) + if (!tps6598x_read_power_status(tps)) +- goto err_clear_ints; ++ goto err_unlock; + + if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE) + if (!tps6598x_read_data_status(tps)) +- goto err_clear_ints; ++ goto err_unlock; + + /* Handle plug insert or removal */ + if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) + tps6598x_handle_plug_event(tps, status); + +-err_clear_ints: +- tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len); +- tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len); +- + err_unlock: + mutex_unlock(&tps->lock); + +diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c +index 14a5f55f24fc8c..b22e0881bfaf38 100644 +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -764,6 +764,17 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + ctrlreq->wValue, vdev->rhport); + + vdev->udev = usb_get_dev(urb->dev); ++ /* ++ * NOTE: A similar operation has been done via ++ * USB_REQ_GET_DESCRIPTOR handler below, which is ++ * supposed to always precede USB_REQ_SET_ADDRESS. ++ * ++ * It's not entirely clear if operating on a different ++ * usb_device instance here is a real possibility, ++ * otherwise this call and vdev->udev assignment above ++ * should be dropped. ++ */ ++ dev_pm_syscore_device(&vdev->udev->dev, true); + usb_put_dev(old); + + spin_lock(&vdev->ud.lock); +@@ -784,6 +795,17 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); + + vdev->udev = usb_get_dev(urb->dev); ++ /* ++ * Set syscore PM flag for the virtually attached ++ * devices to ensure they will not enter suspend on ++ * the client side. ++ * ++ * Note this doesn't have any impact on the physical ++ * devices attached to the host system on the server ++ * side, hence there is no need to undo the operation ++ * on disconnect. ++ */ ++ dev_pm_syscore_device(&vdev->udev->dev, true); + usb_put_dev(old); + goto out; + +diff --git a/drivers/vfio/pci/pds/dirty.c b/drivers/vfio/pci/pds/dirty.c +index 27607d7b9030a4..6adc5f1ae2eb99 100644 +--- a/drivers/vfio/pci/pds/dirty.c ++++ b/drivers/vfio/pci/pds/dirty.c +@@ -81,7 +81,7 @@ static int pds_vfio_dirty_alloc_bitmaps(struct pds_vfio_dirty *dirty, + + host_ack_bmp = vzalloc(bytes); + if (!host_ack_bmp) { +- bitmap_free(host_seq_bmp); ++ vfree(host_seq_bmp); + return -ENOMEM; + } + +diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c +index 7b8fd977f71ccf..134cc10af776bd 100644 +--- a/drivers/vhost/vringh.c ++++ b/drivers/vhost/vringh.c +@@ -1191,6 +1191,7 @@ static inline int copy_from_iotlb(const struct vringh *vrh, void *dst, + struct iov_iter iter; + u64 translated; + int ret; ++ size_t size; + + ret = iotlb_translate(vrh, (u64)(uintptr_t)src, + len - total_translated, &translated, +@@ -1208,9 +1209,9 @@ static inline int copy_from_iotlb(const struct vringh *vrh, void *dst, + translated); + } + +- ret = copy_from_iter(dst, translated, &iter); +- if (ret < 0) +- return ret; ++ size = copy_from_iter(dst, translated, &iter); ++ if (size != translated) ++ return -EFAULT; + + src += translated; + dst += translated; +@@ -1237,6 +1238,7 @@ static inline int copy_to_iotlb(const struct vringh *vrh, void *dst, + struct iov_iter iter; + u64 translated; + int ret; ++ size_t size; + + ret = iotlb_translate(vrh, (u64)(uintptr_t)dst, + len - total_translated, &translated, +@@ -1254,9 +1256,9 @@ static inline int copy_to_iotlb(const struct vringh *vrh, void *dst, + translated); + } + +- ret = copy_to_iter(src, translated, &iter); +- if (ret < 0) +- return ret; ++ size = copy_to_iter(src, translated, &iter); ++ if (size != translated) ++ return -EFAULT; + + src += translated; + dst += translated; +diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c +index 867f9f31137971..a4b497ecfa2051 100644 +--- a/drivers/watchdog/mpc8xxx_wdt.c ++++ b/drivers/watchdog/mpc8xxx_wdt.c +@@ -100,6 +100,8 @@ static int mpc8xxx_wdt_start(struct watchdog_device *w) + ddata->swtc = tmp >> 16; + set_bit(WDOG_HW_RUNNING, &ddata->wdd.status); + ++ mpc8xxx_wdt_keepalive(ddata); ++ + return 0; + } + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index b55d5e2abeb3cb..7afce7b744c018 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1960,6 +1960,16 @@ static inline bool ext4_verity_in_progress(struct inode *inode) + + #define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime + ++/* ++ * Check whether the inode is tracked as orphan (either in orphan file or ++ * orphan list). ++ */ ++static inline bool ext4_inode_orphan_tracked(struct inode *inode) ++{ ++ return ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) || ++ !list_empty(&EXT4_I(inode)->i_orphan); ++} ++ + /* + * Codes for operating systems + */ +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index b37e0e4a71bfbe..0d387a5b5a678c 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -354,7 +354,7 @@ static void ext4_inode_extension_cleanup(struct inode *inode, bool need_trunc) + * to cleanup the orphan list in ext4_handle_inode_extension(). Do it + * now. + */ +- if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { ++ if (ext4_inode_orphan_tracked(inode) && inode->i_nlink) { + handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); + + if (IS_ERR(handle)) { +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 886d4dfa737a27..63b1384823ba56 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4370,7 +4370,7 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode + * old inodes get re-used with the upper 16 bits of the + * uid/gid intact. + */ +- if (ei->i_dtime && list_empty(&ei->i_orphan)) { ++ if (ei->i_dtime && !ext4_inode_orphan_tracked(inode)) { + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } else { +diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c +index a23b0c01f8096d..c53918768cb256 100644 +--- a/fs/ext4/orphan.c ++++ b/fs/ext4/orphan.c +@@ -109,11 +109,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) + + WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && + !inode_is_locked(inode)); +- /* +- * Inode orphaned in orphan file or in orphan list? +- */ +- if (ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) || +- !list_empty(&EXT4_I(inode)->i_orphan)) ++ if (ext4_inode_orphan_tracked(inode)) + return 0; + + /* +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 7e3906f1390975..527f53bfe1b1f0 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1464,9 +1464,9 @@ static void ext4_free_in_core_inode(struct inode *inode) + + static void ext4_destroy_inode(struct inode *inode) + { +- if (!list_empty(&(EXT4_I(inode)->i_orphan))) { ++ if (ext4_inode_orphan_tracked(inode)) { + ext4_msg(inode->i_sb, KERN_ERR, +- "Inode %lu (%p): orphan list check failed!", ++ "Inode %lu (%p): inode tracked as orphan!", + inode->i_ino, EXT4_I(inode)); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, + EXT4_I(inode), sizeof(struct ext4_inode_info), +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index d37104aa847a74..fe23ebfc88ea14 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -1751,12 +1751,13 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) + if (map->m_flags & F2FS_MAP_MAPPED) { + unsigned int ofs = start_pgofs - map->m_lblk; + +- f2fs_update_read_extent_cache_range(&dn, +- start_pgofs, map->m_pblk + ofs, +- map->m_len - ofs); ++ if (map->m_len > ofs) ++ f2fs_update_read_extent_cache_range(&dn, ++ start_pgofs, map->m_pblk + ofs, ++ map->m_len - ofs); + } + if (map->m_next_extent) +- *map->m_next_extent = pgofs + 1; ++ *map->m_next_extent = is_hole ? pgofs + 1 : pgofs; + } + f2fs_put_dnode(&dn); + unlock_out: +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 7329f706da83c3..ab2ddd09d8131c 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -2296,8 +2296,6 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi, + { + if (!inode) + return true; +- if (!test_opt(sbi, RESERVE_ROOT)) +- return false; + if (IS_NOQUOTA(inode)) + return true; + if (uid_eq(F2FS_OPTION(sbi).s_resuid, current_fsuid())) +@@ -2318,7 +2316,7 @@ static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi, + avail_user_block_count = sbi->user_block_count - + sbi->current_reserved_blocks; + +- if (!__allow_reserved_blocks(sbi, inode, cap)) ++ if (test_opt(sbi, RESERVE_ROOT) && !__allow_reserved_blocks(sbi, inode, cap)) + avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks; + + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 031015823acb2b..6267ba6ef10839 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -36,15 +36,23 @@ + #include + #include + +-static void f2fs_zero_post_eof_page(struct inode *inode, loff_t new_size) ++static void f2fs_zero_post_eof_page(struct inode *inode, ++ loff_t new_size, bool lock) + { + loff_t old_size = i_size_read(inode); + + if (old_size >= new_size) + return; + ++ if (mapping_empty(inode->i_mapping)) ++ return; ++ ++ if (lock) ++ filemap_invalidate_lock(inode->i_mapping); + /* zero or drop pages only in range of [old_size, new_size] */ +- truncate_pagecache(inode, old_size); ++ truncate_inode_pages_range(inode->i_mapping, old_size, new_size); ++ if (lock) ++ filemap_invalidate_unlock(inode->i_mapping); + } + + static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) +@@ -115,9 +123,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) + + f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); + +- filemap_invalidate_lock(inode->i_mapping); +- f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT); +- filemap_invalidate_unlock(inode->i_mapping); ++ f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true); + + file_update_time(vmf->vma->vm_file); + filemap_invalidate_lock_shared(inode->i_mapping); +@@ -844,8 +850,16 @@ int f2fs_truncate(struct inode *inode) + /* we should check inline_data size */ + if (!f2fs_may_inline_data(inode)) { + err = f2fs_convert_inline_inode(inode); +- if (err) ++ if (err) { ++ /* ++ * Always truncate page #0 to avoid page cache ++ * leak in evict() path. ++ */ ++ truncate_inode_pages_range(inode->i_mapping, ++ F2FS_BLK_TO_BYTES(0), ++ F2FS_BLK_END_BYTES(0)); + return err; ++ } + } + + err = f2fs_truncate_blocks(inode, i_size_read(inode), true); +@@ -1069,7 +1083,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + filemap_invalidate_lock(inode->i_mapping); + + if (attr->ia_size > old_size) +- f2fs_zero_post_eof_page(inode, attr->ia_size); ++ f2fs_zero_post_eof_page(inode, attr->ia_size, false); + truncate_setsize(inode, attr->ia_size); + + if (attr->ia_size <= old_size) +@@ -1188,9 +1202,7 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len) + if (ret) + return ret; + +- filemap_invalidate_lock(inode->i_mapping); +- f2fs_zero_post_eof_page(inode, offset + len); +- filemap_invalidate_unlock(inode->i_mapping); ++ f2fs_zero_post_eof_page(inode, offset + len, true); + + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; + pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT; +@@ -1476,7 +1488,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + filemap_invalidate_lock(inode->i_mapping); + +- f2fs_zero_post_eof_page(inode, offset + len); ++ f2fs_zero_post_eof_page(inode, offset + len, false); + + f2fs_lock_op(sbi); + f2fs_drop_extent_tree(inode); +@@ -1600,9 +1612,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, + if (ret) + return ret; + +- filemap_invalidate_lock(mapping); +- f2fs_zero_post_eof_page(inode, offset + len); +- filemap_invalidate_unlock(mapping); ++ f2fs_zero_post_eof_page(inode, offset + len, true); + + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; + pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT; +@@ -1736,7 +1746,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + filemap_invalidate_lock(mapping); + +- f2fs_zero_post_eof_page(inode, offset + len); ++ f2fs_zero_post_eof_page(inode, offset + len, false); + truncate_pagecache(inode, offset); + + while (!ret && idx > pg_start) { +@@ -1792,9 +1802,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, + if (err) + return err; + +- filemap_invalidate_lock(inode->i_mapping); +- f2fs_zero_post_eof_page(inode, offset + len); +- filemap_invalidate_unlock(inode->i_mapping); ++ f2fs_zero_post_eof_page(inode, offset + len, true); + + f2fs_balance_fs(sbi, true); + +@@ -4710,9 +4718,8 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from) + if (err) + return err; + +- filemap_invalidate_lock(inode->i_mapping); +- f2fs_zero_post_eof_page(inode, iocb->ki_pos + iov_iter_count(from)); +- filemap_invalidate_unlock(inode->i_mapping); ++ f2fs_zero_post_eof_page(inode, ++ iocb->ki_pos + iov_iter_count(from), true); + return count; + } + +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index 687670075d2256..c4bc86c3535ba6 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -811,8 +811,6 @@ __acquires(&gl->gl_lockref.lock) + clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); + gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD); + return; +- } else { +- clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); + } + } + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 124b9cee6fed7d..94a1caf3266991 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -9226,7 +9226,7 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args + goto out; + if (rcvd->max_rqst_sz > sent->max_rqst_sz) + return -EINVAL; +- if (rcvd->max_resp_sz < sent->max_resp_sz) ++ if (rcvd->max_resp_sz > sent->max_resp_sz) + return -EINVAL; + if (rcvd->max_resp_sz_cached > sent->max_resp_sz_cached) + return -EINVAL; +diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c +index 191b91ffadbb21..f227db9f76c2b4 100644 +--- a/fs/ntfs3/index.c ++++ b/fs/ntfs3/index.c +@@ -1510,6 +1510,16 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, + bmp_size = bmp_size_v = le32_to_cpu(bmp->res.data_size); + } + ++ /* ++ * Index blocks exist, but $BITMAP has zero valid bits. ++ * This implies an on-disk corruption and must be rejected. ++ */ ++ if (in->name == I30_NAME && ++ unlikely(bmp_size_v == 0 && indx->alloc_run.count)) { ++ err = -EINVAL; ++ goto out1; ++ } ++ + bit = bmp_size << 3; + } + +diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c +index 44e93ad491ba77..0139124578d9e2 100644 +--- a/fs/ntfs3/run.c ++++ b/fs/ntfs3/run.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "ntfs.h" +@@ -982,12 +983,16 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, + + if (!dlcn) + return -EINVAL; +- lcn = prev_lcn + dlcn; ++ ++ if (check_add_overflow(prev_lcn, dlcn, &lcn)) ++ return -EINVAL; + prev_lcn = lcn; + } else + return -EINVAL; + +- next_vcn = vcn64 + len; ++ if (check_add_overflow(vcn64, len, &next_vcn)) ++ return -EINVAL; ++ + /* Check boundary. */ + if (next_vcn > evcn + 1) + return -EINVAL; +@@ -1151,7 +1156,8 @@ int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn) + return -EINVAL; + + run_buf += size_size + offset_size; +- vcn64 += len; ++ if (check_add_overflow(vcn64, len, &vcn64)) ++ return -EINVAL; + + #ifndef CONFIG_NTFS3_64BIT_CLUSTER + if (vcn64 > 0x100000000ull) +diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c +index 9b76ee66aeb2f4..38c0d6f64fce38 100644 +--- a/fs/ocfs2/stack_user.c ++++ b/fs/ocfs2/stack_user.c +@@ -1018,6 +1018,7 @@ static int user_cluster_connect(struct ocfs2_cluster_connection *conn) + printk(KERN_ERR "ocfs2: Could not determine" + " locking version\n"); + user_cluster_disconnect(conn); ++ lc = NULL; + goto out; + } + wait_event(lc->oc_wait, (atomic_read(&lc->oc_this_node) > 0)); +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index b74f7690473948..ee6a6ba13f89c8 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -4152,7 +4152,7 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, + static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst, + int num_rqst, const u8 *sig, u8 **iv, + struct aead_request **req, struct sg_table *sgt, +- unsigned int *num_sgs, size_t *sensitive_size) ++ unsigned int *num_sgs) + { + unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm); + unsigned int iv_size = crypto_aead_ivsize(tfm); +@@ -4169,9 +4169,8 @@ static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst + len += req_size; + len = ALIGN(len, __alignof__(struct scatterlist)); + len += array_size(*num_sgs, sizeof(struct scatterlist)); +- *sensitive_size = len; + +- p = kvzalloc(len, GFP_NOFS); ++ p = kzalloc(len, GFP_NOFS); + if (!p) + return ERR_PTR(-ENOMEM); + +@@ -4185,16 +4184,14 @@ static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst + + static void *smb2_get_aead_req(struct crypto_aead *tfm, struct smb_rqst *rqst, + int num_rqst, const u8 *sig, u8 **iv, +- struct aead_request **req, struct scatterlist **sgl, +- size_t *sensitive_size) ++ struct aead_request **req, struct scatterlist **sgl) + { + struct sg_table sgtable = {}; + unsigned int skip, num_sgs, i, j; + ssize_t rc; + void *p; + +- p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, &sgtable, +- &num_sgs, sensitive_size); ++ p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, &sgtable, &num_sgs); + if (IS_ERR(p)) + return ERR_CAST(p); + +@@ -4283,7 +4280,6 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + DECLARE_CRYPTO_WAIT(wait); + unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize); + void *creq; +- size_t sensitive_size; + + rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key); + if (rc) { +@@ -4309,8 +4305,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + return rc; + } + +- creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg, +- &sensitive_size); ++ creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg); + if (IS_ERR(creq)) + return PTR_ERR(creq); + +@@ -4340,7 +4335,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + if (!rc && enc) + memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); + +- kvfree_sensitive(creq, sensitive_size); ++ kfree_sensitive(creq); + return rc; + } + +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index ae47450dc40f82..93c31feab3564c 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -5596,7 +5596,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, + + if (!work->tcon->posix_extensions) { + pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); +- rc = -EOPNOTSUPP; ++ path_put(&path); ++ return -EOPNOTSUPP; + } else { + info = (struct filesystem_posix_info *)(rsp->Buffer); + info->OptimalTransferSize = cpu_to_le32(stfs.f_bsize); +diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c +index 504e2a1cf33b84..31c1ac256e1be4 100644 +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -152,6 +152,10 @@ struct smb_direct_transport { + struct work_struct disconnect_work; + + bool negotiation_requested; ++ ++ bool legacy_iwarp; ++ u8 initiator_depth; ++ u8 responder_resources; + }; + + #define KSMBD_TRANS(t) ((struct ksmbd_transport *)&((t)->transport)) +@@ -346,6 +350,9 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) + t->cm_id = cm_id; + cm_id->context = t; + ++ t->initiator_depth = SMB_DIRECT_CM_INITIATOR_DEPTH; ++ t->responder_resources = 1; ++ + t->status = SMB_DIRECT_CS_NEW; + init_waitqueue_head(&t->wait_status); + +@@ -1623,21 +1630,21 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t, + static int smb_direct_accept_client(struct smb_direct_transport *t) + { + struct rdma_conn_param conn_param; +- struct ib_port_immutable port_immutable; +- u32 ird_ord_hdr[2]; ++ __be32 ird_ord_hdr[2]; + int ret; + ++ /* ++ * smb_direct_handle_connect_request() ++ * already negotiated t->initiator_depth ++ * and t->responder_resources ++ */ + memset(&conn_param, 0, sizeof(conn_param)); +- conn_param.initiator_depth = min_t(u8, t->cm_id->device->attrs.max_qp_rd_atom, +- SMB_DIRECT_CM_INITIATOR_DEPTH); +- conn_param.responder_resources = 0; +- +- t->cm_id->device->ops.get_port_immutable(t->cm_id->device, +- t->cm_id->port_num, +- &port_immutable); +- if (port_immutable.core_cap_flags & RDMA_CORE_PORT_IWARP) { +- ird_ord_hdr[0] = conn_param.responder_resources; +- ird_ord_hdr[1] = 1; ++ conn_param.initiator_depth = t->initiator_depth; ++ conn_param.responder_resources = t->responder_resources; ++ ++ if (t->legacy_iwarp) { ++ ird_ord_hdr[0] = cpu_to_be32(conn_param.responder_resources); ++ ird_ord_hdr[1] = cpu_to_be32(conn_param.initiator_depth); + conn_param.private_data = ird_ord_hdr; + conn_param.private_data_len = sizeof(ird_ord_hdr); + } else { +@@ -2023,10 +2030,13 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs) + return true; + } + +-static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) ++static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id, ++ struct rdma_cm_event *event) + { + struct smb_direct_transport *t; + struct task_struct *handler; ++ u8 peer_initiator_depth; ++ u8 peer_responder_resources; + int ret; + + if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { +@@ -2040,6 +2050,67 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) + if (!t) + return -ENOMEM; + ++ peer_initiator_depth = event->param.conn.initiator_depth; ++ peer_responder_resources = event->param.conn.responder_resources; ++ if (rdma_protocol_iwarp(new_cm_id->device, new_cm_id->port_num) && ++ event->param.conn.private_data_len == 8) { ++ /* ++ * Legacy clients with only iWarp MPA v1 support ++ * need a private blob in order to negotiate ++ * the IRD/ORD values. ++ */ ++ const __be32 *ird_ord_hdr = event->param.conn.private_data; ++ u32 ird32 = be32_to_cpu(ird_ord_hdr[0]); ++ u32 ord32 = be32_to_cpu(ird_ord_hdr[1]); ++ ++ /* ++ * cifs.ko sends the legacy IRD/ORD negotiation ++ * event if iWarp MPA v2 was used. ++ * ++ * Here we check that the values match and only ++ * mark the client as legacy if they don't match. ++ */ ++ if ((u32)event->param.conn.initiator_depth != ird32 || ++ (u32)event->param.conn.responder_resources != ord32) { ++ /* ++ * There are broken clients (old cifs.ko) ++ * using little endian and also ++ * struct rdma_conn_param only uses u8 ++ * for initiator_depth and responder_resources, ++ * so we truncate the value to U8_MAX. ++ * ++ * smb_direct_accept_client() will then ++ * do the real negotiation in order to ++ * select the minimum between client and ++ * server. ++ */ ++ ird32 = min_t(u32, ird32, U8_MAX); ++ ord32 = min_t(u32, ord32, U8_MAX); ++ ++ t->legacy_iwarp = true; ++ peer_initiator_depth = (u8)ird32; ++ peer_responder_resources = (u8)ord32; ++ } ++ } ++ ++ /* ++ * First set what the we as server are able to support ++ */ ++ t->initiator_depth = min_t(u8, t->initiator_depth, ++ new_cm_id->device->attrs.max_qp_rd_atom); ++ ++ /* ++ * negotiate the value by using the minimum ++ * between client and server if the client provided ++ * non 0 values. ++ */ ++ if (peer_initiator_depth != 0) ++ t->initiator_depth = min_t(u8, t->initiator_depth, ++ peer_initiator_depth); ++ if (peer_responder_resources != 0) ++ t->responder_resources = min_t(u8, t->responder_resources, ++ peer_responder_resources); ++ + ret = smb_direct_connect(t); + if (ret) + goto out_err; +@@ -2064,7 +2135,7 @@ static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, + { + switch (event->event) { + case RDMA_CM_EVENT_CONNECT_REQUEST: { +- int ret = smb_direct_handle_connect_request(cm_id); ++ int ret = smb_direct_handle_connect_request(cm_id, event); + + if (ret) { + pr_err("Can't create transport: %d\n", ret); +diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c +index d5918eba27e371..53104f25de5116 100644 +--- a/fs/squashfs/inode.c ++++ b/fs/squashfs/inode.c +@@ -165,6 +165,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); + squashfs_i(inode)->block_list_start = block; + squashfs_i(inode)->offset = offset; ++ squashfs_i(inode)->parent = 0; + inode->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, block_list_start " +@@ -212,6 +213,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block); + squashfs_i(inode)->block_list_start = block; + squashfs_i(inode)->offset = offset; ++ squashfs_i(inode)->parent = 0; + inode->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, block_list_start " +@@ -292,6 +294,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + inode->i_mode |= S_IFLNK; + squashfs_i(inode)->start = block; + squashfs_i(inode)->offset = offset; ++ squashfs_i(inode)->parent = 0; + + if (type == SQUASHFS_LSYMLINK_TYPE) { + __le32 xattr; +@@ -329,6 +332,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + rdev = le32_to_cpu(sqsh_ino->rdev); + init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); ++ squashfs_i(inode)->parent = 0; + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(ino), offset, rdev); +@@ -353,6 +357,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + rdev = le32_to_cpu(sqsh_ino->rdev); + init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); ++ squashfs_i(inode)->parent = 0; + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(ino), offset, rdev); +@@ -373,6 +378,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + inode->i_mode |= S_IFSOCK; + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + init_special_inode(inode, inode->i_mode, 0); ++ squashfs_i(inode)->parent = 0; + break; + } + case SQUASHFS_LFIFO_TYPE: +@@ -392,6 +398,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) + inode->i_op = &squashfs_inode_ops; + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + init_special_inode(inode, inode->i_mode, 0); ++ squashfs_i(inode)->parent = 0; + break; + } + default: +diff --git a/fs/squashfs/squashfs_fs_i.h b/fs/squashfs/squashfs_fs_i.h +index 2c82d6f2a4561b..8e497ac07b9a83 100644 +--- a/fs/squashfs/squashfs_fs_i.h ++++ b/fs/squashfs/squashfs_fs_i.h +@@ -16,6 +16,7 @@ struct squashfs_inode_info { + u64 xattr; + unsigned int xattr_size; + int xattr_count; ++ int parent; + union { + struct { + u64 fragment_block; +@@ -27,7 +28,6 @@ struct squashfs_inode_info { + u64 dir_idx_start; + int dir_idx_offset; + int dir_idx_cnt; +- int parent; + }; + }; + struct inode vfs_inode; +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index 2f73119c7ec98a..848c46c5e9d3c3 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -2265,6 +2265,9 @@ int udf_current_aext(struct inode *inode, struct extent_position *epos, + if (check_add_overflow(sizeof(struct allocExtDesc), + le32_to_cpu(header->lengthAllocDescs), &alen)) + return -1; ++ ++ if (alen > epos->bh->b_size) ++ return -1; + } + + switch (iinfo->i_alloc_type) { +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index cf3f8b9bf43f08..010ac18c05916e 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -351,6 +351,7 @@ + __start_once = .; \ + *(.data..once) \ + __end_once = .; \ ++ *(.data..do_once) \ + STRUCT_ALIGN(); \ + *(__tracepoints) \ + /* implement dynamic printk debug */ \ +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 83da9c81fa86ad..0af6b2a5273adc 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -269,6 +269,7 @@ struct bpf_map_owner { + bool xdp_has_frags; + u64 storage_cookie[MAX_BPF_CGROUP_STORAGE_TYPE]; + const struct btf_type *attach_func_proto; ++ enum bpf_attach_type expected_attach_type; + }; + + struct bpf_map { +diff --git a/include/linux/once.h b/include/linux/once.h +index 30346fcdc7995d..449a0e34ad5ad9 100644 +--- a/include/linux/once.h ++++ b/include/linux/once.h +@@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, + #define DO_ONCE(func, ...) \ + ({ \ + bool ___ret = false; \ +- static bool __section(".data..once") ___done = false; \ ++ static bool __section(".data..do_once") ___done = false; \ + static DEFINE_STATIC_KEY_TRUE(___once_key); \ + if (static_branch_unlikely(&___once_key)) { \ + unsigned long ___flags; \ +@@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, + #define DO_ONCE_SLEEPABLE(func, ...) \ + ({ \ + bool ___ret = false; \ +- static bool __section(".data..once") ___done = false; \ ++ static bool __section(".data..do_once") ___done = false; \ + static DEFINE_STATIC_KEY_TRUE(___once_key); \ + if (static_branch_unlikely(&___once_key)) { \ + ___ret = __do_once_sleepable_start(&___done); \ +diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h +index 1646dadd7f37cf..3b1c8d93b2654c 100644 +--- a/include/trace/events/filelock.h ++++ b/include/trace/events/filelock.h +@@ -27,7 +27,8 @@ + { FL_SLEEP, "FL_SLEEP" }, \ + { FL_DOWNGRADE_PENDING, "FL_DOWNGRADE_PENDING" }, \ + { FL_UNLOCK_PENDING, "FL_UNLOCK_PENDING" }, \ +- { FL_OFDLCK, "FL_OFDLCK" }) ++ { FL_OFDLCK, "FL_OFDLCK" }, \ ++ { FL_RECLAIM, "FL_RECLAIM"}) + + #define show_fl_type(val) \ + __print_symbolic(val, \ +diff --git a/init/Kconfig b/init/Kconfig +index 8b630143c720f6..461591503bf43f 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1367,6 +1367,7 @@ config BOOT_CONFIG_EMBED_FILE + + config INITRAMFS_PRESERVE_MTIME + bool "Preserve cpio archive mtimes in initramfs" ++ depends on BLK_DEV_INITRD + default y + help + Each entry in an initramfs cpio archive carries an mtime value. When +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 3618be05fc3527..a343248c35ded6 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -2279,6 +2279,7 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map, + map->owner->type = prog_type; + map->owner->jited = fp->jited; + map->owner->xdp_has_frags = aux->xdp_has_frags; ++ map->owner->expected_attach_type = fp->expected_attach_type; + map->owner->attach_func_proto = aux->attach_func_proto; + for_each_cgroup_storage_type(i) { + map->owner->storage_cookie[i] = +@@ -2290,6 +2291,10 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map, + ret = map->owner->type == prog_type && + map->owner->jited == fp->jited && + map->owner->xdp_has_frags == aux->xdp_has_frags; ++ if (ret && ++ map->map_type == BPF_MAP_TYPE_PROG_ARRAY && ++ map->owner->expected_attach_type != fp->expected_attach_type) ++ ret = false; + for_each_cgroup_storage_type(i) { + if (!ret) + break; +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a6f825b7fbe6cd..5e644b1b12aaaa 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -13727,7 +13727,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) + } else { /* all other ALU ops: and, sub, xor, add, ... */ + + if (BPF_SRC(insn->code) == BPF_X) { +- if (insn->imm != 0 || insn->off > 1 || ++ if (insn->imm != 0 || (insn->off != 0 && insn->off != 1) || + (insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) { + verbose(env, "BPF_ALU uses reserved fields\n"); + return -EINVAL; +@@ -13737,7 +13737,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) + if (err) + return err; + } else { +- if (insn->src_reg != BPF_REG_0 || insn->off > 1 || ++ if (insn->src_reg != BPF_REG_0 || (insn->off != 0 && insn->off != 1) || + (insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) { + verbose(env, "BPF_ALU uses reserved fields\n"); + return -EINVAL; +diff --git a/kernel/seccomp.c b/kernel/seccomp.c +index 255999ba9190a6..1d26a0e978f269 100644 +--- a/kernel/seccomp.c ++++ b/kernel/seccomp.c +@@ -1099,7 +1099,7 @@ static void seccomp_handle_addfd(struct seccomp_kaddfd *addfd, struct seccomp_kn + static bool should_sleep_killable(struct seccomp_filter *match, + struct seccomp_knotif *n) + { +- return match->wait_killable_recv && n->state == SECCOMP_NOTIFY_SENT; ++ return match->wait_killable_recv && n->state >= SECCOMP_NOTIFY_SENT; + } + + static int seccomp_do_user_notification(int this_syscall, +@@ -1146,13 +1146,11 @@ static int seccomp_do_user_notification(int this_syscall, + + if (err != 0) { + /* +- * Check to see if the notifcation got picked up and +- * whether we should switch to wait killable. ++ * Check to see whether we should switch to wait ++ * killable. Only return the interrupted error if not. + */ +- if (!wait_killable && should_sleep_killable(match, &n)) +- continue; +- +- goto interrupted; ++ if (!(!wait_killable && should_sleep_killable(match, &n))) ++ goto interrupted; + } + + addfd = list_first_entry_or_null(&n.addfd, +diff --git a/kernel/smp.c b/kernel/smp.c +index 3eeffeaf5450c6..13b376c7296a54 100644 +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -862,16 +862,15 @@ static void smp_call_function_many_cond(const struct cpumask *mask, + * @mask: The set of cpus to run on (only runs on online subset). + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. +- * @wait: Bitmask that controls the operation. If %SCF_WAIT is set, wait +- * (atomically) until function has completed on other CPUs. If +- * %SCF_RUN_LOCAL is set, the function will also be run locally +- * if the local CPU is set in the @cpumask. +- * +- * If @wait is true, then returns once @func has returned. ++ * @wait: If true, wait (atomically) until function has completed ++ * on other CPUs. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. Preemption + * must be disabled when calling this function. ++ * ++ * @func is not called on the local CPU even if @mask contains it. Consider ++ * using on_each_cpu_cond_mask() instead if this is not desirable. + */ + void smp_call_function_many(const struct cpumask *mask, + smp_call_func_t func, void *info, bool wait) +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 8903db0b596026..a896b80252ae11 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -2726,18 +2726,23 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, + struct bpf_run_ctx *old_run_ctx; + int err; + ++ /* ++ * graph tracer framework ensures we won't migrate, so there is no need ++ * to use migrate_disable for bpf_prog_run again. The check here just for ++ * __this_cpu_inc_return. ++ */ ++ cant_sleep(); ++ + if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) { + err = 0; + goto out; + } + +- migrate_disable(); + rcu_read_lock(); + old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + err = bpf_prog_run(link->link.prog, regs); + bpf_reset_run_ctx(old_run_ctx); + rcu_read_unlock(); +- migrate_enable(); + + out: + __this_cpu_dec(bpf_prog_active); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index d57d8f1c2dfea4..0c6745a6a13a59 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -6693,6 +6693,8 @@ long hugetlb_change_protection(struct vm_area_struct *vma, + psize); + } + spin_unlock(ptl); ++ ++ cond_resched(); + } + /* + * Must flush TLB before releasing i_mmap_rwsem: x86's huge_pmd_unshare +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index dc9209f9f1a6a3..a128e5709fa153 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -1347,7 +1347,7 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance) + { + struct hci_cp_le_set_ext_adv_params cp; + struct hci_rp_le_set_ext_adv_params rp; +- bool connectable; ++ bool connectable, require_privacy; + u32 flags; + bdaddr_t random_addr; + u8 own_addr_type; +@@ -1385,10 +1385,12 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance) + return -EPERM; + + /* Set require_privacy to true only when non-connectable +- * advertising is used. In that case it is fine to use a +- * non-resolvable private address. ++ * advertising is used and it is not periodic. ++ * In that case it is fine to use a non-resolvable private address. + */ +- err = hci_get_random_address(hdev, !connectable, ++ require_privacy = !connectable && !(adv && adv->periodic); ++ ++ err = hci_get_random_address(hdev, require_privacy, + adv_use_rpa(hdev, flags), adv, + &own_addr_type, &random_addr); + if (err < 0) +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index b94d202bf3745c..69529a3049e741 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -718,6 +718,13 @@ static void iso_sock_kill(struct sock *sk) + + BT_DBG("sk %p state %d", sk, sk->sk_state); + ++ /* Sock is dead, so set conn->sk to NULL to avoid possible UAF */ ++ if (iso_pi(sk)->conn) { ++ iso_conn_lock(iso_pi(sk)->conn); ++ iso_pi(sk)->conn->sk = NULL; ++ iso_conn_unlock(iso_pi(sk)->conn); ++ } ++ + /* Kill poor orphan */ + bt_sock_unlink(&iso_sk_list, sk); + sock_set_flag(sk, SOCK_DEAD); +@@ -2084,7 +2091,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), + skb->len); + conn->rx_len -= skb->len; +- return; ++ break; + + case ISO_END: + skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 9b01eaaa0eb2d6..54ddbb2635e2ff 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -4405,13 +4405,11 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, + return -ENOMEM; + + #ifdef CONFIG_BT_FEATURE_DEBUG +- if (!hdev) { +- flags = bt_dbg_get() ? BIT(0) : 0; ++ flags = bt_dbg_get() ? BIT(0) : 0; + +- memcpy(rp->features[idx].uuid, debug_uuid, 16); +- rp->features[idx].flags = cpu_to_le32(flags); +- idx++; +- } ++ memcpy(rp->features[idx].uuid, debug_uuid, 16); ++ rp->features[idx].flags = cpu_to_le32(flags); ++ idx++; + #endif + + if (hdev && hci_dev_le_state_simultaneous(hdev)) { +diff --git a/net/core/filter.c b/net/core/filter.c +index 7afb7658c38835..b6dbcef649654c 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -9156,13 +9156,17 @@ static bool sock_addr_is_valid_access(int off, int size, + return false; + info->reg_type = PTR_TO_SOCKET; + break; +- default: +- if (type == BPF_READ) { +- if (size != size_default) +- return false; +- } else { ++ case bpf_ctx_range(struct bpf_sock_addr, user_family): ++ case bpf_ctx_range(struct bpf_sock_addr, family): ++ case bpf_ctx_range(struct bpf_sock_addr, type): ++ case bpf_ctx_range(struct bpf_sock_addr, protocol): ++ if (type != BPF_READ) + return false; +- } ++ if (size != size_default) ++ return false; ++ break; ++ default: ++ return false; + } + + return true; +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 4cb0c896caf978..5c848136bc2667 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -77,6 +77,7 @@ static inline struct hlist_head *ping_hashslot(struct ping_table *table, + + int ping_get_port(struct sock *sk, unsigned short ident) + { ++ struct net *net = sock_net(sk); + struct inet_sock *isk, *isk2; + struct hlist_head *hlist; + struct sock *sk2 = NULL; +@@ -90,9 +91,10 @@ int ping_get_port(struct sock *sk, unsigned short ident) + for (i = 0; i < (1L << 16); i++, result++) { + if (!result) + result++; /* avoid zero */ +- hlist = ping_hashslot(&ping_table, sock_net(sk), +- result); ++ hlist = ping_hashslot(&ping_table, net, result); + sk_for_each(sk2, hlist) { ++ if (!net_eq(sock_net(sk2), net)) ++ continue; + isk2 = inet_sk(sk2); + + if (isk2->inet_num == result) +@@ -108,8 +110,10 @@ int ping_get_port(struct sock *sk, unsigned short ident) + if (i >= (1L << 16)) + goto fail; + } else { +- hlist = ping_hashslot(&ping_table, sock_net(sk), ident); ++ hlist = ping_hashslot(&ping_table, net, ident); + sk_for_each(sk2, hlist) { ++ if (!net_eq(sock_net(sk2), net)) ++ continue; + isk2 = inet_sk(sk2); + + /* BUG? Why is this reuse and not reuseaddr? ping.c +@@ -129,7 +133,7 @@ int ping_get_port(struct sock *sk, unsigned short ident) + pr_debug("was not hashed\n"); + sk_add_node_rcu(sk, hlist); + sock_set_flag(sk, SOCK_RCU_FREE); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); ++ sock_prot_inuse_add(net, sk->sk_prot, 1); + } + spin_unlock(&ping_table.lock); + return 0; +@@ -188,6 +192,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ if (!net_eq(sock_net(sk), net)) ++ continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 40a2f172be2cbd..7d824578f217a8 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2786,8 +2786,8 @@ bool tcp_check_oom(struct sock *sk, int shift) + + void __tcp_close(struct sock *sk, long timeout) + { ++ bool data_was_unread = false; + struct sk_buff *skb; +- int data_was_unread = 0; + int state; + + WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK); +@@ -2806,11 +2806,12 @@ void __tcp_close(struct sock *sk, long timeout) + * reader process may not have drained the data yet! + */ + while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { +- u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; ++ u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) +- len--; +- data_was_unread += len; ++ end_seq--; ++ if (after(end_seq, tcp_sk(sk)->copied_seq)) ++ data_was_unread = true; + __kfree_skb(skb); + } + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 210337ef23cf5c..164c6e80498265 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -5219,12 +5219,20 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + } + + rx.sdata = prev_sta->sdata; ++ if (!status->link_valid && prev_sta->sta.mlo) { ++ struct link_sta_info *link_sta; ++ ++ link_sta = link_sta_info_get_bss(rx.sdata, ++ hdr->addr2); ++ if (!link_sta) ++ continue; ++ ++ link_id = link_sta->link_id; ++ } ++ + if (!ieee80211_rx_data_set_sta(&rx, prev_sta, link_id)) + goto out; + +- if (!status->link_valid && prev_sta->sta.mlo) +- continue; +- + ieee80211_prepare_and_rx_handle(&rx, skb, false); + + prev_sta = sta; +@@ -5232,10 +5240,18 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + + if (prev_sta) { + rx.sdata = prev_sta->sdata; +- if (!ieee80211_rx_data_set_sta(&rx, prev_sta, link_id)) +- goto out; ++ if (!status->link_valid && prev_sta->sta.mlo) { ++ struct link_sta_info *link_sta; ++ ++ link_sta = link_sta_info_get_bss(rx.sdata, ++ hdr->addr2); ++ if (!link_sta) ++ goto out; + +- if (!status->link_valid && prev_sta->sta.mlo) ++ link_id = link_sta->link_id; ++ } ++ ++ if (!ieee80211_rx_data_set_sta(&rx, prev_sta, link_id)) + goto out; + + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index c2d88b1b06b872..20b223e6e93b9c 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -62,7 +62,7 @@ struct hbucket { + : jhash_size((htable_bits) - HTABLE_REGION_BITS)) + #define ahash_sizeof_regions(htable_bits) \ + (ahash_numof_locks(htable_bits) * sizeof(struct ip_set_region)) +-#define ahash_region(n, htable_bits) \ ++#define ahash_region(n) \ + ((n) / jhash_size(HTABLE_REGION_BITS)) + #define ahash_bucket_start(h, htable_bits) \ + ((htable_bits) < HTABLE_REGION_BITS ? 0 \ +@@ -701,7 +701,7 @@ mtype_resize(struct ip_set *set, bool retried) + #endif + key = HKEY(data, h->initval, htable_bits); + m = __ipset_dereference(hbucket(t, key)); +- nr = ahash_region(key, htable_bits); ++ nr = ahash_region(key); + if (!m) { + m = kzalloc(sizeof(*m) + + AHASH_INIT_SIZE * dsize, +@@ -851,7 +851,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + rcu_read_lock_bh(); + t = rcu_dereference_bh(h->table); + key = HKEY(value, h->initval, t->htable_bits); +- r = ahash_region(key, t->htable_bits); ++ r = ahash_region(key); + atomic_inc(&t->uref); + elements = t->hregion[r].elements; + maxelem = t->maxelem; +@@ -1049,7 +1049,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + rcu_read_lock_bh(); + t = rcu_dereference_bh(h->table); + key = HKEY(value, h->initval, t->htable_bits); +- r = ahash_region(key, t->htable_bits); ++ r = ahash_region(key); + atomic_inc(&t->uref); + rcu_read_unlock_bh(); + +diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c +index 8182833a358280..d9c3eefe8cbb0c 100644 +--- a/net/netfilter/ipvs/ip_vs_conn.c ++++ b/net/netfilter/ipvs/ip_vs_conn.c +@@ -884,7 +884,7 @@ static void ip_vs_conn_expire(struct timer_list *t) + * conntrack cleanup for the net. + */ + smp_rmb(); +- if (ipvs->enable) ++ if (READ_ONCE(ipvs->enable)) + ip_vs_conn_drop_conntrack(cp); + } + +@@ -1432,7 +1432,7 @@ void ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs) + cond_resched_rcu(); + + /* netns clean up started, abort delayed work */ +- if (!ipvs->enable) ++ if (!READ_ONCE(ipvs->enable)) + break; + } + rcu_read_unlock(); +diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c +index 3230506ae3ffd8..34c4648ba36ece 100644 +--- a/net/netfilter/ipvs/ip_vs_core.c ++++ b/net/netfilter/ipvs/ip_vs_core.c +@@ -1353,9 +1353,6 @@ ip_vs_out_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *stat + if (unlikely(!skb_dst(skb))) + return NF_ACCEPT; + +- if (!ipvs->enable) +- return NF_ACCEPT; +- + ip_vs_fill_iph_skb(af, skb, false, &iph); + #ifdef CONFIG_IP_VS_IPV6 + if (af == AF_INET6) { +@@ -1936,7 +1933,7 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state + return NF_ACCEPT; + } + /* ipvs enabled in this netns ? */ +- if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable)) ++ if (unlikely(sysctl_backup_only(ipvs))) + return NF_ACCEPT; + + ip_vs_fill_iph_skb(af, skb, false, &iph); +@@ -2104,7 +2101,7 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb, + int r; + + /* ipvs enabled in this netns ? */ +- if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable)) ++ if (unlikely(sysctl_backup_only(ipvs))) + return NF_ACCEPT; + + if (state->pf == NFPROTO_IPV4) { +@@ -2291,7 +2288,7 @@ static int __net_init __ip_vs_init(struct net *net) + return -ENOMEM; + + /* Hold the beast until a service is registered */ +- ipvs->enable = 0; ++ WRITE_ONCE(ipvs->enable, 0); + ipvs->net = net; + /* Counters used for creating unique names */ + ipvs->gen = atomic_read(&ipvs_netns_cnt); +@@ -2363,7 +2360,7 @@ static void __net_exit __ip_vs_dev_cleanup_batch(struct list_head *net_list) + ipvs = net_ipvs(net); + ip_vs_unregister_hooks(ipvs, AF_INET); + ip_vs_unregister_hooks(ipvs, AF_INET6); +- ipvs->enable = 0; /* Disable packet reception */ ++ WRITE_ONCE(ipvs->enable, 0); /* Disable packet reception */ + smp_wmb(); + ip_vs_sync_net_cleanup(ipvs); + } +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index ae76542de3e989..c82dcbb4dabce2 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -256,7 +256,7 @@ static void est_reload_work_handler(struct work_struct *work) + struct ip_vs_est_kt_data *kd = ipvs->est_kt_arr[id]; + + /* netns clean up started, abort delayed work */ +- if (!ipvs->enable) ++ if (!READ_ONCE(ipvs->enable)) + goto unlock; + if (!kd) + continue; +@@ -1482,9 +1482,9 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, + + *svc_p = svc; + +- if (!ipvs->enable) { ++ if (!READ_ONCE(ipvs->enable)) { + /* Now there is a service - full throttle */ +- ipvs->enable = 1; ++ WRITE_ONCE(ipvs->enable, 1); + + /* Start estimation for first time */ + ip_vs_est_reload_start(ipvs); +diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c +index c5970ba416aea8..b48d3a09e21742 100644 +--- a/net/netfilter/ipvs/ip_vs_est.c ++++ b/net/netfilter/ipvs/ip_vs_est.c +@@ -230,7 +230,7 @@ static int ip_vs_estimation_kthread(void *data) + void ip_vs_est_reload_start(struct netns_ipvs *ipvs) + { + /* Ignore reloads before first service is added */ +- if (!ipvs->enable) ++ if (!READ_ONCE(ipvs->enable)) + return; + ip_vs_est_stopped_recalc(ipvs); + /* Bump the kthread configuration genid */ +@@ -304,7 +304,7 @@ static int ip_vs_est_add_kthread(struct netns_ipvs *ipvs) + int i; + + if ((unsigned long)ipvs->est_kt_count >= ipvs->est_max_threads && +- ipvs->enable && ipvs->est_max_threads) ++ READ_ONCE(ipvs->enable) && ipvs->est_max_threads) + return -EINVAL; + + mutex_lock(&ipvs->est_mutex); +@@ -341,7 +341,7 @@ static int ip_vs_est_add_kthread(struct netns_ipvs *ipvs) + } + + /* Start kthread tasks only when services are present */ +- if (ipvs->enable && !ip_vs_est_stopped(ipvs)) { ++ if (READ_ONCE(ipvs->enable) && !ip_vs_est_stopped(ipvs)) { + ret = ip_vs_est_kthread_start(ipvs, kd); + if (ret < 0) + goto out; +@@ -484,7 +484,7 @@ int ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats) + struct ip_vs_estimator *est = &stats->est; + int ret; + +- if (!ipvs->est_max_threads && ipvs->enable) ++ if (!ipvs->est_max_threads && READ_ONCE(ipvs->enable)) + ipvs->est_max_threads = ip_vs_est_max_threads(ipvs); + + est->ktid = -1; +@@ -661,7 +661,7 @@ static int ip_vs_est_calc_limits(struct netns_ipvs *ipvs, int *chain_max) + /* Wait for cpufreq frequency transition */ + wait_event_idle_timeout(wq, kthread_should_stop(), + HZ / 50); +- if (!ipvs->enable || kthread_should_stop()) ++ if (!READ_ONCE(ipvs->enable) || kthread_should_stop()) + goto stop; + } + +@@ -679,7 +679,7 @@ static int ip_vs_est_calc_limits(struct netns_ipvs *ipvs, int *chain_max) + rcu_read_unlock(); + local_bh_enable(); + +- if (!ipvs->enable || kthread_should_stop()) ++ if (!READ_ONCE(ipvs->enable) || kthread_should_stop()) + goto stop; + cond_resched(); + +@@ -755,7 +755,7 @@ static void ip_vs_est_calc_phase(struct netns_ipvs *ipvs) + mutex_lock(&ipvs->est_mutex); + for (id = 1; id < ipvs->est_kt_count; id++) { + /* netns clean up started, abort */ +- if (!ipvs->enable) ++ if (!READ_ONCE(ipvs->enable)) + goto unlock2; + kd = ipvs->est_kt_arr[id]; + if (!kd) +@@ -785,7 +785,7 @@ static void ip_vs_est_calc_phase(struct netns_ipvs *ipvs) + id = ipvs->est_kt_count; + + next_kt: +- if (!ipvs->enable || kthread_should_stop()) ++ if (!READ_ONCE(ipvs->enable) || kthread_should_stop()) + goto unlock; + id--; + if (id < 0) +diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c +index ef1f45e43b6308..61d3797fb79954 100644 +--- a/net/netfilter/ipvs/ip_vs_ftp.c ++++ b/net/netfilter/ipvs/ip_vs_ftp.c +@@ -53,6 +53,7 @@ enum { + IP_VS_FTP_EPSV, + }; + ++static bool exiting_module; + /* + * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper + * First port is set to the default port. +@@ -605,7 +606,7 @@ static void __ip_vs_ftp_exit(struct net *net) + { + struct netns_ipvs *ipvs = net_ipvs(net); + +- if (!ipvs) ++ if (!ipvs || !exiting_module) + return; + + unregister_ip_vs_app(ipvs, &ip_vs_ftp); +@@ -627,6 +628,7 @@ static int __init ip_vs_ftp_init(void) + */ + static void __exit ip_vs_ftp_exit(void) + { ++ exiting_module = true; + unregister_pernet_subsys(&ip_vs_ftp_ops); + /* rcu_barrier() is called by netns */ + } +diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c +index 994a0a1efb5890..cb2a672105dc1a 100644 +--- a/net/nfc/nci/ntf.c ++++ b/net/nfc/nci/ntf.c +@@ -27,11 +27,16 @@ + + /* Handle NCI Notification packets */ + +-static void nci_core_reset_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_core_reset_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { + /* Handle NCI 2.x core reset notification */ +- const struct nci_core_reset_ntf *ntf = (void *)skb->data; ++ const struct nci_core_reset_ntf *ntf; ++ ++ if (skb->len < sizeof(struct nci_core_reset_ntf)) ++ return -EINVAL; ++ ++ ntf = (struct nci_core_reset_ntf *)skb->data; + + ndev->nci_ver = ntf->nci_ver; + pr_debug("nci_ver 0x%x, config_status 0x%x\n", +@@ -42,15 +47,22 @@ static void nci_core_reset_ntf_packet(struct nci_dev *ndev, + __le32_to_cpu(ntf->manufact_specific_info); + + nci_req_complete(ndev, NCI_STATUS_OK); ++ ++ return 0; + } + +-static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, +- struct sk_buff *skb) ++static int nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, ++ struct sk_buff *skb) + { +- struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; ++ struct nci_core_conn_credit_ntf *ntf; + struct nci_conn_info *conn_info; + int i; + ++ if (skb->len < sizeof(struct nci_core_conn_credit_ntf)) ++ return -EINVAL; ++ ++ ntf = (struct nci_core_conn_credit_ntf *)skb->data; ++ + pr_debug("num_entries %d\n", ntf->num_entries); + + if (ntf->num_entries > NCI_MAX_NUM_CONN) +@@ -68,7 +80,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, + conn_info = nci_get_conn_info_by_conn_id(ndev, + ntf->conn_entries[i].conn_id); + if (!conn_info) +- return; ++ return 0; + + atomic_add(ntf->conn_entries[i].credits, + &conn_info->credits_cnt); +@@ -77,12 +89,19 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, + /* trigger the next tx */ + if (!skb_queue_empty(&ndev->tx_q)) + queue_work(ndev->tx_wq, &ndev->tx_work); ++ ++ return 0; + } + +-static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_core_generic_error_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { +- __u8 status = skb->data[0]; ++ __u8 status; ++ ++ if (skb->len < 1) ++ return -EINVAL; ++ ++ status = skb->data[0]; + + pr_debug("status 0x%x\n", status); + +@@ -91,12 +110,19 @@ static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, + (the state remains the same) */ + nci_req_complete(ndev, status); + } ++ ++ return 0; + } + +-static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, +- struct sk_buff *skb) ++static int nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, ++ struct sk_buff *skb) + { +- struct nci_core_intf_error_ntf *ntf = (void *) skb->data; ++ struct nci_core_intf_error_ntf *ntf; ++ ++ if (skb->len < sizeof(struct nci_core_intf_error_ntf)) ++ return -EINVAL; ++ ++ ntf = (struct nci_core_intf_error_ntf *)skb->data; + + ntf->conn_id = nci_conn_id(&ntf->conn_id); + +@@ -105,6 +131,8 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, + /* complete the data exchange transaction, if exists */ + if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) + nci_data_exchange_complete(ndev, NULL, ntf->conn_id, -EIO); ++ ++ return 0; + } + + static const __u8 * +@@ -329,13 +357,18 @@ void nci_clear_target_list(struct nci_dev *ndev) + ndev->n_targets = 0; + } + +-static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_rf_discover_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { + struct nci_rf_discover_ntf ntf; +- const __u8 *data = skb->data; ++ const __u8 *data; + bool add_target = true; + ++ if (skb->len < sizeof(struct nci_rf_discover_ntf)) ++ return -EINVAL; ++ ++ data = skb->data; ++ + ntf.rf_discovery_id = *data++; + ntf.rf_protocol = *data++; + ntf.rf_tech_and_mode = *data++; +@@ -390,6 +423,8 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, + nfc_targets_found(ndev->nfc_dev, ndev->targets, + ndev->n_targets); + } ++ ++ return 0; + } + + static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, +@@ -531,14 +566,19 @@ static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev, + return NCI_STATUS_OK; + } + +-static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { + struct nci_conn_info *conn_info; + struct nci_rf_intf_activated_ntf ntf; +- const __u8 *data = skb->data; ++ const __u8 *data; + int err = NCI_STATUS_OK; + ++ if (skb->len < sizeof(struct nci_rf_intf_activated_ntf)) ++ return -EINVAL; ++ ++ data = skb->data; ++ + ntf.rf_discovery_id = *data++; + ntf.rf_interface = *data++; + ntf.rf_protocol = *data++; +@@ -645,7 +685,7 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, + if (err == NCI_STATUS_OK) { + conn_info = ndev->rf_conn_info; + if (!conn_info) +- return; ++ return 0; + + conn_info->max_pkt_payload_len = ntf.max_data_pkt_payload_size; + conn_info->initial_num_credits = ntf.initial_num_credits; +@@ -691,19 +731,26 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, + pr_err("error when signaling tm activation\n"); + } + } ++ ++ return 0; + } + +-static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { + const struct nci_conn_info *conn_info; +- const struct nci_rf_deactivate_ntf *ntf = (void *)skb->data; ++ const struct nci_rf_deactivate_ntf *ntf; ++ ++ if (skb->len < sizeof(struct nci_rf_deactivate_ntf)) ++ return -EINVAL; ++ ++ ntf = (struct nci_rf_deactivate_ntf *)skb->data; + + pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); + + conn_info = ndev->rf_conn_info; + if (!conn_info) +- return; ++ return 0; + + /* drop tx data queue */ + skb_queue_purge(&ndev->tx_q); +@@ -735,14 +782,20 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, + } + + nci_req_complete(ndev, NCI_STATUS_OK); ++ ++ return 0; + } + +-static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, +- const struct sk_buff *skb) ++static int nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, ++ const struct sk_buff *skb) + { + u8 status = NCI_STATUS_OK; +- const struct nci_nfcee_discover_ntf *nfcee_ntf = +- (struct nci_nfcee_discover_ntf *)skb->data; ++ const struct nci_nfcee_discover_ntf *nfcee_ntf; ++ ++ if (skb->len < sizeof(struct nci_nfcee_discover_ntf)) ++ return -EINVAL; ++ ++ nfcee_ntf = (struct nci_nfcee_discover_ntf *)skb->data; + + /* NFCForum NCI 9.2.1 HCI Network Specific Handling + * If the NFCC supports the HCI Network, it SHALL return one, +@@ -753,6 +806,8 @@ static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, + ndev->cur_params.id = nfcee_ntf->nfcee_id; + + nci_req_complete(ndev, status); ++ ++ return 0; + } + + void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) +@@ -779,35 +834,43 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) + + switch (ntf_opcode) { + case NCI_OP_CORE_RESET_NTF: +- nci_core_reset_ntf_packet(ndev, skb); ++ if (nci_core_reset_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_CORE_CONN_CREDITS_NTF: +- nci_core_conn_credits_ntf_packet(ndev, skb); ++ if (nci_core_conn_credits_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_CORE_GENERIC_ERROR_NTF: +- nci_core_generic_error_ntf_packet(ndev, skb); ++ if (nci_core_generic_error_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_CORE_INTF_ERROR_NTF: +- nci_core_conn_intf_error_ntf_packet(ndev, skb); ++ if (nci_core_conn_intf_error_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_RF_DISCOVER_NTF: +- nci_rf_discover_ntf_packet(ndev, skb); ++ if (nci_rf_discover_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_RF_INTF_ACTIVATED_NTF: +- nci_rf_intf_activated_ntf_packet(ndev, skb); ++ if (nci_rf_intf_activated_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_RF_DEACTIVATE_NTF: +- nci_rf_deactivate_ntf_packet(ndev, skb); ++ if (nci_rf_deactivate_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_NFCEE_DISCOVER_NTF: +- nci_nfcee_discover_ntf_packet(ndev, skb); ++ if (nci_nfcee_discover_ntf_packet(ndev, skb)) ++ goto end; + break; + + case NCI_OP_RF_NFCEE_ACTION_NTF: +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index cf30bd649e2704..d063b63516f818 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -724,7 +724,7 @@ svcauth_gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci, + rqstp->rq_auth_stat = rpc_autherr_badverf; + return SVC_DENIED; + } +- if (flavor != RPC_AUTH_GSS) { ++ if (flavor != RPC_AUTH_GSS || checksum.len < XDR_UNIT) { + rqstp->rq_auth_stat = rpc_autherr_badverf; + return SVC_DENIED; + } +diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c +index b5b0d43bb8dcdd..c3f2717aebf254 100644 +--- a/sound/pci/lx6464es/lx_core.c ++++ b/sound/pci/lx6464es/lx_core.c +@@ -316,7 +316,7 @@ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh) + /* low-level dsp access */ + int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) + { +- u16 ret; ++ int ret; + + mutex_lock(&chip->msg_lock); + +@@ -330,10 +330,10 @@ int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) + + int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) + { +- u16 ret = 0; + u32 freq_raw = 0; + u32 freq = 0; + u32 frequency = 0; ++ int ret; + + mutex_lock(&chip->msg_lock); + +diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c +index fe222c4b74c006..c04be088f17a2b 100644 +--- a/sound/soc/codecs/wcd934x.c ++++ b/sound/soc/codecs/wcd934x.c +@@ -5858,6 +5858,13 @@ static const struct snd_soc_component_driver wcd934x_component_drv = { + .endianness = 1, + }; + ++static void wcd934x_put_device_action(void *data) ++{ ++ struct device *dev = data; ++ ++ put_device(dev); ++} ++ + static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd) + { + struct device *dev = &wcd->sdev->dev; +@@ -5878,11 +5885,13 @@ static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd) + } + + slim_get_logical_addr(wcd->sidev); +- wcd->if_regmap = regmap_init_slimbus(wcd->sidev, ++ wcd->if_regmap = devm_regmap_init_slimbus(wcd->sidev, + &wcd934x_ifc_regmap_config); +- if (IS_ERR(wcd->if_regmap)) ++ if (IS_ERR(wcd->if_regmap)) { ++ put_device(&wcd->sidev->dev); + return dev_err_probe(dev, PTR_ERR(wcd->if_regmap), + "Failed to allocate ifc register map\n"); ++ } + + of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate", + &wcd->dmic_sample_rate); +@@ -5926,6 +5935,10 @@ static int wcd934x_codec_probe(struct platform_device *pdev) + return ret; + } + ++ ret = devm_add_action_or_reset(dev, wcd934x_put_device_action, &wcd->sidev->dev); ++ if (ret) ++ return ret; ++ + /* set default rate 9P6MHz */ + regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG, + WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, +diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c +index 7a30d2d36f199b..fbd7e1f0783fd9 100644 +--- a/sound/soc/intel/boards/bytcht_es8316.c ++++ b/sound/soc/intel/boards/bytcht_es8316.c +@@ -46,7 +46,8 @@ enum { + BYT_CHT_ES8316_INTMIC_IN2_MAP, + }; + +-#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & GENMASK(3, 0)) ++#define BYT_CHT_ES8316_MAP_MASK GENMASK(3, 0) ++#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & BYT_CHT_ES8316_MAP_MASK) + #define BYT_CHT_ES8316_SSP0 BIT(16) + #define BYT_CHT_ES8316_MONO_SPEAKER BIT(17) + #define BYT_CHT_ES8316_JD_INVERTED BIT(18) +@@ -59,10 +60,23 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + + static void log_quirks(struct device *dev) + { +- if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP) ++ int map; ++ ++ map = BYT_CHT_ES8316_MAP(quirk); ++ switch (map) { ++ case BYT_CHT_ES8316_INTMIC_IN1_MAP: + dev_info(dev, "quirk IN1_MAP enabled"); +- if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP) ++ break; ++ case BYT_CHT_ES8316_INTMIC_IN2_MAP: + dev_info(dev, "quirk IN2_MAP enabled"); ++ break; ++ default: ++ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to INTMIC_IN1_MAP\n", map); ++ quirk &= ~BYT_CHT_ES8316_MAP_MASK; ++ quirk |= BYT_CHT_ES8316_INTMIC_IN1_MAP; ++ break; ++ } ++ + if (quirk & BYT_CHT_ES8316_SSP0) + dev_info(dev, "quirk SSP0 enabled"); + if (quirk & BYT_CHT_ES8316_MONO_SPEAKER) +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 6a85e8fdcae646..beca466dd468ec 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -68,7 +68,8 @@ enum { + BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13), + }; + +-#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0)) ++#define BYT_RT5640_MAP_MASK GENMASK(3, 0) ++#define BYT_RT5640_MAP(quirk) ((quirk) & BYT_RT5640_MAP_MASK) + #define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4) + #define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8) + #define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13) +@@ -140,7 +141,9 @@ static void log_quirks(struct device *dev) + dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n"); + break; + default: +- dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); ++ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC1_MAP\n", map); ++ byt_rt5640_quirk &= ~BYT_RT5640_MAP_MASK; ++ byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP; + break; + } + if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1) +diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c +index 805afaf47b2904..2abe47303ecdb3 100644 +--- a/sound/soc/intel/boards/bytcr_rt5651.c ++++ b/sound/soc/intel/boards/bytcr_rt5651.c +@@ -58,7 +58,8 @@ enum { + BYT_RT5651_OVCD_SF_1P5 = (RT5651_OVCD_SF_1P5 << 13), + }; + +-#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(3, 0)) ++#define BYT_RT5651_MAP_MASK GENMASK(3, 0) ++#define BYT_RT5651_MAP(quirk) ((quirk) & BYT_RT5651_MAP_MASK) + #define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4) + #define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8) + #define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13) +@@ -100,14 +101,29 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + + static void log_quirks(struct device *dev) + { +- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP) ++ int map; ++ ++ map = BYT_RT5651_MAP(byt_rt5651_quirk); ++ switch (map) { ++ case BYT_RT5651_DMIC_MAP: + dev_info(dev, "quirk DMIC_MAP enabled"); +- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP) ++ break; ++ case BYT_RT5651_IN1_MAP: + dev_info(dev, "quirk IN1_MAP enabled"); +- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP) ++ break; ++ case BYT_RT5651_IN2_MAP: + dev_info(dev, "quirk IN2_MAP enabled"); +- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_IN2_MAP) ++ break; ++ case BYT_RT5651_IN1_IN2_MAP: + dev_info(dev, "quirk IN1_IN2_MAP enabled"); ++ break; ++ default: ++ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC_MAP\n", map); ++ byt_rt5651_quirk &= ~BYT_RT5651_MAP_MASK; ++ byt_rt5651_quirk |= BYT_RT5651_DMIC_MAP; ++ break; ++ } ++ + if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { + dev_info(dev, "quirk realtek,jack-detect-source %ld\n", + BYT_RT5651_JDSRC(byt_rt5651_quirk)); +diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c +index 0e5ae7fa0ef7a7..0db8c4b2f0ff2e 100644 +--- a/sound/soc/sof/ipc3-topology.c ++++ b/sound/soc/sof/ipc3-topology.c +@@ -2394,11 +2394,6 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif + if (ret < 0) + return ret; + +- /* free all the scheduler widgets now */ +- ret = sof_ipc3_free_widgets_in_list(sdev, true, &dyn_widgets, verify); +- if (ret < 0) +- return ret; +- + /* + * Tear down all pipelines associated with PCMs that did not get suspended + * and unset the prepare flag so that they can be set up again during resume. +@@ -2414,6 +2409,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif + } + } + ++ /* free all the scheduler widgets now. This will also power down the secondary cores */ ++ ret = sof_ipc3_free_widgets_in_list(sdev, true, &dyn_widgets, verify); ++ if (ret < 0) ++ return ret; ++ + list_for_each_entry(sroute, &sdev->route_list, list) + sroute->setup = false; + +diff --git a/tools/include/nolibc/std.h b/tools/include/nolibc/std.h +index a9d8b5b51f37f8..f24953f8b949c1 100644 +--- a/tools/include/nolibc/std.h ++++ b/tools/include/nolibc/std.h +@@ -33,6 +33,6 @@ typedef unsigned long nlink_t; + typedef signed long off_t; + typedef signed long blksize_t; + typedef signed long blkcnt_t; +-typedef __kernel_old_time_t time_t; ++typedef __kernel_time_t time_t; + + #endif /* _NOLIBC_STD_H */ +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index aefbfa2df6207c..95f2ffefff3ff7 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -5013,6 +5013,16 @@ static bool map_is_reuse_compat(const struct bpf_map *map, int map_fd) + return false; + } + ++ /* ++ * bpf_get_map_info_by_fd() for DEVMAP will always return flags with ++ * BPF_F_RDONLY_PROG set, but it generally is not set at map creation time. ++ * Thus, ignore the BPF_F_RDONLY_PROG flag in the flags returned from ++ * bpf_get_map_info_by_fd() when checking for compatibility with an ++ * existing DEVMAP. ++ */ ++ if (map->def.type == BPF_MAP_TYPE_DEVMAP || map->def.type == BPF_MAP_TYPE_DEVMAP_HASH) ++ map_info.map_flags &= ~BPF_F_RDONLY_PROG; ++ + return (map_info.type == map->def.type && + map_info.key_size == map->def.key_size && + map_info.value_size == map->def.value_size && +diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c +index 3eba10c1e3e8f6..e711a2584143f5 100644 +--- a/tools/testing/nvdimm/test/ndtest.c ++++ b/tools/testing/nvdimm/test/ndtest.c +@@ -845,11 +845,22 @@ static int ndtest_probe(struct platform_device *pdev) + + p->dcr_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); ++ if (!p->dcr_dma) { ++ rc = -ENOMEM; ++ goto err; ++ } + p->label_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); ++ if (!p->label_dma) { ++ rc = -ENOMEM; ++ goto err; ++ } + p->dimm_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); +- ++ if (!p->dimm_dma) { ++ rc = -ENOMEM; ++ goto err; ++ } + rc = ndtest_nvdimm_init(p); + if (rc) + goto err; +diff --git a/tools/testing/selftests/arm64/pauth/exec_target.c b/tools/testing/selftests/arm64/pauth/exec_target.c +index 4435600ca400dd..e597861b26d6bf 100644 +--- a/tools/testing/selftests/arm64/pauth/exec_target.c ++++ b/tools/testing/selftests/arm64/pauth/exec_target.c +@@ -13,7 +13,12 @@ int main(void) + unsigned long hwcaps; + size_t val; + +- fread(&val, sizeof(size_t), 1, stdin); ++ size_t size = fread(&val, sizeof(size_t), 1, stdin); ++ ++ if (size != 1) { ++ fprintf(stderr, "Could not read input from stdin\n"); ++ return EXIT_FAILURE; ++ } + + /* don't try to execute illegal (unimplemented) instructions) caller + * should have checked this and keep worker simple +diff --git a/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c b/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c +index 540181c115a85a..ef00d38b0a8d24 100644 +--- a/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c ++++ b/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c +@@ -23,7 +23,6 @@ struct { + + struct { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); +- __uint(max_entries, 2); + __type(key, int); + __type(value, __u32); + } perf_event_map SEC(".maps"); +diff --git a/tools/testing/selftests/bpf/test_tcpnotify_user.c b/tools/testing/selftests/bpf/test_tcpnotify_user.c +index 595194453ff8f8..35b4893ccdf8ae 100644 +--- a/tools/testing/selftests/bpf/test_tcpnotify_user.c ++++ b/tools/testing/selftests/bpf/test_tcpnotify_user.c +@@ -15,20 +15,18 @@ + #include + #include + #include +-#include + #include +-#include + +-#include "bpf_util.h" + #include "cgroup_helpers.h" + + #include "test_tcpnotify.h" +-#include "trace_helpers.h" + #include "testing_helpers.h" + + #define SOCKET_BUFFER_SIZE (getpagesize() < 8192L ? getpagesize() : 8192L) + + pthread_t tid; ++static bool exit_thread; ++ + int rx_callbacks; + + static void dummyfn(void *ctx, int cpu, void *data, __u32 size) +@@ -45,7 +43,7 @@ void tcp_notifier_poller(struct perf_buffer *pb) + { + int err; + +- while (1) { ++ while (!exit_thread) { + err = perf_buffer__poll(pb, 100); + if (err < 0 && err != -EINTR) { + printf("failed perf_buffer__poll: %d\n", err); +@@ -78,15 +76,10 @@ int main(int argc, char **argv) + int error = EXIT_FAILURE; + struct bpf_object *obj; + char test_script[80]; +- cpu_set_t cpuset; + __u32 key = 0; + + libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + +- CPU_ZERO(&cpuset); +- CPU_SET(0, &cpuset); +- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); +- + cg_fd = cgroup_setup_and_join(cg_path); + if (cg_fd < 0) + goto err; +@@ -151,6 +144,13 @@ int main(int argc, char **argv) + + sleep(10); + ++ exit_thread = true; ++ int ret = pthread_join(tid, NULL); ++ if (ret) { ++ printf("FAILED: pthread_join\n"); ++ goto err; ++ } ++ + if (verify_result(&g)) { + printf("FAILED: Wrong stats Expected %d calls, got %d\n", + g.ncalls, rx_callbacks); +diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c +index 4aaafbfc2f9735..a019de995e5dfd 100644 +--- a/tools/testing/selftests/nolibc/nolibc-test.c ++++ b/tools/testing/selftests/nolibc/nolibc-test.c +@@ -176,8 +176,8 @@ int expect_zr(int expr, int llen) + } + + +-#define EXPECT_NZ(cond, expr, val) \ +- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen; } while (0) ++#define EXPECT_NZ(cond, expr) \ ++ do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen); } while (0) + + static __attribute__((unused)) + int expect_nz(int expr, int llen) +diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c +index a1f506ba557864..4f09c5db0c7f30 100644 +--- a/tools/testing/selftests/watchdog/watchdog-test.c ++++ b/tools/testing/selftests/watchdog/watchdog-test.c +@@ -332,6 +332,12 @@ int main(int argc, char *argv[]) + if (oneshot) + goto end; + ++ /* Check if WDIOF_KEEPALIVEPING is supported */ ++ if (!(info.options & WDIOF_KEEPALIVEPING)) { ++ printf("WDIOC_KEEPALIVE not supported by this device\n"); ++ goto end; ++ } ++ + printf("Watchdog Ticking Away!\n"); + + /* diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.112-113.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.112-113.patch new file mode 100644 index 000000000..48d54ba46 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.112-113.patch @@ -0,0 +1,7576 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 60d48ebbc2cb00..fff3ca50c6c26c 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -5638,6 +5638,9 @@ + + rootflags= [KNL] Set root filesystem mount option string + ++ initramfs_options= [KNL] ++ Specify mount options for for the initramfs mount. ++ + rootfstype= [KNL] Set root filesystem type + + rootwait [KNL] Wait (indefinitely) for root device to show up. +diff --git a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml +index 5ac994b3c0aa15..b304bc5a08c402 100644 +--- a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml ++++ b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml +@@ -57,11 +57,24 @@ required: + - clocks + - clock-names + - '#phy-cells' +- - power-domains + - resets + - reset-names + - rockchip,grf + ++allOf: ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - rockchip,px30-csi-dphy ++ - rockchip,rk1808-csi-dphy ++ - rockchip,rk3326-csi-dphy ++ - rockchip,rk3368-csi-dphy ++ then: ++ required: ++ - power-domains ++ + additionalProperties: false + + examples: +diff --git a/Makefile b/Makefile +index 64d76baa0e0c9b..ab277ff8764317 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 112 ++SUBLEVEL = 113 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c +index c907478be196ed..4abb86dc98fdac 100644 +--- a/arch/arm/mach-omap2/pm33xx-core.c ++++ b/arch/arm/mach-omap2/pm33xx-core.c +@@ -388,12 +388,15 @@ static int __init amx3_idle_init(struct device_node *cpu_node, int cpu) + if (!state_node) + break; + +- if (!of_device_is_available(state_node)) ++ if (!of_device_is_available(state_node)) { ++ of_node_put(state_node); + continue; ++ } + + if (i == CPUIDLE_STATE_MAX) { + pr_warn("%s: cpuidle states reached max possible\n", + __func__); ++ of_node_put(state_node); + break; + } + +@@ -403,6 +406,7 @@ static int __init amx3_idle_init(struct device_node *cpu_node, int cpu) + states[state_count].wfi_flags |= WFI_FLAG_WAKE_M3 | + WFI_FLAG_FLUSH_CACHE; + ++ of_node_put(state_node); + state_count++; + } + +diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi +index 6f5f96853ba1c2..701e139a9cbd06 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -1529,6 +1529,8 @@ mdss: display-subsystem@1a00000 { + + interrupts = ; + ++ resets = <&gcc GCC_MDSS_BCR>; ++ + interrupt-controller; + #interrupt-cells = <1>; + +diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi +index c844e01f9aa15b..86432ed25b23a1 100644 +--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi +@@ -1210,6 +1210,8 @@ mdss: display-subsystem@1a00000 { + + power-domains = <&gcc MDSS_GDSC>; + ++ resets = <&gcc GCC_MDSS_BCR>; ++ + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index 64ea9d73d970a9..fa91e2036dd56f 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -5208,11 +5208,11 @@ slimbam: dma-controller@17184000 { + compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; + qcom,controlled-remotely; + reg = <0 0x17184000 0 0x2a000>; +- num-channels = <31>; ++ num-channels = <23>; + interrupts = ; + #dma-cells = <1>; + qcom,ee = <1>; +- qcom,num-ees = <2>; ++ qcom,num-ees = <4>; + iommus = <&apps_smmu 0x1806 0x0>; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +index 1497f7c8adfaf4..dfdc6e659cc464 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +@@ -185,7 +185,7 @@ secure_proxy_sa3: mailbox@43600000 { + + main_pmx0: pinctrl@f4000 { + compatible = "pinctrl-single"; +- reg = <0x00 0xf4000 0x00 0x2ac>; ++ reg = <0x00 0xf4000 0x00 0x25c>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index 2ce9ef9d924aac..4561c4a670afbd 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -2174,17 +2174,21 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) + #ifdef CONFIG_ARM64_MTE + static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) + { ++ static bool cleared_zero_page = false; ++ + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0); + + mte_cpu_setup(); + + /* + * Clear the tags in the zero page. This needs to be done via the +- * linear map which has the Tagged attribute. ++ * linear map which has the Tagged attribute. Since this page is ++ * always mapped as pte_special(), set_pte_at() will not attempt to ++ * clear the tags or set PG_mte_tagged. + */ +- if (try_page_mte_tagging(ZERO_PAGE(0))) { ++ if (!cleared_zero_page) { ++ cleared_zero_page = true; + mte_clear_page_tags(lm_alias(empty_zero_page)); +- set_page_mte_tagged(ZERO_PAGE(0)); + } + + kasan_init_hw_tags_cpu(); +diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c +index 4edecaac8f919a..84ea9c50c076f0 100644 +--- a/arch/arm64/kernel/mte.c ++++ b/arch/arm64/kernel/mte.c +@@ -428,7 +428,8 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr, + put_page(page); + break; + } +- WARN_ON_ONCE(!page_mte_tagged(page)); ++ ++ WARN_ON_ONCE(!page_mte_tagged(page) && !is_zero_page(page)); + + /* limit access to the end of the page */ + offset = offset_in_page(addr); +diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c +index 70b91a8c6bb3f3..c0942cce3b6878 100644 +--- a/arch/arm64/kernel/probes/kprobes.c ++++ b/arch/arm64/kernel/probes/kprobes.c +@@ -131,9 +131,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) + + void *alloc_insn_page(void) + { +- return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, ++ void *addr; ++ ++ addr = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, + GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS, + NUMA_NO_NODE, __builtin_return_address(0)); ++ if (!addr) ++ return NULL; ++ set_memory_rox((unsigned long)addr, 1); ++ return addr; + } + + /* arm kprobe: install breakpoint in text */ +diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c +index 655dc2b1616f2c..31be0d00976e22 100644 +--- a/arch/loongarch/kernel/setup.c ++++ b/arch/loongarch/kernel/setup.c +@@ -363,10 +363,9 @@ void __init platform_init(void) + arch_reserve_vmcore(); + arch_parse_crashkernel(); + +-#ifdef CONFIG_ACPI_TABLE_UPGRADE +- acpi_table_upgrade(); +-#endif + #ifdef CONFIG_ACPI ++ acpi_table_upgrade(); ++ acpi_gbl_use_global_lock = false; + acpi_gbl_use_default_register_widths = false; + acpi_boot_table_init(); + #endif +diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h +index 82d1148c6379a5..74b4027a4e8083 100644 +--- a/arch/parisc/include/uapi/asm/ioctls.h ++++ b/arch/parisc/include/uapi/asm/ioctls.h +@@ -10,10 +10,10 @@ + #define TCSETS _IOW('T', 17, struct termios) /* TCSETATTR */ + #define TCSETSW _IOW('T', 18, struct termios) /* TCSETATTRD */ + #define TCSETSF _IOW('T', 19, struct termios) /* TCSETATTRF */ +-#define TCGETA _IOR('T', 1, struct termio) +-#define TCSETA _IOW('T', 2, struct termio) +-#define TCSETAW _IOW('T', 3, struct termio) +-#define TCSETAF _IOW('T', 4, struct termio) ++#define TCGETA 0x40125401 ++#define TCSETA 0x80125402 ++#define TCSETAW 0x80125403 ++#define TCSETAF 0x80125404 + #define TCSBRK _IO('T', 5) + #define TCXONC _IO('T', 6) + #define TCFLSH _IO('T', 7) +diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c +index 69d65ffab31263..03165c82dfdbd9 100644 +--- a/arch/parisc/lib/memcpy.c ++++ b/arch/parisc/lib/memcpy.c +@@ -41,7 +41,6 @@ unsigned long raw_copy_from_user(void *dst, const void __user *src, + mtsp(get_kernel_space(), SR_TEMP2); + + /* Check region is user accessible */ +- if (start) + while (start < end) { + if (!prober_user(SR_TEMP1, start)) { + newlen = (start - (unsigned long) src); +diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c +index 28fac477007316..5337ad8a2e340f 100644 +--- a/arch/powerpc/platforms/powernv/pci-ioda.c ++++ b/arch/powerpc/platforms/powernv/pci-ioda.c +@@ -1895,7 +1895,7 @@ static int pnv_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + return 0; + + out: +- irq_domain_free_irqs_parent(domain, virq, i - 1); ++ irq_domain_free_irqs_parent(domain, virq, i); + msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, nr_irqs); + return ret; + } +diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c +index fdcf10cd4d1270..b53f817fc421f8 100644 +--- a/arch/powerpc/platforms/pseries/msi.c ++++ b/arch/powerpc/platforms/pseries/msi.c +@@ -587,7 +587,7 @@ static int pseries_irq_domain_alloc(struct irq_domain *domain, unsigned int virq + + out: + /* TODO: handle RTAS cleanup in ->msi_finish() ? */ +- irq_domain_free_irqs_parent(domain, virq, i - 1); ++ irq_domain_free_irqs_parent(domain, virq, i); + return ret; + } + +diff --git a/arch/s390/net/bpf_jit.h b/arch/s390/net/bpf_jit.h +deleted file mode 100644 +index 7822ea92e54afd..00000000000000 +--- a/arch/s390/net/bpf_jit.h ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * BPF Jit compiler defines +- * +- * Copyright IBM Corp. 2012,2015 +- * +- * Author(s): Martin Schwidefsky +- * Michael Holzheu +- */ +- +-#ifndef __ARCH_S390_NET_BPF_JIT_H +-#define __ARCH_S390_NET_BPF_JIT_H +- +-#ifndef __ASSEMBLY__ +- +-#include +-#include +- +-#endif /* __ASSEMBLY__ */ +- +-/* +- * Stackframe layout (packed stack): +- * +- * ^ high +- * +---------------+ | +- * | old backchain | | +- * +---------------+ | +- * | r15 - r6 | | +- * +---------------+ | +- * | 4 byte align | | +- * | tail_call_cnt | | +- * BFP -> +===============+ | +- * | | | +- * | BPF stack | | +- * | | | +- * R15+160 -> +---------------+ | +- * | new backchain | | +- * R15+152 -> +---------------+ | +- * | + 152 byte SA | | +- * R15 -> +---------------+ + low +- * +- * We get 160 bytes stack space from calling function, but only use +- * 12 * 8 byte for old backchain, r15..r6, and tail_call_cnt. +- * +- * The stack size used by the BPF program ("BPF stack" above) is passed +- * via "aux->stack_depth". +- */ +-#define STK_SPACE_ADD (160) +-#define STK_160_UNUSED (160 - 12 * 8) +-#define STK_OFF (STK_SPACE_ADD - STK_160_UNUSED) +- +-#define STK_OFF_R6 (160 - 11 * 8) /* Offset of r6 on stack */ +-#define STK_OFF_TCCNT (160 - 12 * 8) /* Offset of tail_call_cnt on stack */ +- +-#endif /* __ARCH_S390_NET_BPF_JIT_H */ +diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c +index 2d8facfd4e4252..5a64d34a37482b 100644 +--- a/arch/s390/net/bpf_jit_comp.c ++++ b/arch/s390/net/bpf_jit_comp.c +@@ -31,11 +31,10 @@ + #include + #include + #include +-#include "bpf_jit.h" + + struct bpf_jit { + u32 seen; /* Flags to remember seen eBPF instructions */ +- u32 seen_reg[16]; /* Array to remember which registers are used */ ++ u16 seen_regs; /* Mask to remember which registers are used */ + u32 *addrs; /* Array with relative instruction addresses */ + u8 *prg_buf; /* Start of program */ + int size; /* Size of program and literal pool */ +@@ -53,6 +52,7 @@ struct bpf_jit { + int excnt; /* Number of exception table entries */ + int prologue_plt_ret; /* Return address for prologue hotpatch PLT */ + int prologue_plt; /* Start of prologue hotpatch PLT */ ++ u32 frame_off; /* Offset of struct bpf_prog from %r15 */ + }; + + #define SEEN_MEM BIT(0) /* use mem[] for temporary storage */ +@@ -118,8 +118,8 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) + { + u32 r1 = reg2hex[b1]; + +- if (r1 >= 6 && r1 <= 15 && !jit->seen_reg[r1]) +- jit->seen_reg[r1] = 1; ++ if (r1 >= 6 && r1 <= 15) ++ jit->seen_regs |= (1 << r1); + } + + #define REG_SET_SEEN(b1) \ +@@ -127,8 +127,6 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) + reg_set_seen(jit, b1); \ + }) + +-#define REG_SEEN(b1) jit->seen_reg[reg2hex[(b1)]] +- + /* + * EMIT macros for code generation + */ +@@ -400,12 +398,26 @@ static void jit_fill_hole(void *area, unsigned int size) + memset(area, 0, size); + } + ++/* ++ * Caller-allocated part of the frame. ++ * Thanks to packed stack, its otherwise unused initial part can be used for ++ * the BPF stack and for the next frame. ++ */ ++struct prog_frame { ++ u64 unused[8]; ++ /* BPF stack starts here and grows towards 0 */ ++ u32 tail_call_cnt; ++ u32 pad; ++ u64 r6[10]; /* r6 - r15 */ ++ u64 backchain; ++} __packed; ++ + /* + * Save registers from "rs" (register start) to "re" (register end) on stack + */ + static void save_regs(struct bpf_jit *jit, u32 rs, u32 re) + { +- u32 off = STK_OFF_R6 + (rs - 6) * 8; ++ u32 off = offsetof(struct prog_frame, r6) + (rs - 6) * 8; + + if (rs == re) + /* stg %rs,off(%r15) */ +@@ -418,12 +430,9 @@ static void save_regs(struct bpf_jit *jit, u32 rs, u32 re) + /* + * Restore registers from "rs" (register start) to "re" (register end) on stack + */ +-static void restore_regs(struct bpf_jit *jit, u32 rs, u32 re, u32 stack_depth) ++static void restore_regs(struct bpf_jit *jit, u32 rs, u32 re) + { +- u32 off = STK_OFF_R6 + (rs - 6) * 8; +- +- if (jit->seen & SEEN_STACK) +- off += STK_OFF + stack_depth; ++ u32 off = jit->frame_off + offsetof(struct prog_frame, r6) + (rs - 6) * 8; + + if (rs == re) + /* lg %rs,off(%r15) */ +@@ -436,12 +445,12 @@ static void restore_regs(struct bpf_jit *jit, u32 rs, u32 re, u32 stack_depth) + /* + * Return first seen register (from start) + */ +-static int get_start(struct bpf_jit *jit, int start) ++static int get_start(u16 seen_regs, int start) + { + int i; + + for (i = start; i <= 15; i++) { +- if (jit->seen_reg[i]) ++ if (seen_regs & (1 << i)) + return i; + } + return 0; +@@ -450,15 +459,15 @@ static int get_start(struct bpf_jit *jit, int start) + /* + * Return last seen register (from start) (gap >= 2) + */ +-static int get_end(struct bpf_jit *jit, int start) ++static int get_end(u16 seen_regs, int start) + { + int i; + + for (i = start; i < 15; i++) { +- if (!jit->seen_reg[i] && !jit->seen_reg[i + 1]) ++ if (!(seen_regs & (3 << i))) + return i - 1; + } +- return jit->seen_reg[15] ? 15 : 14; ++ return (seen_regs & (1 << 15)) ? 15 : 14; + } + + #define REGS_SAVE 1 +@@ -467,8 +476,9 @@ static int get_end(struct bpf_jit *jit, int start) + * Save and restore clobbered registers (6-15) on stack. + * We save/restore registers in chunks with gap >= 2 registers. + */ +-static void save_restore_regs(struct bpf_jit *jit, int op, u32 stack_depth) ++static void save_restore_regs(struct bpf_jit *jit, int op, u16 extra_regs) + { ++ u16 seen_regs = jit->seen_regs | extra_regs; + const int last = 15, save_restore_size = 6; + int re = 6, rs; + +@@ -482,14 +492,14 @@ static void save_restore_regs(struct bpf_jit *jit, int op, u32 stack_depth) + } + + do { +- rs = get_start(jit, re); ++ rs = get_start(seen_regs, re); + if (!rs) + break; +- re = get_end(jit, rs + 1); ++ re = get_end(seen_regs, rs + 1); + if (op == REGS_SAVE) + save_regs(jit, rs, re); + else +- restore_regs(jit, rs, re, stack_depth); ++ restore_regs(jit, rs, re); + re++; + } while (re <= last); + } +@@ -554,11 +564,12 @@ static void bpf_jit_plt(struct bpf_plt *plt, void *ret, void *target) + * Emit function prologue + * + * Save registers and create stack frame if necessary. +- * See stack frame layout description in "bpf_jit.h"! ++ * Stack frame layout is described by struct prog_frame. + */ +-static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp, +- u32 stack_depth) ++static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp) + { ++ BUILD_BUG_ON(sizeof(struct prog_frame) != STACK_FRAME_OVERHEAD); ++ + /* No-op for hotpatching */ + /* brcl 0,prologue_plt */ + EMIT6_PCREL_RILC(0xc0040000, 0, jit->prologue_plt); +@@ -566,8 +577,9 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp, + + if (fp->aux->func_idx == 0) { + /* Initialize the tail call counter in the main program. */ +- /* xc STK_OFF_TCCNT(4,%r15),STK_OFF_TCCNT(%r15) */ +- _EMIT6(0xd703f000 | STK_OFF_TCCNT, 0xf000 | STK_OFF_TCCNT); ++ /* xc tail_call_cnt(4,%r15),tail_call_cnt(%r15) */ ++ _EMIT6(0xd703f000 | offsetof(struct prog_frame, tail_call_cnt), ++ 0xf000 | offsetof(struct prog_frame, tail_call_cnt)); + } else { + /* + * Skip the tail call counter initialization in subprograms. +@@ -579,7 +591,7 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp, + /* Tail calls have to skip above initialization */ + jit->tail_call_start = jit->prg; + /* Save registers */ +- save_restore_regs(jit, REGS_SAVE, stack_depth); ++ save_restore_regs(jit, REGS_SAVE, 0); + /* Setup literal pool */ + if (is_first_pass(jit) || (jit->seen & SEEN_LITERAL)) { + if (!is_first_pass(jit) && +@@ -597,13 +609,15 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp, + if (is_first_pass(jit) || (jit->seen & SEEN_STACK)) { + /* lgr %w1,%r15 (backchain) */ + EMIT4(0xb9040000, REG_W1, REG_15); +- /* la %bfp,STK_160_UNUSED(%r15) (BPF frame pointer) */ +- EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, STK_160_UNUSED); +- /* aghi %r15,-STK_OFF */ +- EMIT4_IMM(0xa70b0000, REG_15, -(STK_OFF + stack_depth)); +- /* stg %w1,152(%r15) (backchain) */ ++ /* la %bfp,unused_end(%r15) (BPF frame pointer) */ ++ EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, ++ offsetofend(struct prog_frame, unused)); ++ /* aghi %r15,-frame_off */ ++ EMIT4_IMM(0xa70b0000, REG_15, -jit->frame_off); ++ /* stg %w1,backchain(%r15) */ + EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, +- REG_15, 152); ++ REG_15, ++ offsetof(struct prog_frame, backchain)); + } + } + +@@ -647,13 +661,13 @@ static void call_r1(struct bpf_jit *jit) + /* + * Function epilogue + */ +-static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth) ++static void bpf_jit_epilogue(struct bpf_jit *jit) + { + jit->exit_ip = jit->prg; + /* Load exit code: lgr %r2,%b0 */ + EMIT4(0xb9040000, REG_2, BPF_REG_0); + /* Restore registers */ +- save_restore_regs(jit, REGS_RESTORE, stack_depth); ++ save_restore_regs(jit, REGS_RESTORE, 0); + if (nospec_uses_trampoline()) { + jit->r14_thunk_ip = jit->prg; + /* Generate __s390_indirect_jump_r14 thunk */ +@@ -779,7 +793,7 @@ static int sign_extend(struct bpf_jit *jit, int r, u8 size, u8 flags) + * stack space for the large switch statement. + */ + static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, +- int i, bool extra_pass, u32 stack_depth) ++ int i, bool extra_pass) + { + struct bpf_insn *insn = &fp->insnsi[i]; + u32 dst_reg = insn->dst_reg; +@@ -1425,17 +1439,11 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, + jit->seen |= SEEN_FUNC; + /* + * Copy the tail call counter to where the callee expects it. +- * +- * Note 1: The callee can increment the tail call counter, but +- * we do not load it back, since the x86 JIT does not do this +- * either. +- * +- * Note 2: We assume that the verifier does not let us call the +- * main program, which clears the tail call counter on entry. + */ +- /* mvc STK_OFF_TCCNT(4,%r15),N(%r15) */ +- _EMIT6(0xd203f000 | STK_OFF_TCCNT, +- 0xf000 | (STK_OFF_TCCNT + STK_OFF + stack_depth)); ++ /* mvc tail_call_cnt(4,%r15),frame_off+tail_call_cnt(%r15) */ ++ _EMIT6(0xd203f000 | offsetof(struct prog_frame, tail_call_cnt), ++ 0xf000 | (jit->frame_off + ++ offsetof(struct prog_frame, tail_call_cnt))); + + /* Sign-extend the kfunc arguments. */ + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) { +@@ -1457,6 +1465,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, + call_r1(jit); + /* lgr %b0,%r2: load return value into %b0 */ + EMIT4(0xb9040000, BPF_REG_0, REG_2); ++ ++ /* ++ * Copy the potentially updated tail call counter back. ++ */ ++ ++ if (insn->src_reg == BPF_PSEUDO_CALL) ++ /* ++ * mvc frame_off+tail_call_cnt(%r15), ++ * tail_call_cnt(4,%r15) ++ */ ++ _EMIT6(0xd203f000 | (jit->frame_off + ++ offsetof(struct prog_frame, ++ tail_call_cnt)), ++ 0xf000 | offsetof(struct prog_frame, ++ tail_call_cnt)); ++ + break; + } + case BPF_JMP | BPF_TAIL_CALL: { +@@ -1486,10 +1510,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, + * goto out; + */ + +- if (jit->seen & SEEN_STACK) +- off = STK_OFF_TCCNT + STK_OFF + stack_depth; +- else +- off = STK_OFF_TCCNT; ++ off = jit->frame_off + ++ offsetof(struct prog_frame, tail_call_cnt); + /* lhi %w0,1 */ + EMIT4_IMM(0xa7080000, REG_W0, 1); + /* laal %w1,%w0,off(%r15) */ +@@ -1519,7 +1541,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, + /* + * Restore registers before calling function + */ +- save_restore_regs(jit, REGS_RESTORE, stack_depth); ++ save_restore_regs(jit, REGS_RESTORE, 0); + + /* + * goto *(prog->bpf_func + tail_call_start); +@@ -1822,7 +1844,7 @@ static int bpf_set_addr(struct bpf_jit *jit, int i) + * Compile eBPF program into s390x code + */ + static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp, +- bool extra_pass, u32 stack_depth) ++ bool extra_pass) + { + int i, insn_count, lit32_size, lit64_size; + +@@ -1830,19 +1852,25 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp, + jit->lit64 = jit->lit64_start; + jit->prg = 0; + jit->excnt = 0; ++ if (is_first_pass(jit) || (jit->seen & SEEN_STACK)) ++ jit->frame_off = sizeof(struct prog_frame) - ++ offsetofend(struct prog_frame, unused) + ++ round_up(fp->aux->stack_depth, 8); ++ else ++ jit->frame_off = 0; + +- bpf_jit_prologue(jit, fp, stack_depth); ++ bpf_jit_prologue(jit, fp); + if (bpf_set_addr(jit, 0) < 0) + return -1; + for (i = 0; i < fp->len; i += insn_count) { +- insn_count = bpf_jit_insn(jit, fp, i, extra_pass, stack_depth); ++ insn_count = bpf_jit_insn(jit, fp, i, extra_pass); + if (insn_count < 0) + return -1; + /* Next instruction address */ + if (bpf_set_addr(jit, i + insn_count) < 0) + return -1; + } +- bpf_jit_epilogue(jit, stack_depth); ++ bpf_jit_epilogue(jit); + + lit32_size = jit->lit32 - jit->lit32_start; + lit64_size = jit->lit64 - jit->lit64_start; +@@ -1902,7 +1930,6 @@ static struct bpf_binary_header *bpf_jit_alloc(struct bpf_jit *jit, + */ + struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) + { +- u32 stack_depth = round_up(fp->aux->stack_depth, 8); + struct bpf_prog *tmp, *orig_fp = fp; + struct bpf_binary_header *header; + struct s390_jit_data *jit_data; +@@ -1955,7 +1982,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) + * - 3: Calculate program size and addrs array + */ + for (pass = 1; pass <= 3; pass++) { +- if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) { ++ if (bpf_jit_prog(&jit, fp, extra_pass)) { + fp = orig_fp; + goto free_addrs; + } +@@ -1969,7 +1996,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) + goto free_addrs; + } + skip_init_ctx: +- if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) { ++ if (bpf_jit_prog(&jit, fp, extra_pass)) { + bpf_jit_binary_free(header); + fp = orig_fp; + goto free_addrs; +@@ -2285,9 +2312,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, + /* stg %r1,backchain_off(%r15) */ + EMIT6_DISP_LH(0xe3000000, 0x0024, REG_1, REG_0, REG_15, + tjit->backchain_off); +- /* mvc tccnt_off(4,%r15),stack_size+STK_OFF_TCCNT(%r15) */ ++ /* mvc tccnt_off(4,%r15),stack_size+tail_call_cnt(%r15) */ + _EMIT6(0xd203f000 | tjit->tccnt_off, +- 0xf000 | (tjit->stack_size + STK_OFF_TCCNT)); ++ 0xf000 | (tjit->stack_size + ++ offsetof(struct prog_frame, tail_call_cnt))); + /* stmg %r2,%rN,fwd_reg_args_off(%r15) */ + if (nr_reg_args) + EMIT6_DISP_LH(0xeb000000, 0x0024, REG_2, +@@ -2424,8 +2452,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, + (nr_stack_args * sizeof(u64) - 1) << 16 | + tjit->stack_args_off, + 0xf000 | tjit->orig_stack_args_off); +- /* mvc STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */ +- _EMIT6(0xd203f000 | STK_OFF_TCCNT, 0xf000 | tjit->tccnt_off); ++ /* mvc tail_call_cnt(4,%r15),tccnt_off(%r15) */ ++ _EMIT6(0xd203f000 | offsetof(struct prog_frame, tail_call_cnt), ++ 0xf000 | tjit->tccnt_off); + /* lgr %r1,%r8 */ + EMIT4(0xb9040000, REG_1, REG_8); + /* %r1() */ +@@ -2433,6 +2462,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, + /* stg %r2,retval_off(%r15) */ + EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15, + tjit->retval_off); ++ /* mvc tccnt_off(%r15),tail_call_cnt(4,%r15) */ ++ _EMIT6(0xd203f000 | tjit->tccnt_off, ++ 0xf000 | offsetof(struct prog_frame, tail_call_cnt)); + + im->ip_after_call = jit->prg_buf + jit->prg; + +@@ -2482,8 +2514,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, + if (flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET)) + EMIT6_DISP_LH(0xe3000000, 0x0004, REG_2, REG_0, REG_15, + tjit->retval_off); +- /* mvc stack_size+STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */ +- _EMIT6(0xd203f000 | (tjit->stack_size + STK_OFF_TCCNT), ++ /* mvc stack_size+tail_call_cnt(4,%r15),tccnt_off(%r15) */ ++ _EMIT6(0xd203f000 | (tjit->stack_size + ++ offsetof(struct prog_frame, tail_call_cnt)), + 0xf000 | tjit->tccnt_off); + /* aghi %r15,stack_size */ + EMIT4_IMM(0xa70b0000, REG_15, tjit->stack_size); +diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c +index 06012e68bdcaec..284a4cafa4324c 100644 +--- a/arch/sparc/kernel/of_device_32.c ++++ b/arch/sparc/kernel/of_device_32.c +@@ -387,6 +387,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, + + if (of_device_register(op)) { + printk("%pOF: Could not register of device.\n", dp); ++ put_device(&op->dev); + kfree(op); + op = NULL; + } +diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c +index d3842821a5a050..d2cd4f42e0cf07 100644 +--- a/arch/sparc/kernel/of_device_64.c ++++ b/arch/sparc/kernel/of_device_64.c +@@ -680,6 +680,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, + + if (of_device_register(op)) { + printk("%pOF: Could not register of device.\n", dp); ++ put_device(&op->dev); + kfree(op); + op = NULL; + } +diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c +index 8dad5d0995dcce..5bf77c07f6b620 100644 +--- a/arch/sparc/mm/hugetlbpage.c ++++ b/arch/sparc/mm/hugetlbpage.c +@@ -133,6 +133,26 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + + static pte_t sun4u_hugepage_shift_to_tte(pte_t entry, unsigned int shift) + { ++ unsigned long hugepage_size = _PAGE_SZ4MB_4U; ++ ++ pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4U; ++ ++ switch (shift) { ++ case HPAGE_256MB_SHIFT: ++ hugepage_size = _PAGE_SZ256MB_4U; ++ pte_val(entry) |= _PAGE_PMD_HUGE; ++ break; ++ case HPAGE_SHIFT: ++ pte_val(entry) |= _PAGE_PMD_HUGE; ++ break; ++ case HPAGE_64K_SHIFT: ++ hugepage_size = _PAGE_SZ64K_4U; ++ break; ++ default: ++ WARN_ONCE(1, "unsupported hugepage shift=%u\n", shift); ++ } ++ ++ pte_val(entry) = pte_val(entry) | hugepage_size; + return entry; + } + +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index 723e48b57bd0f8..425980eacaa841 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -661,6 +661,7 @@ + #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300 + #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301 + #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR 0xc0000302 ++#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET 0xc0000303 + + /* AMD Last Branch Record MSRs */ + #define MSR_AMD64_LBR_SELECT 0xc000010e +diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c +index 5a4b21389b1d98..d432f3824f0c29 100644 +--- a/arch/x86/kernel/umip.c ++++ b/arch/x86/kernel/umip.c +@@ -156,15 +156,26 @@ static int identify_insn(struct insn *insn) + if (!insn->modrm.nbytes) + return -EINVAL; + +- /* All the instructions of interest start with 0x0f. */ +- if (insn->opcode.bytes[0] != 0xf) ++ /* The instructions of interest have 2-byte opcodes: 0F 00 or 0F 01. */ ++ if (insn->opcode.nbytes < 2 || insn->opcode.bytes[0] != 0xf) + return -EINVAL; + + if (insn->opcode.bytes[1] == 0x1) { + switch (X86_MODRM_REG(insn->modrm.value)) { + case 0: ++ /* The reg form of 0F 01 /0 encodes VMX instructions. */ ++ if (X86_MODRM_MOD(insn->modrm.value) == 3) ++ return -EINVAL; ++ + return UMIP_INST_SGDT; + case 1: ++ /* ++ * The reg form of 0F 01 /1 encodes MONITOR/MWAIT, ++ * STAC/CLAC, and ENCLS. ++ */ ++ if (X86_MODRM_MOD(insn->modrm.value) == 3) ++ return -EINVAL; ++ + return UMIP_INST_SIDT; + case 4: + return UMIP_INST_SMSW; +diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c +index da2d82e3a8735e..f2cd8cfb0ef557 100644 +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -588,6 +588,7 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + msr_info->data = pmu->global_ctrl; + break; + case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR: ++ case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET: + case MSR_CORE_PERF_GLOBAL_OVF_CTRL: + msr_info->data = 0; + break; +@@ -649,6 +650,10 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + if (!msr_info->host_initiated) + pmu->global_status &= ~data; + break; ++ case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET: ++ if (!msr_info->host_initiated) ++ pmu->global_status |= data & ~pmu->global_status_mask; ++ break; + default: + kvm_pmu_mark_pmc_in_use(vcpu, msr_info->index); + return static_call(kvm_x86_pmu_set_msr)(vcpu, msr_info); +diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c +index 3fd47de14b38a3..0bad24f763d222 100644 +--- a/arch/x86/kvm/svm/pmu.c ++++ b/arch/x86/kvm/svm/pmu.c +@@ -117,6 +117,7 @@ static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) + case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS: + case MSR_AMD64_PERF_CNTR_GLOBAL_CTL: + case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR: ++ case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET: + return pmu->version > 1; + default: + if (msr > MSR_F15H_PERF_CTR5 && +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 29566e457ec4b5..0833f2c1a9d68b 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -4156,11 +4156,20 @@ static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu) + + static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) + { ++ struct vcpu_svm *svm = to_svm(vcpu); ++ ++ /* ++ * Next RIP must be provided as IRQs are disabled, and accessing guest ++ * memory to decode the instruction might fault, i.e. might sleep. ++ */ ++ if (!nrips || !svm->vmcb->control.next_rip) ++ return EXIT_FASTPATH_NONE; ++ + if (is_guest_mode(vcpu)) + return EXIT_FASTPATH_NONE; + +- if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && +- to_svm(vcpu)->vmcb->control.exit_info_1) ++ if (svm->vmcb->control.exit_code == SVM_EXIT_MSR && ++ svm->vmcb->control.exit_info_1) + return handle_fastpath_set_msr_irqoff(vcpu); + + return EXIT_FASTPATH_NONE; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 71d60d4e991fd3..a589a5781e9066 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1495,6 +1495,7 @@ static const u32 msrs_to_save_pmu[] = { + MSR_AMD64_PERF_CNTR_GLOBAL_CTL, + MSR_AMD64_PERF_CNTR_GLOBAL_STATUS, + MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, ++ MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET, + }; + + static u32 msrs_to_save[ARRAY_SIZE(msrs_to_save_base) + +@@ -7194,6 +7195,7 @@ static void kvm_probe_msr_to_save(u32 msr_index) + case MSR_AMD64_PERF_CNTR_GLOBAL_CTL: + case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS: + case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR: ++ case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET: + if (!kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) + return; + break; +diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c +index 178cf96ca10acb..f878bbb8b0ac2f 100644 +--- a/arch/xtensa/platforms/iss/simdisk.c ++++ b/arch/xtensa/platforms/iss/simdisk.c +@@ -230,10 +230,14 @@ static ssize_t proc_read_simdisk(struct file *file, char __user *buf, + static ssize_t proc_write_simdisk(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { +- char *tmp = memdup_user_nul(buf, count); ++ char *tmp; + struct simdisk *dev = pde_data(file_inode(file)); + int err; + ++ if (count == 0 || count > PAGE_SIZE) ++ return -EINVAL; ++ ++ tmp = memdup_user_nul(buf, count); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + +diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c +index e6468eab2681e9..7f1a9dba404979 100644 +--- a/block/blk-crypto-fallback.c ++++ b/block/blk-crypto-fallback.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include "blk-cgroup.h" + #include "blk-crypto-internal.h" +@@ -229,7 +230,9 @@ static bool blk_crypto_fallback_split_bio_if_needed(struct bio **bio_ptr) + bio->bi_status = BLK_STS_RESOURCE; + return false; + } ++ + bio_chain(split_bio, bio); ++ trace_block_split(split_bio, bio->bi_iter.bi_sector); + submit_bio_noacct(bio); + *bio_ptr = split_bio; + } +diff --git a/crypto/essiv.c b/crypto/essiv.c +index f7d4ef4837e541..4dbec116ddc3e0 100644 +--- a/crypto/essiv.c ++++ b/crypto/essiv.c +@@ -186,9 +186,14 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc) + const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); + struct essiv_aead_request_ctx *rctx = aead_request_ctx(req); + struct aead_request *subreq = &rctx->aead_req; ++ int ivsize = crypto_aead_ivsize(tfm); ++ int ssize = req->assoclen - ivsize; + struct scatterlist *src = req->src; + int err; + ++ if (ssize < 0) ++ return -EINVAL; ++ + crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv); + + /* +@@ -198,19 +203,12 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc) + */ + rctx->assoc = NULL; + if (req->src == req->dst || !enc) { +- scatterwalk_map_and_copy(req->iv, req->dst, +- req->assoclen - crypto_aead_ivsize(tfm), +- crypto_aead_ivsize(tfm), 1); ++ scatterwalk_map_and_copy(req->iv, req->dst, ssize, ivsize, 1); + } else { + u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset; +- int ivsize = crypto_aead_ivsize(tfm); +- int ssize = req->assoclen - ivsize; + struct scatterlist *sg; + int nents; + +- if (ssize < 0) +- return -EINVAL; +- + nents = sg_nents_for_len(req->src, ssize); + if (nents < 0) + return -EINVAL; +diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c +index d50261d05f3a1a..515b20d0b698a4 100644 +--- a/drivers/acpi/acpi_dbg.c ++++ b/drivers/acpi/acpi_dbg.c +@@ -569,11 +569,11 @@ static int acpi_aml_release(struct inode *inode, struct file *file) + return 0; + } + +-static int acpi_aml_read_user(char __user *buf, int len) ++static ssize_t acpi_aml_read_user(char __user *buf, size_t len) + { +- int ret; + struct circ_buf *crc = &acpi_aml_io.out_crc; +- int n; ++ ssize_t ret; ++ size_t n; + char *p; + + ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER); +@@ -582,7 +582,7 @@ static int acpi_aml_read_user(char __user *buf, int len) + /* sync head before removing logs */ + smp_rmb(); + p = &crc->buf[crc->tail]; +- n = min(len, circ_count_to_end(crc)); ++ n = min_t(size_t, len, circ_count_to_end(crc)); + if (copy_to_user(buf, p, n)) { + ret = -EFAULT; + goto out; +@@ -599,8 +599,8 @@ static int acpi_aml_read_user(char __user *buf, int len) + static ssize_t acpi_aml_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) + { +- int ret = 0; +- int size = 0; ++ ssize_t ret = 0; ++ ssize_t size = 0; + + if (!count) + return 0; +@@ -639,11 +639,11 @@ static ssize_t acpi_aml_read(struct file *file, char __user *buf, + return size > 0 ? size : ret; + } + +-static int acpi_aml_write_user(const char __user *buf, int len) ++static ssize_t acpi_aml_write_user(const char __user *buf, size_t len) + { +- int ret; + struct circ_buf *crc = &acpi_aml_io.in_crc; +- int n; ++ ssize_t ret; ++ size_t n; + char *p; + + ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER); +@@ -652,7 +652,7 @@ static int acpi_aml_write_user(const char __user *buf, int len) + /* sync tail before inserting cmds */ + smp_mb(); + p = &crc->buf[crc->head]; +- n = min(len, circ_space_to_end(crc)); ++ n = min_t(size_t, len, circ_space_to_end(crc)); + if (copy_from_user(p, buf, n)) { + ret = -EFAULT; + goto out; +@@ -663,14 +663,14 @@ static int acpi_aml_write_user(const char __user *buf, int len) + ret = n; + out: + acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0); +- return n; ++ return ret; + } + + static ssize_t acpi_aml_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { +- int ret = 0; +- int size = 0; ++ ssize_t ret = 0; ++ ssize_t size = 0; + + if (!count) + return 0; +diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c +index 33c3b16af556b5..ecba82ac7cd5f9 100644 +--- a/drivers/acpi/acpi_tad.c ++++ b/drivers/acpi/acpi_tad.c +@@ -564,6 +564,9 @@ static int acpi_tad_remove(struct platform_device *pdev) + + pm_runtime_get_sync(dev); + ++ if (dd->capabilities & ACPI_TAD_RT) ++ sysfs_remove_group(&dev->kobj, &acpi_tad_time_attr_group); ++ + if (dd->capabilities & ACPI_TAD_DC_WAKE) + sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group); + +diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c +index 989dc01af03fbb..bc205b3309043b 100644 +--- a/drivers/acpi/acpica/evglock.c ++++ b/drivers/acpi/acpica/evglock.c +@@ -42,6 +42,10 @@ acpi_status acpi_ev_init_global_lock_handler(void) + return_ACPI_STATUS(AE_OK); + } + ++ if (!acpi_gbl_use_global_lock) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Attempt installation of the global lock handler */ + + status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, +diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c +index e3cbaf3c3bbc15..a70b6db3bf0596 100644 +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -94,7 +94,7 @@ enum { + + struct acpi_battery { + struct mutex lock; +- struct mutex sysfs_lock; ++ struct mutex update_lock; + struct power_supply *bat; + struct power_supply_desc bat_desc; + struct acpi_device *device; +@@ -888,15 +888,12 @@ static int sysfs_add_battery(struct acpi_battery *battery) + + static void sysfs_remove_battery(struct acpi_battery *battery) + { +- mutex_lock(&battery->sysfs_lock); +- if (!battery->bat) { +- mutex_unlock(&battery->sysfs_lock); ++ if (!battery->bat) + return; +- } ++ + battery_hook_remove_battery(battery); + power_supply_unregister(battery->bat); + battery->bat = NULL; +- mutex_unlock(&battery->sysfs_lock); + } + + static void find_battery(const struct dmi_header *dm, void *private) +@@ -1056,6 +1053,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) + + if (!battery) + return; ++ ++ guard(mutex)(&battery->update_lock); ++ + old = battery->bat; + /* + * On Acer Aspire V5-573G notifications are sometimes triggered too +@@ -1078,21 +1078,22 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) + } + + static int battery_notify(struct notifier_block *nb, +- unsigned long mode, void *_unused) ++ unsigned long mode, void *_unused) + { + struct acpi_battery *battery = container_of(nb, struct acpi_battery, + pm_nb); +- int result; + +- switch (mode) { +- case PM_POST_HIBERNATION: +- case PM_POST_SUSPEND: ++ if (mode == PM_POST_SUSPEND || mode == PM_POST_HIBERNATION) { ++ guard(mutex)(&battery->update_lock); ++ + if (!acpi_battery_present(battery)) + return 0; + + if (battery->bat) { + acpi_battery_refresh(battery); + } else { ++ int result; ++ + result = acpi_battery_get_info(battery); + if (result) + return result; +@@ -1104,7 +1105,6 @@ static int battery_notify(struct notifier_block *nb, + + acpi_battery_init_alarm(battery); + acpi_battery_get_state(battery); +- break; + } + + return 0; +@@ -1182,6 +1182,8 @@ static int acpi_battery_update_retry(struct acpi_battery *battery) + { + int retry, ret; + ++ guard(mutex)(&battery->update_lock); ++ + for (retry = 5; retry; retry--) { + ret = acpi_battery_update(battery, false); + if (!ret) +@@ -1192,6 +1194,13 @@ static int acpi_battery_update_retry(struct acpi_battery *battery) + return ret; + } + ++static void sysfs_battery_cleanup(struct acpi_battery *battery) ++{ ++ guard(mutex)(&battery->update_lock); ++ ++ sysfs_remove_battery(battery); ++} ++ + static int acpi_battery_add(struct acpi_device *device) + { + int result = 0; +@@ -1203,15 +1212,21 @@ static int acpi_battery_add(struct acpi_device *device) + if (device->dep_unmet) + return -EPROBE_DEFER; + +- battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); ++ battery = devm_kzalloc(&device->dev, sizeof(*battery), GFP_KERNEL); + if (!battery) + return -ENOMEM; + battery->device = device; + strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); + device->driver_data = battery; +- mutex_init(&battery->lock); +- mutex_init(&battery->sysfs_lock); ++ result = devm_mutex_init(&device->dev, &battery->lock); ++ if (result) ++ return result; ++ ++ result = devm_mutex_init(&device->dev, &battery->update_lock); ++ if (result) ++ return result; ++ + if (acpi_has_method(battery->device->handle, "_BIX")) + set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); + +@@ -1238,10 +1253,7 @@ static int acpi_battery_add(struct acpi_device *device) + device_init_wakeup(&device->dev, 0); + unregister_pm_notifier(&battery->pm_nb); + fail: +- sysfs_remove_battery(battery); +- mutex_destroy(&battery->lock); +- mutex_destroy(&battery->sysfs_lock); +- kfree(battery); ++ sysfs_battery_cleanup(battery); + + return result; + } +@@ -1260,11 +1272,10 @@ static void acpi_battery_remove(struct acpi_device *device) + + device_init_wakeup(&device->dev, 0); + unregister_pm_notifier(&battery->pm_nb); +- sysfs_remove_battery(battery); + +- mutex_destroy(&battery->lock); +- mutex_destroy(&battery->sysfs_lock); +- kfree(battery); ++ guard(mutex)(&battery->update_lock); ++ ++ sysfs_remove_battery(battery); + } + + #ifdef CONFIG_PM_SLEEP +@@ -1281,6 +1292,9 @@ static int acpi_battery_resume(struct device *dev) + return -EINVAL; + + battery->update_time = 0; ++ ++ guard(mutex)(&battery->update_lock); ++ + acpi_battery_update(battery, true); + return 0; + } +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index dca5682308cb32..5898c3c8c2a7f2 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -74,6 +74,7 @@ static bool acpi_nondev_subnode_extract(union acpi_object *desc, + struct fwnode_handle *parent) + { + struct acpi_data_node *dn; ++ acpi_handle scope = NULL; + bool result; + + dn = kzalloc(sizeof(*dn), GFP_KERNEL); +@@ -86,29 +87,35 @@ static bool acpi_nondev_subnode_extract(union acpi_object *desc, + INIT_LIST_HEAD(&dn->data.properties); + INIT_LIST_HEAD(&dn->data.subnodes); + +- result = acpi_extract_properties(handle, desc, &dn->data); +- +- if (handle) { +- acpi_handle scope; +- acpi_status status; ++ /* ++ * The scope for the completion of relative pathname segments and ++ * subnode object lookup is the one of the namespace node (device) ++ * containing the object that has returned the package. That is, it's ++ * the scope of that object's parent device. ++ */ ++ if (handle) ++ acpi_get_parent(handle, &scope); + +- /* +- * The scope for the subnode object lookup is the one of the +- * namespace node (device) containing the object that has +- * returned the package. That is, it's the scope of that +- * object's parent. +- */ +- status = acpi_get_parent(handle, &scope); +- if (ACPI_SUCCESS(status) +- && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data, +- &dn->fwnode)) +- result = true; +- } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data, +- &dn->fwnode)) { ++ /* ++ * Extract properties from the _DSD-equivalent package pointed to by ++ * desc and use scope (if not NULL) for the completion of relative ++ * pathname segments. ++ * ++ * The extracted properties will be held in the new data node dn. ++ */ ++ result = acpi_extract_properties(scope, desc, &dn->data); ++ /* ++ * Look for subnodes in the _DSD-equivalent package pointed to by desc ++ * and create child nodes of dn if there are any. ++ */ ++ if (acpi_enumerate_nondev_subnodes(scope, desc, &dn->data, &dn->fwnode)) + result = true; +- } + + if (result) { ++ /* ++ * This will be NULL if the desc package is embedded in an outer ++ * _DSD-equivalent package and its scope cannot be determined. ++ */ + dn->handle = handle; + dn->data.pointer = desc; + list_add_tail(&dn->sibling, list); +@@ -120,35 +127,21 @@ static bool acpi_nondev_subnode_extract(union acpi_object *desc, + return false; + } + +-static bool acpi_nondev_subnode_data_ok(acpi_handle handle, +- const union acpi_object *link, +- struct list_head *list, +- struct fwnode_handle *parent) +-{ +- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; +- acpi_status status; +- +- status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf, +- ACPI_TYPE_PACKAGE); +- if (ACPI_FAILURE(status)) +- return false; +- +- if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list, +- parent)) +- return true; +- +- ACPI_FREE(buf.pointer); +- return false; +-} +- + static bool acpi_nondev_subnode_ok(acpi_handle scope, + const union acpi_object *link, + struct list_head *list, + struct fwnode_handle *parent) + { ++ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + acpi_handle handle; + acpi_status status; + ++ /* ++ * If the scope is unknown, the _DSD-equivalent package being parsed ++ * was embedded in an outer _DSD-equivalent package as a result of ++ * direct evaluation of an object pointed to by a reference. In that ++ * case, using a pathname as the target object pointer is invalid. ++ */ + if (!scope) + return false; + +@@ -157,7 +150,17 @@ static bool acpi_nondev_subnode_ok(acpi_handle scope, + if (ACPI_FAILURE(status)) + return false; + +- return acpi_nondev_subnode_data_ok(handle, link, list, parent); ++ status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf, ++ ACPI_TYPE_PACKAGE); ++ if (ACPI_FAILURE(status)) ++ return false; ++ ++ if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list, ++ parent)) ++ return true; ++ ++ ACPI_FREE(buf.pointer); ++ return false; + } + + static bool acpi_add_nondev_subnodes(acpi_handle scope, +@@ -168,9 +171,12 @@ static bool acpi_add_nondev_subnodes(acpi_handle scope, + bool ret = false; + int i; + ++ /* ++ * Every element in the links package is expected to represent a link ++ * to a non-device node in a tree containing device-specific data. ++ */ + for (i = 0; i < links->package.count; i++) { + union acpi_object *link, *desc; +- acpi_handle handle; + bool result; + + link = &links->package.elements[i]; +@@ -178,26 +184,53 @@ static bool acpi_add_nondev_subnodes(acpi_handle scope, + if (link->package.count != 2) + continue; + +- /* The first one must be a string. */ ++ /* The first one (the key) must be a string. */ + if (link->package.elements[0].type != ACPI_TYPE_STRING) + continue; + +- /* The second one may be a string, a reference or a package. */ ++ /* The second one (the target) may be a string or a package. */ + switch (link->package.elements[1].type) { + case ACPI_TYPE_STRING: ++ /* ++ * The string is expected to be a full pathname or a ++ * pathname segment relative to the given scope. That ++ * pathname is expected to point to an object returning ++ * a package that contains _DSD-equivalent information. ++ */ + result = acpi_nondev_subnode_ok(scope, link, list, + parent); + break; +- case ACPI_TYPE_LOCAL_REFERENCE: +- handle = link->package.elements[1].reference.handle; +- result = acpi_nondev_subnode_data_ok(handle, link, list, +- parent); +- break; + case ACPI_TYPE_PACKAGE: ++ /* ++ * This happens when a reference is used in AML to ++ * point to the target. Since the target is expected ++ * to be a named object, a reference to it will cause it ++ * to be avaluated in place and its return package will ++ * be embedded in the links package at the location of ++ * the reference. ++ * ++ * The target package is expected to contain _DSD- ++ * equivalent information, but the scope in which it ++ * is located in the original AML is unknown. Thus ++ * it cannot contain pathname segments represented as ++ * strings because there is no way to build full ++ * pathnames out of them. ++ */ ++ acpi_handle_debug(scope, "subnode %s: Unknown scope\n", ++ link->package.elements[0].string.pointer); + desc = &link->package.elements[1]; + result = acpi_nondev_subnode_extract(desc, NULL, link, + list, parent); + break; ++ case ACPI_TYPE_LOCAL_REFERENCE: ++ /* ++ * It is not expected to see any local references in ++ * the links package because referencing a named object ++ * should cause it to be evaluated in place. ++ */ ++ acpi_handle_info(scope, "subnode %s: Unexpected reference\n", ++ link->package.elements[0].string.pointer); ++ fallthrough; + default: + result = false; + break; +@@ -357,6 +390,9 @@ static void acpi_untie_nondev_subnodes(struct acpi_device_data *data) + struct acpi_data_node *dn; + + list_for_each_entry(dn, &data->subnodes, sibling) { ++ if (!dn->handle) ++ continue; ++ + acpi_detach_data(dn->handle, acpi_nondev_subnode_tag); + + acpi_untie_nondev_subnodes(&dn->data); +@@ -371,6 +407,9 @@ static bool acpi_tie_nondev_subnodes(struct acpi_device_data *data) + acpi_status status; + bool ret; + ++ if (!dn->handle) ++ continue; ++ + status = acpi_attach_data(dn->handle, acpi_nondev_subnode_tag, dn); + if (ACPI_FAILURE(status) && status != AE_ALREADY_EXISTS) { + acpi_handle_err(dn->handle, "Can't tag data node\n"); +diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c +index c48f4d9f2c690b..558cfb3a06c5ea 100644 +--- a/drivers/bus/mhi/ep/main.c ++++ b/drivers/bus/mhi/ep/main.c +@@ -387,17 +387,13 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + { + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + struct device *dev = &mhi_cntrl->mhi_dev->dev; +- size_t tr_len, read_offset, write_offset; ++ size_t tr_len, read_offset; + struct mhi_ep_buf_info buf_info = {}; + u32 len = MHI_EP_DEFAULT_MTU; + struct mhi_ring_element *el; +- bool tr_done = false; + void *buf_addr; +- u32 buf_left; + int ret; + +- buf_left = len; +- + do { + /* Don't process the transfer ring if the channel is not in RUNNING state */ + if (mhi_chan->state != MHI_CH_STATE_RUNNING) { +@@ -410,24 +406,23 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + /* Check if there is data pending to be read from previous read operation */ + if (mhi_chan->tre_bytes_left) { + dev_dbg(dev, "TRE bytes remaining: %u\n", mhi_chan->tre_bytes_left); +- tr_len = min(buf_left, mhi_chan->tre_bytes_left); ++ tr_len = min(len, mhi_chan->tre_bytes_left); + } else { + mhi_chan->tre_loc = MHI_TRE_DATA_GET_PTR(el); + mhi_chan->tre_size = MHI_TRE_DATA_GET_LEN(el); + mhi_chan->tre_bytes_left = mhi_chan->tre_size; + +- tr_len = min(buf_left, mhi_chan->tre_size); ++ tr_len = min(len, mhi_chan->tre_size); + } + + read_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left; +- write_offset = len - buf_left; + + buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL); + if (!buf_addr) + return -ENOMEM; + + buf_info.host_addr = mhi_chan->tre_loc + read_offset; +- buf_info.dev_addr = buf_addr + write_offset; ++ buf_info.dev_addr = buf_addr; + buf_info.size = tr_len; + buf_info.cb = mhi_ep_read_completion; + buf_info.cb_buf = buf_addr; +@@ -443,16 +438,12 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + goto err_free_buf_addr; + } + +- buf_left -= tr_len; + mhi_chan->tre_bytes_left -= tr_len; + +- if (!mhi_chan->tre_bytes_left) { +- if (MHI_TRE_DATA_GET_IEOT(el)) +- tr_done = true; +- ++ if (!mhi_chan->tre_bytes_left) + mhi_chan->rd_offset = (mhi_chan->rd_offset + 1) % ring->ring_size; +- } +- } while (buf_left && !tr_done); ++ /* Read until the some buffer is left or the ring becomes not empty */ ++ } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); + + return 0; + +@@ -486,15 +477,11 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring) + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } else { + /* UL channel */ +- do { +- ret = mhi_ep_read_channel(mhi_cntrl, ring); +- if (ret < 0) { +- dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); +- return ret; +- } +- +- /* Read until the ring becomes empty */ +- } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); ++ ret = mhi_ep_read_channel(mhi_cntrl, ring); ++ if (ret < 0) { ++ dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); ++ return ret; ++ } + } + + return 0; +diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c +index cfd17c02fe20ef..4af748ff509855 100644 +--- a/drivers/bus/mhi/host/init.c ++++ b/drivers/bus/mhi/host/init.c +@@ -164,7 +164,6 @@ void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl) + int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) + { + struct mhi_event *mhi_event = mhi_cntrl->mhi_event; +- struct device *dev = &mhi_cntrl->mhi_dev->dev; + unsigned long irq_flags = IRQF_SHARED | IRQF_NO_SUSPEND; + int i, ret; + +@@ -191,7 +190,7 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) + continue; + + if (mhi_event->irq >= mhi_cntrl->nr_irqs) { +- dev_err(dev, "irq %d not available for event ring\n", ++ dev_err(mhi_cntrl->cntrl_dev, "irq %d not available for event ring\n", + mhi_event->irq); + ret = -EINVAL; + goto error_request; +@@ -202,7 +201,7 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) + irq_flags, + "mhi", mhi_event); + if (ret) { +- dev_err(dev, "Error requesting irq:%d for ev:%d\n", ++ dev_err(mhi_cntrl->cntrl_dev, "Error requesting irq:%d for ev:%d\n", + mhi_cntrl->irq[mhi_event->irq], i); + goto error_request; + } +diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c +index ecfcb50302f6ce..efda90dcf5b3d0 100644 +--- a/drivers/char/ipmi/ipmi_kcs_sm.c ++++ b/drivers/char/ipmi/ipmi_kcs_sm.c +@@ -122,10 +122,10 @@ struct si_sm_data { + unsigned long error0_timeout; + }; + +-static unsigned int init_kcs_data_with_state(struct si_sm_data *kcs, +- struct si_sm_io *io, enum kcs_states state) ++static unsigned int init_kcs_data(struct si_sm_data *kcs, ++ struct si_sm_io *io) + { +- kcs->state = state; ++ kcs->state = KCS_IDLE; + kcs->io = io; + kcs->write_pos = 0; + kcs->write_count = 0; +@@ -140,12 +140,6 @@ static unsigned int init_kcs_data_with_state(struct si_sm_data *kcs, + return 2; + } + +-static unsigned int init_kcs_data(struct si_sm_data *kcs, +- struct si_sm_io *io) +-{ +- return init_kcs_data_with_state(kcs, io, KCS_IDLE); +-} +- + static inline unsigned char read_status(struct si_sm_data *kcs) + { + return kcs->io->inputb(kcs->io, 1); +@@ -276,7 +270,7 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, + if (size > MAX_KCS_WRITE_SIZE) + return IPMI_REQ_LEN_EXCEEDED_ERR; + +- if (kcs->state != KCS_IDLE) { ++ if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) { + dev_warn(kcs->io->dev, "KCS in invalid state %d\n", kcs->state); + return IPMI_NOT_IN_MY_STATE_ERR; + } +@@ -501,7 +495,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) + } + + if (kcs->state == KCS_HOSED) { +- init_kcs_data_with_state(kcs, kcs->io, KCS_ERROR0); ++ init_kcs_data(kcs, kcs->io); + return SI_SM_HOSED; + } + +diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c +index 96f175bd6d9fb7..b7d8bf202ed2d0 100644 +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -39,7 +39,9 @@ + + #define IPMI_DRIVER_VERSION "39.2" + +-static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); ++static struct ipmi_recv_msg *ipmi_alloc_recv_msg(struct ipmi_user *user); ++static void ipmi_set_recv_msg_user(struct ipmi_recv_msg *msg, ++ struct ipmi_user *user); + static int ipmi_init_msghandler(void); + static void smi_recv_tasklet(struct tasklet_struct *t); + static void handle_new_recv_msgs(struct ipmi_smi *intf); +@@ -939,13 +941,11 @@ static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) + * risk. At this moment, simply skip it in that case. + */ + ipmi_free_recv_msg(msg); +- atomic_dec(&msg->user->nr_msgs); + } else { + int index; + struct ipmi_user *user = acquire_ipmi_user(msg->user, &index); + + if (user) { +- atomic_dec(&user->nr_msgs); + user->handler->ipmi_recv_hndl(msg, user->handler_data); + release_ipmi_user(user, index); + } else { +@@ -1634,8 +1634,7 @@ int ipmi_set_gets_events(struct ipmi_user *user, bool val) + spin_unlock_irqrestore(&intf->events_lock, flags); + + list_for_each_entry_safe(msg, msg2, &msgs, link) { +- msg->user = user; +- kref_get(&user->refcount); ++ ipmi_set_recv_msg_user(msg, user); + deliver_local_response(intf, msg); + } + +@@ -2309,22 +2308,18 @@ static int i_ipmi_request(struct ipmi_user *user, + struct ipmi_recv_msg *recv_msg; + int rv = 0; + +- if (user) { +- if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { +- /* Decrement will happen at the end of the routine. */ +- rv = -EBUSY; +- goto out; +- } +- } +- +- if (supplied_recv) ++ if (supplied_recv) { + recv_msg = supplied_recv; +- else { +- recv_msg = ipmi_alloc_recv_msg(); +- if (recv_msg == NULL) { +- rv = -ENOMEM; +- goto out; ++ recv_msg->user = user; ++ if (user) { ++ atomic_inc(&user->nr_msgs); ++ /* The put happens when the message is freed. */ ++ kref_get(&user->refcount); + } ++ } else { ++ recv_msg = ipmi_alloc_recv_msg(user); ++ if (IS_ERR(recv_msg)) ++ return PTR_ERR(recv_msg); + } + recv_msg->user_msg_data = user_msg_data; + +@@ -2335,8 +2330,7 @@ static int i_ipmi_request(struct ipmi_user *user, + if (smi_msg == NULL) { + if (!supplied_recv) + ipmi_free_recv_msg(recv_msg); +- rv = -ENOMEM; +- goto out; ++ return -ENOMEM; + } + } + +@@ -2346,10 +2340,6 @@ static int i_ipmi_request(struct ipmi_user *user, + goto out_err; + } + +- recv_msg->user = user; +- if (user) +- /* The put happens when the message is freed. */ +- kref_get(&user->refcount); + recv_msg->msgid = msgid; + /* + * Store the message to send in the receive message so timeout +@@ -2378,8 +2368,10 @@ static int i_ipmi_request(struct ipmi_user *user, + + if (rv) { + out_err: +- ipmi_free_smi_msg(smi_msg); +- ipmi_free_recv_msg(recv_msg); ++ if (!supplied_smi) ++ ipmi_free_smi_msg(smi_msg); ++ if (!supplied_recv) ++ ipmi_free_recv_msg(recv_msg); + } else { + dev_dbg(intf->si_dev, "Send: %*ph\n", + smi_msg->data_size, smi_msg->data); +@@ -2388,9 +2380,6 @@ static int i_ipmi_request(struct ipmi_user *user, + } + rcu_read_unlock(); + +-out: +- if (rv && user) +- atomic_dec(&user->nr_msgs); + return rv; + } + +@@ -3883,7 +3872,7 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, + unsigned char chan; + struct ipmi_user *user = NULL; + struct ipmi_ipmb_addr *ipmb_addr; +- struct ipmi_recv_msg *recv_msg; ++ struct ipmi_recv_msg *recv_msg = NULL; + + if (msg->rsp_size < 10) { + /* Message not big enough, just ignore it. */ +@@ -3904,9 +3893,8 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, + rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); + if (rcvr) { + user = rcvr->user; +- kref_get(&user->refcount); +- } else +- user = NULL; ++ recv_msg = ipmi_alloc_recv_msg(user); ++ } + rcu_read_unlock(); + + if (user == NULL) { +@@ -3941,47 +3929,41 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, + rv = -1; + } + rcu_read_unlock(); +- } else { +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { +- /* +- * We couldn't allocate memory for the +- * message, so requeue it for handling +- * later. +- */ +- rv = 1; +- kref_put(&user->refcount, free_user); +- } else { +- /* Extract the source address from the data. */ +- ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; +- ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE; +- ipmb_addr->slave_addr = msg->rsp[6]; +- ipmb_addr->lun = msg->rsp[7] & 3; +- ipmb_addr->channel = msg->rsp[3] & 0xf; ++ } else if (!IS_ERR(recv_msg)) { ++ /* Extract the source address from the data. */ ++ ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; ++ ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE; ++ ipmb_addr->slave_addr = msg->rsp[6]; ++ ipmb_addr->lun = msg->rsp[7] & 3; ++ ipmb_addr->channel = msg->rsp[3] & 0xf; + +- /* +- * Extract the rest of the message information +- * from the IPMB header. +- */ +- recv_msg->user = user; +- recv_msg->recv_type = IPMI_CMD_RECV_TYPE; +- recv_msg->msgid = msg->rsp[7] >> 2; +- recv_msg->msg.netfn = msg->rsp[4] >> 2; +- recv_msg->msg.cmd = msg->rsp[8]; +- recv_msg->msg.data = recv_msg->msg_data; ++ /* ++ * Extract the rest of the message information ++ * from the IPMB header. ++ */ ++ recv_msg->recv_type = IPMI_CMD_RECV_TYPE; ++ recv_msg->msgid = msg->rsp[7] >> 2; ++ recv_msg->msg.netfn = msg->rsp[4] >> 2; ++ recv_msg->msg.cmd = msg->rsp[8]; ++ recv_msg->msg.data = recv_msg->msg_data; + +- /* +- * We chop off 10, not 9 bytes because the checksum +- * at the end also needs to be removed. +- */ +- recv_msg->msg.data_len = msg->rsp_size - 10; +- memcpy(recv_msg->msg_data, &msg->rsp[9], +- msg->rsp_size - 10); +- if (deliver_response(intf, recv_msg)) +- ipmi_inc_stat(intf, unhandled_commands); +- else +- ipmi_inc_stat(intf, handled_commands); +- } ++ /* ++ * We chop off 10, not 9 bytes because the checksum ++ * at the end also needs to be removed. ++ */ ++ recv_msg->msg.data_len = msg->rsp_size - 10; ++ memcpy(recv_msg->msg_data, &msg->rsp[9], ++ msg->rsp_size - 10); ++ if (deliver_response(intf, recv_msg)) ++ ipmi_inc_stat(intf, unhandled_commands); ++ else ++ ipmi_inc_stat(intf, handled_commands); ++ } else { ++ /* ++ * We couldn't allocate memory for the message, so ++ * requeue it for handling later. ++ */ ++ rv = 1; + } + + return rv; +@@ -3994,7 +3976,7 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf, + int rv = 0; + struct ipmi_user *user = NULL; + struct ipmi_ipmb_direct_addr *daddr; +- struct ipmi_recv_msg *recv_msg; ++ struct ipmi_recv_msg *recv_msg = NULL; + unsigned char netfn = msg->rsp[0] >> 2; + unsigned char cmd = msg->rsp[3]; + +@@ -4003,9 +3985,8 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf, + rcvr = find_cmd_rcvr(intf, netfn, cmd, 0); + if (rcvr) { + user = rcvr->user; +- kref_get(&user->refcount); +- } else +- user = NULL; ++ recv_msg = ipmi_alloc_recv_msg(user); ++ } + rcu_read_unlock(); + + if (user == NULL) { +@@ -4032,44 +4013,38 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf, + rv = -1; + } + rcu_read_unlock(); +- } else { +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { +- /* +- * We couldn't allocate memory for the +- * message, so requeue it for handling +- * later. +- */ +- rv = 1; +- kref_put(&user->refcount, free_user); +- } else { +- /* Extract the source address from the data. */ +- daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; +- daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; +- daddr->channel = 0; +- daddr->slave_addr = msg->rsp[1]; +- daddr->rs_lun = msg->rsp[0] & 3; +- daddr->rq_lun = msg->rsp[2] & 3; ++ } else if (!IS_ERR(recv_msg)) { ++ /* Extract the source address from the data. */ ++ daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; ++ daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; ++ daddr->channel = 0; ++ daddr->slave_addr = msg->rsp[1]; ++ daddr->rs_lun = msg->rsp[0] & 3; ++ daddr->rq_lun = msg->rsp[2] & 3; + +- /* +- * Extract the rest of the message information +- * from the IPMB header. +- */ +- recv_msg->user = user; +- recv_msg->recv_type = IPMI_CMD_RECV_TYPE; +- recv_msg->msgid = (msg->rsp[2] >> 2); +- recv_msg->msg.netfn = msg->rsp[0] >> 2; +- recv_msg->msg.cmd = msg->rsp[3]; +- recv_msg->msg.data = recv_msg->msg_data; +- +- recv_msg->msg.data_len = msg->rsp_size - 4; +- memcpy(recv_msg->msg_data, msg->rsp + 4, +- msg->rsp_size - 4); +- if (deliver_response(intf, recv_msg)) +- ipmi_inc_stat(intf, unhandled_commands); +- else +- ipmi_inc_stat(intf, handled_commands); +- } ++ /* ++ * Extract the rest of the message information ++ * from the IPMB header. ++ */ ++ recv_msg->recv_type = IPMI_CMD_RECV_TYPE; ++ recv_msg->msgid = (msg->rsp[2] >> 2); ++ recv_msg->msg.netfn = msg->rsp[0] >> 2; ++ recv_msg->msg.cmd = msg->rsp[3]; ++ recv_msg->msg.data = recv_msg->msg_data; ++ ++ recv_msg->msg.data_len = msg->rsp_size - 4; ++ memcpy(recv_msg->msg_data, msg->rsp + 4, ++ msg->rsp_size - 4); ++ if (deliver_response(intf, recv_msg)) ++ ipmi_inc_stat(intf, unhandled_commands); ++ else ++ ipmi_inc_stat(intf, handled_commands); ++ } else { ++ /* ++ * We couldn't allocate memory for the message, so ++ * requeue it for handling later. ++ */ ++ rv = 1; + } + + return rv; +@@ -4183,7 +4158,7 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, + unsigned char chan; + struct ipmi_user *user = NULL; + struct ipmi_lan_addr *lan_addr; +- struct ipmi_recv_msg *recv_msg; ++ struct ipmi_recv_msg *recv_msg = NULL; + + if (msg->rsp_size < 12) { + /* Message not big enough, just ignore it. */ +@@ -4204,9 +4179,8 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, + rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); + if (rcvr) { + user = rcvr->user; +- kref_get(&user->refcount); +- } else +- user = NULL; ++ recv_msg = ipmi_alloc_recv_msg(user); ++ } + rcu_read_unlock(); + + if (user == NULL) { +@@ -4218,49 +4192,44 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, + * them to be freed. + */ + rv = 0; +- } else { +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { +- /* +- * We couldn't allocate memory for the +- * message, so requeue it for handling later. +- */ +- rv = 1; +- kref_put(&user->refcount, free_user); +- } else { +- /* Extract the source address from the data. */ +- lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; +- lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; +- lan_addr->session_handle = msg->rsp[4]; +- lan_addr->remote_SWID = msg->rsp[8]; +- lan_addr->local_SWID = msg->rsp[5]; +- lan_addr->lun = msg->rsp[9] & 3; +- lan_addr->channel = msg->rsp[3] & 0xf; +- lan_addr->privilege = msg->rsp[3] >> 4; ++ } else if (!IS_ERR(recv_msg)) { ++ /* Extract the source address from the data. */ ++ lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; ++ lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; ++ lan_addr->session_handle = msg->rsp[4]; ++ lan_addr->remote_SWID = msg->rsp[8]; ++ lan_addr->local_SWID = msg->rsp[5]; ++ lan_addr->lun = msg->rsp[9] & 3; ++ lan_addr->channel = msg->rsp[3] & 0xf; ++ lan_addr->privilege = msg->rsp[3] >> 4; + +- /* +- * Extract the rest of the message information +- * from the IPMB header. +- */ +- recv_msg->user = user; +- recv_msg->recv_type = IPMI_CMD_RECV_TYPE; +- recv_msg->msgid = msg->rsp[9] >> 2; +- recv_msg->msg.netfn = msg->rsp[6] >> 2; +- recv_msg->msg.cmd = msg->rsp[10]; +- recv_msg->msg.data = recv_msg->msg_data; ++ /* ++ * Extract the rest of the message information ++ * from the IPMB header. ++ */ ++ recv_msg->recv_type = IPMI_CMD_RECV_TYPE; ++ recv_msg->msgid = msg->rsp[9] >> 2; ++ recv_msg->msg.netfn = msg->rsp[6] >> 2; ++ recv_msg->msg.cmd = msg->rsp[10]; ++ recv_msg->msg.data = recv_msg->msg_data; + +- /* +- * We chop off 12, not 11 bytes because the checksum +- * at the end also needs to be removed. +- */ +- recv_msg->msg.data_len = msg->rsp_size - 12; +- memcpy(recv_msg->msg_data, &msg->rsp[11], +- msg->rsp_size - 12); +- if (deliver_response(intf, recv_msg)) +- ipmi_inc_stat(intf, unhandled_commands); +- else +- ipmi_inc_stat(intf, handled_commands); +- } ++ /* ++ * We chop off 12, not 11 bytes because the checksum ++ * at the end also needs to be removed. ++ */ ++ recv_msg->msg.data_len = msg->rsp_size - 12; ++ memcpy(recv_msg->msg_data, &msg->rsp[11], ++ msg->rsp_size - 12); ++ if (deliver_response(intf, recv_msg)) ++ ipmi_inc_stat(intf, unhandled_commands); ++ else ++ ipmi_inc_stat(intf, handled_commands); ++ } else { ++ /* ++ * We couldn't allocate memory for the message, so ++ * requeue it for handling later. ++ */ ++ rv = 1; + } + + return rv; +@@ -4282,7 +4251,7 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, + unsigned char chan; + struct ipmi_user *user = NULL; + struct ipmi_system_interface_addr *smi_addr; +- struct ipmi_recv_msg *recv_msg; ++ struct ipmi_recv_msg *recv_msg = NULL; + + /* + * We expect the OEM SW to perform error checking +@@ -4311,9 +4280,8 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, + rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); + if (rcvr) { + user = rcvr->user; +- kref_get(&user->refcount); +- } else +- user = NULL; ++ recv_msg = ipmi_alloc_recv_msg(user); ++ } + rcu_read_unlock(); + + if (user == NULL) { +@@ -4326,48 +4294,42 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, + */ + + rv = 0; +- } else { +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { +- /* +- * We couldn't allocate memory for the +- * message, so requeue it for handling +- * later. +- */ +- rv = 1; +- kref_put(&user->refcount, free_user); +- } else { +- /* +- * OEM Messages are expected to be delivered via +- * the system interface to SMS software. We might +- * need to visit this again depending on OEM +- * requirements +- */ +- smi_addr = ((struct ipmi_system_interface_addr *) +- &recv_msg->addr); +- smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; +- smi_addr->channel = IPMI_BMC_CHANNEL; +- smi_addr->lun = msg->rsp[0] & 3; +- +- recv_msg->user = user; +- recv_msg->user_msg_data = NULL; +- recv_msg->recv_type = IPMI_OEM_RECV_TYPE; +- recv_msg->msg.netfn = msg->rsp[0] >> 2; +- recv_msg->msg.cmd = msg->rsp[1]; +- recv_msg->msg.data = recv_msg->msg_data; ++ } else if (!IS_ERR(recv_msg)) { ++ /* ++ * OEM Messages are expected to be delivered via ++ * the system interface to SMS software. We might ++ * need to visit this again depending on OEM ++ * requirements ++ */ ++ smi_addr = ((struct ipmi_system_interface_addr *) ++ &recv_msg->addr); ++ smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; ++ smi_addr->channel = IPMI_BMC_CHANNEL; ++ smi_addr->lun = msg->rsp[0] & 3; ++ ++ recv_msg->user_msg_data = NULL; ++ recv_msg->recv_type = IPMI_OEM_RECV_TYPE; ++ recv_msg->msg.netfn = msg->rsp[0] >> 2; ++ recv_msg->msg.cmd = msg->rsp[1]; ++ recv_msg->msg.data = recv_msg->msg_data; + +- /* +- * The message starts at byte 4 which follows the +- * Channel Byte in the "GET MESSAGE" command +- */ +- recv_msg->msg.data_len = msg->rsp_size - 4; +- memcpy(recv_msg->msg_data, &msg->rsp[4], +- msg->rsp_size - 4); +- if (deliver_response(intf, recv_msg)) +- ipmi_inc_stat(intf, unhandled_commands); +- else +- ipmi_inc_stat(intf, handled_commands); +- } ++ /* ++ * The message starts at byte 4 which follows the ++ * Channel Byte in the "GET MESSAGE" command ++ */ ++ recv_msg->msg.data_len = msg->rsp_size - 4; ++ memcpy(recv_msg->msg_data, &msg->rsp[4], ++ msg->rsp_size - 4); ++ if (deliver_response(intf, recv_msg)) ++ ipmi_inc_stat(intf, unhandled_commands); ++ else ++ ipmi_inc_stat(intf, handled_commands); ++ } else { ++ /* ++ * We couldn't allocate memory for the message, so ++ * requeue it for handling later. ++ */ ++ rv = 1; + } + + return rv; +@@ -4426,8 +4388,8 @@ static int handle_read_event_rsp(struct ipmi_smi *intf, + if (!user->gets_events) + continue; + +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { ++ recv_msg = ipmi_alloc_recv_msg(user); ++ if (IS_ERR(recv_msg)) { + rcu_read_unlock(); + list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, + link) { +@@ -4446,8 +4408,6 @@ static int handle_read_event_rsp(struct ipmi_smi *intf, + deliver_count++; + + copy_event_into_recv_msg(recv_msg, msg); +- recv_msg->user = user; +- kref_get(&user->refcount); + list_add_tail(&recv_msg->link, &msgs); + } + srcu_read_unlock(&intf->users_srcu, index); +@@ -4463,8 +4423,8 @@ static int handle_read_event_rsp(struct ipmi_smi *intf, + * No one to receive the message, put it in queue if there's + * not already too many things in the queue. + */ +- recv_msg = ipmi_alloc_recv_msg(); +- if (!recv_msg) { ++ recv_msg = ipmi_alloc_recv_msg(NULL); ++ if (IS_ERR(recv_msg)) { + /* + * We couldn't allocate memory for the + * message, so requeue it for handling +@@ -5156,27 +5116,51 @@ static void free_recv_msg(struct ipmi_recv_msg *msg) + kfree(msg); + } + +-static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) ++static struct ipmi_recv_msg *ipmi_alloc_recv_msg(struct ipmi_user *user) + { + struct ipmi_recv_msg *rv; + ++ if (user) { ++ if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { ++ atomic_dec(&user->nr_msgs); ++ return ERR_PTR(-EBUSY); ++ } ++ } ++ + rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC); +- if (rv) { +- rv->user = NULL; +- rv->done = free_recv_msg; +- atomic_inc(&recv_msg_inuse_count); ++ if (!rv) { ++ if (user) ++ atomic_dec(&user->nr_msgs); ++ return ERR_PTR(-ENOMEM); + } ++ ++ rv->user = user; ++ rv->done = free_recv_msg; ++ if (user) ++ kref_get(&user->refcount); ++ atomic_inc(&recv_msg_inuse_count); + return rv; + } + + void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) + { +- if (msg->user && !oops_in_progress) ++ if (msg->user && !oops_in_progress) { ++ atomic_dec(&msg->user->nr_msgs); + kref_put(&msg->user->refcount, free_user); ++ } + msg->done(msg); + } + EXPORT_SYMBOL(ipmi_free_recv_msg); + ++static void ipmi_set_recv_msg_user(struct ipmi_recv_msg *msg, ++ struct ipmi_user *user) ++{ ++ WARN_ON_ONCE(msg->user); /* User should not be set. */ ++ msg->user = user; ++ atomic_inc(&user->nr_msgs); ++ kref_get(&user->refcount); ++} ++ + static atomic_t panic_done_count = ATOMIC_INIT(0); + + static void dummy_smi_done_handler(struct ipmi_smi_msg *msg) +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index c71e61ccb95a2b..5e6ee5b82b8ff4 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -977,8 +977,8 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, + * will call disable_irq which undoes all of the above. + */ + if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { +- tpm_tis_write8(priv, original_int_vec, +- TPM_INT_VECTOR(priv->locality)); ++ tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), ++ original_int_vec); + rc = -1; + } + +diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c +index c173a44c800aa8..629f050a855aae 100644 +--- a/drivers/clk/at91/clk-peripheral.c ++++ b/drivers/clk/at91/clk-peripheral.c +@@ -279,8 +279,11 @@ static int clk_sam9x5_peripheral_determine_rate(struct clk_hw *hw, + long best_diff = LONG_MIN; + u32 shift; + +- if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) +- return parent_rate; ++ if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) { ++ req->rate = parent_rate; ++ ++ return 0; ++ } + + /* Fist step: check the available dividers. */ + for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) { +diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c +index dfba6eb61ccfee..4ecdf9ae024439 100644 +--- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c ++++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c +@@ -103,7 +103,7 @@ static const struct mtk_gate infra_ao_clks[] = { + GATE_INFRA_AO0(CLK_INFRA_AO_CQ_DMA_FPC, "infra_ao_cq_dma_fpc", "fpc", 28), + GATE_INFRA_AO0(CLK_INFRA_AO_UART5, "infra_ao_uart5", "top_uart", 29), + /* INFRA_AO1 */ +- GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "clk26m", 0), ++ GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "top_hdmi_xtal", 0), + GATE_INFRA_AO1(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "top_spi", 1), + GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0, "infra_ao_msdc0", "top_msdc50_0_hclk", 2), + GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1, "infra_ao_msdc1", "top_axi", 4), +diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c +index c93bc7f926e5d4..359f92df826b5e 100644 +--- a/drivers/clk/mediatek/clk-mux.c ++++ b/drivers/clk/mediatek/clk-mux.c +@@ -132,9 +132,7 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index) + static int mtk_clk_mux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { +- struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); +- +- return clk_mux_determine_rate_flags(hw, req, mux->data->flags); ++ return clk_mux_determine_rate_flags(hw, req, 0); + } + + const struct clk_ops mtk_mux_clr_set_upd_ops = { +diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c +index 69ebf65081b81f..bbd7d64038fab5 100644 +--- a/drivers/clk/nxp/clk-lpc18xx-cgu.c ++++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c +@@ -371,23 +371,25 @@ static unsigned long lpc18xx_pll0_recalc_rate(struct clk_hw *hw, + return 0; + } + +-static long lpc18xx_pll0_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *prate) ++static int lpc18xx_pll0_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) + { + unsigned long m; + +- if (*prate < rate) { ++ if (req->best_parent_rate < req->rate) { + pr_warn("%s: pll dividers not supported\n", __func__); + return -EINVAL; + } + +- m = DIV_ROUND_UP_ULL(*prate, rate * 2); +- if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { +- pr_warn("%s: unable to support rate %lu\n", __func__, rate); ++ m = DIV_ROUND_UP_ULL(req->best_parent_rate, req->rate * 2); ++ if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { ++ pr_warn("%s: unable to support rate %lu\n", __func__, req->rate); + return -EINVAL; + } + +- return 2 * *prate * m; ++ req->rate = 2 * req->best_parent_rate * m; ++ ++ return 0; + } + + static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -403,7 +405,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, + } + + m = DIV_ROUND_UP_ULL(parent_rate, rate * 2); +- if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { ++ if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { + pr_warn("%s: unable to support rate %lu\n", __func__, rate); + return -EINVAL; + } +@@ -444,7 +446,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, + + static const struct clk_ops lpc18xx_pll0_ops = { + .recalc_rate = lpc18xx_pll0_recalc_rate, +- .round_rate = lpc18xx_pll0_round_rate, ++ .determine_rate = lpc18xx_pll0_determine_rate, + .set_rate = lpc18xx_pll0_set_rate, + }; + +diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c +index 7bfba0afd77831..4ec408c3a26aa4 100644 +--- a/drivers/clk/tegra/clk-bpmp.c ++++ b/drivers/clk/tegra/clk-bpmp.c +@@ -635,7 +635,7 @@ static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp, + + bpmp->num_clocks = count; + +- bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(struct tegra_bpmp_clk), GFP_KERNEL); ++ bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(*bpmp->clocks), GFP_KERNEL); + if (!bpmp->clocks) + return -ENOMEM; + +diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c +index e95fdc49c2269c..bbceb0289d457a 100644 +--- a/drivers/clocksource/clps711x-timer.c ++++ b/drivers/clocksource/clps711x-timer.c +@@ -78,24 +78,33 @@ static int __init clps711x_timer_init(struct device_node *np) + unsigned int irq = irq_of_parse_and_map(np, 0); + struct clk *clock = of_clk_get(np, 0); + void __iomem *base = of_iomap(np, 0); ++ int ret = 0; + + if (!base) + return -ENOMEM; +- if (!irq) +- return -EINVAL; +- if (IS_ERR(clock)) +- return PTR_ERR(clock); ++ if (!irq) { ++ ret = -EINVAL; ++ goto unmap_io; ++ } ++ if (IS_ERR(clock)) { ++ ret = PTR_ERR(clock); ++ goto unmap_io; ++ } + + switch (of_alias_get_id(np, "timer")) { + case CLPS711X_CLKSRC_CLOCKSOURCE: + clps711x_clksrc_init(clock, base); + break; + case CLPS711X_CLKSRC_CLOCKEVENT: +- return _clps711x_clkevt_init(clock, base, irq); ++ ret = _clps711x_clkevt_init(clock, base, irq); ++ break; + default: +- return -EINVAL; ++ ret = -EINVAL; ++ break; + } + +- return 0; ++unmap_io: ++ iounmap(base); ++ return ret; + } + TIMER_OF_DECLARE(clps711x, "cirrus,ep7209-timer", clps711x_timer_init); +diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c +index ed782c0b48af25..60b4e3b608c006 100644 +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -1341,10 +1341,10 @@ static void update_qos_request(enum freq_qos_req_type type) + continue; + + req = policy->driver_data; +- cpufreq_cpu_put(policy); +- +- if (!req) ++ if (!req) { ++ cpufreq_cpu_put(policy); + continue; ++ } + + if (hwp_active) + intel_pstate_get_hwp_cap(cpu); +@@ -1360,6 +1360,8 @@ static void update_qos_request(enum freq_qos_req_type type) + + if (freq_qos_update_request(req, freq) < 0) + pr_warn("Failed to update freq constraint: CPU%d\n", i); ++ ++ cpufreq_cpu_put(policy); + } + } + +diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c +index 7b8fcfa55038bc..39186008afbfdf 100644 +--- a/drivers/cpufreq/tegra186-cpufreq.c ++++ b/drivers/cpufreq/tegra186-cpufreq.c +@@ -86,10 +86,14 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy, + { + struct tegra186_cpufreq_data *data = cpufreq_get_driver_data(); + struct cpufreq_frequency_table *tbl = policy->freq_table + index; +- unsigned int edvd_offset = data->cpus[policy->cpu].edvd_offset; ++ unsigned int edvd_offset; + u32 edvd_val = tbl->driver_data; ++ u32 cpu; + +- writel(edvd_val, data->regs + edvd_offset); ++ for_each_cpu(cpu, policy->cpus) { ++ edvd_offset = data->cpus[cpu].edvd_offset; ++ writel(edvd_val, data->regs + edvd_offset); ++ } + + return 0; + } +diff --git a/drivers/crypto/aspeed/aspeed-hace-crypto.c b/drivers/crypto/aspeed/aspeed-hace-crypto.c +index f0eddb7854e5d8..15e843b4854d0a 100644 +--- a/drivers/crypto/aspeed/aspeed-hace-crypto.c ++++ b/drivers/crypto/aspeed/aspeed-hace-crypto.c +@@ -346,7 +346,7 @@ static int aspeed_sk_start_sg(struct aspeed_hace_dev *hace_dev) + + } else { + dma_unmap_sg(hace_dev->dev, req->dst, rctx->dst_nents, +- DMA_TO_DEVICE); ++ DMA_FROM_DEVICE); + dma_unmap_sg(hace_dev->dev, req->src, rctx->src_nents, + DMA_TO_DEVICE); + } +diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c +index 099b32a10dd753..d234495f1115b8 100644 +--- a/drivers/crypto/atmel-tdes.c ++++ b/drivers/crypto/atmel-tdes.c +@@ -548,7 +548,7 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd) + + if (err && (dd->flags & TDES_FLAGS_FAST)) { + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); +- dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); + } + + return err; +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index 29c9537216fa6d..8f3406289df430 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -252,7 +252,7 @@ static void rk_hash_unprepare(struct crypto_engine *engine, void *breq) + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct rk_crypto_info *rkc = rctx->dev; + +- dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ dma_unmap_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + } + + static int rk_hash_run(struct crypto_engine *engine, void *breq) +diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c +index 9a2656d73600b5..b39f395c077eeb 100644 +--- a/drivers/firmware/meson/meson_sm.c ++++ b/drivers/firmware/meson/meson_sm.c +@@ -225,11 +225,16 @@ EXPORT_SYMBOL(meson_sm_call_write); + struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node) + { + struct platform_device *pdev = of_find_device_by_node(sm_node); ++ struct meson_sm_firmware *fw; + + if (!pdev) + return NULL; + +- return platform_get_drvdata(pdev); ++ fw = platform_get_drvdata(pdev); ++ ++ put_device(&pdev->dev); ++ ++ return fw; + } + EXPORT_SYMBOL_GPL(meson_sm_get); + +diff --git a/drivers/gpio/gpio-wcd934x.c b/drivers/gpio/gpio-wcd934x.c +index cfa7b0a50c8e33..03b16b8f639ad0 100644 +--- a/drivers/gpio/gpio-wcd934x.c ++++ b/drivers/gpio/gpio-wcd934x.c +@@ -102,7 +102,7 @@ static int wcd_gpio_probe(struct platform_device *pdev) + chip->base = -1; + chip->ngpio = WCD934X_NPINS; + chip->label = dev_name(dev); +- chip->can_sleep = false; ++ chip->can_sleep = true; + + return devm_gpiochip_add_data(dev, chip, data); + } +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +index 670d5ab9d9984f..f97c1826770825 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +@@ -154,10 +154,13 @@ static bool dce60_setup_scaling_configuration( + REG_SET(SCL_BYPASS_CONTROL, 0, SCL_BYPASS_MODE, 0); + + if (data->taps.h_taps + data->taps.v_taps <= 2) { +- /* Set bypass */ +- +- /* DCE6 has no SCL_MODE register, skip scale mode programming */ ++ /* Disable scaler functionality */ ++ REG_WRITE(SCL_SCALER_ENABLE, 0); + ++ /* Clear registers that can cause glitches even when the scaler is off */ ++ REG_WRITE(SCL_TAP_CONTROL, 0); ++ REG_WRITE(SCL_AUTOMATIC_MODE_CONTROL, 0); ++ REG_WRITE(SCL_F_SHARP_CONTROL, 0); + return false; + } + +@@ -165,7 +168,7 @@ static bool dce60_setup_scaling_configuration( + SCL_H_NUM_OF_TAPS, data->taps.h_taps - 1, + SCL_V_NUM_OF_TAPS, data->taps.v_taps - 1); + +- /* DCE6 has no SCL_MODE register, skip scale mode programming */ ++ REG_WRITE(SCL_SCALER_ENABLE, 1); + + /* DCE6 has no SCL_BOUNDARY_MODE bit, skip replace out of bound pixels */ + +@@ -502,6 +505,8 @@ static void dce60_transform_set_scaler( + REG_SET(DC_LB_MEM_SIZE, 0, + DC_LB_MEM_SIZE, xfm_dce->lb_memory_size); + ++ REG_WRITE(SCL_UPDATE, 0x00010000); ++ + /* Clear SCL_F_SHARP_CONTROL value to 0 */ + REG_WRITE(SCL_F_SHARP_CONTROL, 0); + +@@ -527,8 +532,7 @@ static void dce60_transform_set_scaler( + if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) { + /* 4. Program vertical filters */ + if (xfm_dce->filter_v == NULL) +- REG_SET(SCL_VERT_FILTER_CONTROL, 0, +- SCL_V_2TAP_HARDCODE_COEF_EN, 0); ++ REG_WRITE(SCL_VERT_FILTER_CONTROL, 0); + program_multi_taps_filter( + xfm_dce, + data->taps.v_taps, +@@ -542,8 +546,7 @@ static void dce60_transform_set_scaler( + + /* 5. Program horizontal filters */ + if (xfm_dce->filter_h == NULL) +- REG_SET(SCL_HORZ_FILTER_CONTROL, 0, +- SCL_H_2TAP_HARDCODE_COEF_EN, 0); ++ REG_WRITE(SCL_HORZ_FILTER_CONTROL, 0); + program_multi_taps_filter( + xfm_dce, + data->taps.h_taps, +@@ -566,6 +569,8 @@ static void dce60_transform_set_scaler( + /* DCE6 has no SCL_COEF_UPDATE_COMPLETE bit to flip to new coefficient memory */ + + /* DCE6 DATA_FORMAT register does not support ALPHA_EN */ ++ ++ REG_WRITE(SCL_UPDATE, 0); + } + #endif + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h +index cbce194ec7b82b..eb716e8337e236 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h +@@ -155,6 +155,9 @@ + SRI(SCL_COEF_RAM_TAP_DATA, SCL, id), \ + SRI(VIEWPORT_START, SCL, id), \ + SRI(VIEWPORT_SIZE, SCL, id), \ ++ SRI(SCL_SCALER_ENABLE, SCL, id), \ ++ SRI(SCL_HORZ_FILTER_INIT_RGB_LUMA, SCL, id), \ ++ SRI(SCL_HORZ_FILTER_INIT_CHROMA, SCL, id), \ + SRI(SCL_HORZ_FILTER_SCALE_RATIO, SCL, id), \ + SRI(SCL_VERT_FILTER_SCALE_RATIO, SCL, id), \ + SRI(SCL_VERT_FILTER_INIT, SCL, id), \ +@@ -590,6 +593,7 @@ struct dce_transform_registers { + uint32_t SCL_VERT_FILTER_SCALE_RATIO; + uint32_t SCL_HORZ_FILTER_INIT; + #if defined(CONFIG_DRM_AMD_DC_SI) ++ uint32_t SCL_SCALER_ENABLE; + uint32_t SCL_HORZ_FILTER_INIT_RGB_LUMA; + uint32_t SCL_HORZ_FILTER_INIT_CHROMA; + #endif +diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h +index 9de01ae574c035..067eddd9c62d80 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h +@@ -4115,6 +4115,7 @@ + #define mmSCL0_SCL_COEF_RAM_CONFLICT_STATUS 0x1B55 + #define mmSCL0_SCL_COEF_RAM_SELECT 0x1B40 + #define mmSCL0_SCL_COEF_RAM_TAP_DATA 0x1B41 ++#define mmSCL0_SCL_SCALER_ENABLE 0x1B42 + #define mmSCL0_SCL_CONTROL 0x1B44 + #define mmSCL0_SCL_DEBUG 0x1B6A + #define mmSCL0_SCL_DEBUG2 0x1B69 +@@ -4144,6 +4145,7 @@ + #define mmSCL1_SCL_COEF_RAM_CONFLICT_STATUS 0x1E55 + #define mmSCL1_SCL_COEF_RAM_SELECT 0x1E40 + #define mmSCL1_SCL_COEF_RAM_TAP_DATA 0x1E41 ++#define mmSCL1_SCL_SCALER_ENABLE 0x1E42 + #define mmSCL1_SCL_CONTROL 0x1E44 + #define mmSCL1_SCL_DEBUG 0x1E6A + #define mmSCL1_SCL_DEBUG2 0x1E69 +@@ -4173,6 +4175,7 @@ + #define mmSCL2_SCL_COEF_RAM_CONFLICT_STATUS 0x4155 + #define mmSCL2_SCL_COEF_RAM_SELECT 0x4140 + #define mmSCL2_SCL_COEF_RAM_TAP_DATA 0x4141 ++#define mmSCL2_SCL_SCALER_ENABLE 0x4142 + #define mmSCL2_SCL_CONTROL 0x4144 + #define mmSCL2_SCL_DEBUG 0x416A + #define mmSCL2_SCL_DEBUG2 0x4169 +@@ -4202,6 +4205,7 @@ + #define mmSCL3_SCL_COEF_RAM_CONFLICT_STATUS 0x4455 + #define mmSCL3_SCL_COEF_RAM_SELECT 0x4440 + #define mmSCL3_SCL_COEF_RAM_TAP_DATA 0x4441 ++#define mmSCL3_SCL_SCALER_ENABLE 0x4442 + #define mmSCL3_SCL_CONTROL 0x4444 + #define mmSCL3_SCL_DEBUG 0x446A + #define mmSCL3_SCL_DEBUG2 0x4469 +@@ -4231,6 +4235,7 @@ + #define mmSCL4_SCL_COEF_RAM_CONFLICT_STATUS 0x4755 + #define mmSCL4_SCL_COEF_RAM_SELECT 0x4740 + #define mmSCL4_SCL_COEF_RAM_TAP_DATA 0x4741 ++#define mmSCL4_SCL_SCALER_ENABLE 0x4742 + #define mmSCL4_SCL_CONTROL 0x4744 + #define mmSCL4_SCL_DEBUG 0x476A + #define mmSCL4_SCL_DEBUG2 0x4769 +@@ -4260,6 +4265,7 @@ + #define mmSCL5_SCL_COEF_RAM_CONFLICT_STATUS 0x4A55 + #define mmSCL5_SCL_COEF_RAM_SELECT 0x4A40 + #define mmSCL5_SCL_COEF_RAM_TAP_DATA 0x4A41 ++#define mmSCL5_SCL_SCALER_ENABLE 0x4A42 + #define mmSCL5_SCL_CONTROL 0x4A44 + #define mmSCL5_SCL_DEBUG 0x4A6A + #define mmSCL5_SCL_DEBUG2 0x4A69 +@@ -4287,6 +4293,7 @@ + #define mmSCL_COEF_RAM_CONFLICT_STATUS 0x1B55 + #define mmSCL_COEF_RAM_SELECT 0x1B40 + #define mmSCL_COEF_RAM_TAP_DATA 0x1B41 ++#define mmSCL_SCALER_ENABLE 0x1B42 + #define mmSCL_CONTROL 0x1B44 + #define mmSCL_DEBUG 0x1B6A + #define mmSCL_DEBUG2 0x1B69 +diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h +index bd8085ec54ed57..da5596fbfdcb31 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h +@@ -8648,6 +8648,8 @@ + #define REGAMMA_LUT_INDEX__REGAMMA_LUT_INDEX__SHIFT 0x00000000 + #define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK_MASK 0x00000007L + #define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK__SHIFT 0x00000000 ++#define SCL_SCALER_ENABLE__SCL_SCALE_EN_MASK 0x00000001L ++#define SCL_SCALER_ENABLE__SCL_SCALE_EN__SHIFT 0x00000000 + #define SCL_ALU_CONTROL__SCL_ALU_DISABLE_MASK 0x00000001L + #define SCL_ALU_CONTROL__SCL_ALU_DISABLE__SHIFT 0x00000000 + #define SCL_BYPASS_CONTROL__SCL_BYPASS_MODE_MASK 0x00000003L +diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +index 036ee034397283..11f164a15d7c21 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bo.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -836,7 +836,7 @@ nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo, + nvif_vmm_put(vmm, &old_mem->vma[1]); + nvif_vmm_put(vmm, &old_mem->vma[0]); + } +- return 0; ++ return ret; + } + + static int +diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +index 92f4261305bd9d..f2ae5d17ea601e 100644 +--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c ++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +@@ -576,7 +576,10 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi, + udelay(10); + rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL); + +- ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN; ++ rcar_mipi_dsi_clr(dsi, TXSETR, TXSETR_LANECNT_MASK); ++ rcar_mipi_dsi_set(dsi, TXSETR, dsi->lanes - 1); ++ ++ ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN; + rcar_mipi_dsi_write(dsi, PPISETR, ppisetr); + + rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ); +diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +index a6b276f1d6ee15..a54c7eb4113b93 100644 +--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h ++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +@@ -12,6 +12,9 @@ + #define LINKSR_LPBUSY (1 << 1) + #define LINKSR_HSBUSY (1 << 0) + ++#define TXSETR 0x100 ++#define TXSETR_LANECNT_MASK (0x3 << 0) ++ + /* + * Video Mode Register + */ +@@ -80,10 +83,7 @@ + * PHY-Protocol Interface (PPI) Registers + */ + #define PPISETR 0x700 +-#define PPISETR_DLEN_0 (0x1 << 0) +-#define PPISETR_DLEN_1 (0x3 << 0) +-#define PPISETR_DLEN_2 (0x7 << 0) +-#define PPISETR_DLEN_3 (0xf << 0) ++#define PPISETR_DLEN_MASK (0xf << 0) + #define PPISETR_CLEN (1 << 8) + + #define PPICLCR 0x710 +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index b129ce873af3f2..b235e7cc41f3f8 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -1514,6 +1514,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, + SVGA3dCmdHeader *header) + { + struct vmw_bo *vmw_bo = NULL; ++ struct vmw_resource *res; + struct vmw_surface *srf = NULL; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceDMA); + int ret; +@@ -1549,18 +1550,24 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, + + dirty = (cmd->body.transfer == SVGA3D_WRITE_HOST_VRAM) ? + VMW_RES_DIRTY_SET : 0; +- ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, +- dirty, user_surface_converter, +- &cmd->body.host.sid, NULL); ++ ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, dirty, ++ user_surface_converter, &cmd->body.host.sid, ++ NULL); + if (unlikely(ret != 0)) { + if (unlikely(ret != -ERESTARTSYS)) + VMW_DEBUG_USER("could not find surface for DMA.\n"); + return ret; + } + +- srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); ++ res = sw_context->res_cache[vmw_res_surface].res; ++ if (!res) { ++ VMW_DEBUG_USER("Invalid DMA surface.\n"); ++ return -EINVAL; ++ } + +- vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->tbo, header); ++ srf = vmw_res_to_srf(res); ++ vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->tbo, ++ header); + + return 0; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +index aaacbdcbd742fb..946f166d6fc765 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +@@ -326,8 +326,10 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, + hash_add_rcu(ctx->sw_context->res_ht, &node->hash.head, node->hash.key); + } + node->res = vmw_resource_reference_unless_doomed(res); +- if (!node->res) ++ if (!node->res) { ++ hash_del_rcu(&node->hash.head); + return -ESRCH; ++ } + + node->first_usage = 1; + if (!res->dev_priv->has_mob) { +@@ -654,7 +656,7 @@ void vmw_validation_drop_ht(struct vmw_validation_context *ctx) + hash_del_rcu(&val->hash.head); + + list_for_each_entry(val, &ctx->resource_ctx_list, head) +- hash_del_rcu(&entry->hash.head); ++ hash_del_rcu(&val->hash.head); + + ctx->sw_context = NULL; + } +diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c +index f52abf759260f2..5de86a953d4182 100644 +--- a/drivers/iio/adc/xilinx-ams.c ++++ b/drivers/iio/adc/xilinx-ams.c +@@ -118,7 +118,7 @@ + #define AMS_ALARM_THRESHOLD_OFF_10 0x10 + #define AMS_ALARM_THRESHOLD_OFF_20 0x20 + +-#define AMS_ALARM_THR_DIRECT_MASK BIT(1) ++#define AMS_ALARM_THR_DIRECT_MASK BIT(0) + #define AMS_ALARM_THR_MIN 0x0000 + #define AMS_ALARM_THR_MAX (BIT(16) - 1) + +@@ -385,6 +385,29 @@ static void ams_update_pl_alarm(struct ams *ams, unsigned long alarm_mask) + ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg); + } + ++static void ams_unmask(struct ams *ams) ++{ ++ unsigned int status, unmask; ++ ++ status = readl(ams->base + AMS_ISR_0); ++ ++ /* Clear those bits which are not active anymore */ ++ unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm; ++ ++ /* Clear status of disabled alarm */ ++ unmask |= ams->intr_mask; ++ ++ ams->current_masked_alarm &= status; ++ ++ /* Also clear those which are masked out anyway */ ++ ams->current_masked_alarm &= ~ams->intr_mask; ++ ++ /* Clear the interrupts before we unmask them */ ++ writel(unmask, ams->base + AMS_ISR_0); ++ ++ ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK); ++} ++ + static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask) + { + unsigned long flags; +@@ -397,6 +420,7 @@ static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask) + + spin_lock_irqsave(&ams->intr_lock, flags); + ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask); ++ ams_unmask(ams); + spin_unlock_irqrestore(&ams->intr_lock, flags); + } + +@@ -1025,28 +1049,9 @@ static void ams_handle_events(struct iio_dev *indio_dev, unsigned long events) + static void ams_unmask_worker(struct work_struct *work) + { + struct ams *ams = container_of(work, struct ams, ams_unmask_work.work); +- unsigned int status, unmask; + + spin_lock_irq(&ams->intr_lock); +- +- status = readl(ams->base + AMS_ISR_0); +- +- /* Clear those bits which are not active anymore */ +- unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm; +- +- /* Clear status of disabled alarm */ +- unmask |= ams->intr_mask; +- +- ams->current_masked_alarm &= status; +- +- /* Also clear those which are masked out anyway */ +- ams->current_masked_alarm &= ~ams->intr_mask; +- +- /* Clear the interrupts before we unmask them */ +- writel(unmask, ams->base + AMS_ISR_0); +- +- ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK); +- ++ ams_unmask(ams); + spin_unlock_irq(&ams->intr_lock); + + /* If still pending some alarm re-trigger the timer */ +diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c +index e0b7f658d61196..cf9cf90cd6e276 100644 +--- a/drivers/iio/dac/ad5360.c ++++ b/drivers/iio/dac/ad5360.c +@@ -262,7 +262,7 @@ static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set, + unsigned int clr) + { + struct ad5360_state *st = iio_priv(indio_dev); +- unsigned int ret; ++ int ret; + + mutex_lock(&st->lock); + +diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c +index 7644acfd879e04..9228e3cee1b850 100644 +--- a/drivers/iio/dac/ad5421.c ++++ b/drivers/iio/dac/ad5421.c +@@ -186,7 +186,7 @@ static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set, + unsigned int clr) + { + struct ad5421_state *st = iio_priv(indio_dev); +- unsigned int ret; ++ int ret; + + mutex_lock(&st->lock); + +diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c +index 4abf80f75ef5d9..03e75261e891fe 100644 +--- a/drivers/iio/frequency/adf4350.c ++++ b/drivers/iio/frequency/adf4350.c +@@ -143,6 +143,19 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) + if (freq > ADF4350_MAX_OUT_FREQ || freq < st->min_out_freq) + return -EINVAL; + ++ st->r4_rf_div_sel = 0; ++ ++ /* ++ * !\TODO: The below computation is making sure we get a power of 2 ++ * shift (st->r4_rf_div_sel) so that freq becomes higher or equal to ++ * ADF4350_MIN_VCO_FREQ. This might be simplified with fls()/fls_long() ++ * and friends. ++ */ ++ while (freq < ADF4350_MIN_VCO_FREQ) { ++ freq <<= 1; ++ st->r4_rf_div_sel++; ++ } ++ + if (freq > ADF4350_MAX_FREQ_45_PRESC) { + prescaler = ADF4350_REG1_PRESCALER; + mdiv = 75; +@@ -151,13 +164,6 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) + mdiv = 23; + } + +- st->r4_rf_div_sel = 0; +- +- while (freq < ADF4350_MIN_VCO_FREQ) { +- freq <<= 1; +- st->r4_rf_div_sel++; +- } +- + /* + * Allow a predefined reference division factor + * if not set, compute our own +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +index 91c181bb92869d..a1f055014cc652 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +@@ -747,10 +747,6 @@ static int inv_icm42600_resume(struct device *dev) + if (ret) + goto out_unlock; + +- pm_runtime_disable(dev); +- pm_runtime_set_active(dev); +- pm_runtime_enable(dev); +- + /* restore sensors state */ + ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro, + st->suspended.accel, +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index 88bccdbb0bed08..ac7b8fb36db8fb 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -4415,7 +4415,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) + } + + if (info->ats_supported && ecap_prs(iommu->ecap) && +- pci_pri_supported(pdev)) ++ ecap_pds(iommu->ecap) && pci_pri_supported(pdev)) + info->pri_supported = 1; + } + } +diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c +index 57289966915492..2d20cf9d84cead 100644 +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -248,11 +248,11 @@ static int plic_irq_suspend(void) + + priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; + +- for (i = 0; i < priv->nr_irqs; i++) +- if (readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)) +- __set_bit(i, priv->prio_save); +- else +- __clear_bit(i, priv->prio_save); ++ /* irq ID 0 is reserved */ ++ for (i = 1; i < priv->nr_irqs; i++) { ++ __assign_bit(i, priv->prio_save, ++ readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)); ++ } + + for_each_cpu(cpu, cpu_present_mask) { + struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu); +@@ -279,7 +279,8 @@ static void plic_irq_resume(void) + + priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; + +- for (i = 0; i < priv->nr_irqs; i++) { ++ /* irq ID 0 is reserved */ ++ for (i = 1; i < priv->nr_irqs; i++) { + index = BIT_WORD(i); + writel((priv->prio_save[index] & BIT_MASK(i)) ? 1 : 0, + priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); +diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c +index e4fcac97dbfaa0..90f248ef2a1fcc 100644 +--- a/drivers/mailbox/zynqmp-ipi-mailbox.c ++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c +@@ -616,11 +616,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata) + i = pdata->num_mboxes; + for (; i >= 0; i--) { + ipi_mbox = &pdata->ipi_mboxes[i]; +- if (ipi_mbox->dev.parent) { +- mbox_controller_unregister(&ipi_mbox->mbox); +- if (device_is_registered(&ipi_mbox->dev)) +- device_unregister(&ipi_mbox->dev); +- } ++ if (device_is_registered(&ipi_mbox->dev)) ++ device_unregister(&ipi_mbox->dev); + } + } + +diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c +index 1f7edc0f5b1abe..a184fd9fc6f3b3 100644 +--- a/drivers/media/i2c/mt9v111.c ++++ b/drivers/media/i2c/mt9v111.c +@@ -534,8 +534,8 @@ static int mt9v111_calc_frame_rate(struct mt9v111_dev *mt9v111, + static int mt9v111_hw_config(struct mt9v111_dev *mt9v111) + { + struct i2c_client *c = mt9v111->client; +- unsigned int ret; + u16 outfmtctrl2; ++ int ret; + + /* Force device reset. */ + ret = __mt9v111_hw_reset(mt9v111); +diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c +index 94abd042045dab..6fd8885f5928e4 100644 +--- a/drivers/media/mc/mc-devnode.c ++++ b/drivers/media/mc/mc-devnode.c +@@ -50,11 +50,6 @@ static void media_devnode_release(struct device *cd) + { + struct media_devnode *devnode = to_media_devnode(cd); + +- mutex_lock(&media_devnode_lock); +- /* Mark device node number as free */ +- clear_bit(devnode->minor, media_devnode_nums); +- mutex_unlock(&media_devnode_lock); +- + /* Release media_devnode and perform other cleanups as needed. */ + if (devnode->release) + devnode->release(devnode); +@@ -283,6 +278,7 @@ void media_devnode_unregister(struct media_devnode *devnode) + /* Delete the cdev on this minor as well */ + cdev_device_del(&devnode->cdev, &devnode->dev); + devnode->media_dev = NULL; ++ clear_bit(devnode->minor, media_devnode_nums); + mutex_unlock(&media_devnode_lock); + + put_device(&devnode->dev); +diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c +index 951b79ca125cdd..f885e718524c22 100644 +--- a/drivers/media/mc/mc-entity.c ++++ b/drivers/media/mc/mc-entity.c +@@ -678,7 +678,7 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, + * (already discovered through iterating over links) and pads + * not internally connected. + */ +- if (origin == local || !local->num_links || ++ if (origin == local || local->num_links || + !media_entity_has_pad_interdep(origin->entity, origin->index, + local->index)) + continue; +diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c +index 013694bfcb1c1b..7cbb2d5869320b 100644 +--- a/drivers/media/pci/cx18/cx18-queue.c ++++ b/drivers/media/pci/cx18/cx18-queue.c +@@ -379,15 +379,22 @@ int cx18_stream_alloc(struct cx18_stream *s) + break; + } + ++ buf->dma_handle = dma_map_single(&s->cx->pci_dev->dev, ++ buf->buf, s->buf_size, ++ s->dma); ++ if (dma_mapping_error(&s->cx->pci_dev->dev, buf->dma_handle)) { ++ kfree(buf->buf); ++ kfree(mdl); ++ kfree(buf); ++ break; ++ } ++ + INIT_LIST_HEAD(&mdl->list); + INIT_LIST_HEAD(&mdl->buf_list); + mdl->id = s->mdl_base_idx; /* a somewhat safe value */ + cx18_enqueue(s, mdl, &s->q_idle); + + INIT_LIST_HEAD(&buf->list); +- buf->dma_handle = dma_map_single(&s->cx->pci_dev->dev, +- buf->buf, s->buf_size, +- s->dma); + cx18_buf_sync_for_cpu(s, buf); + list_add_tail(&buf->list, &s->buf_pool); + } +diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c +index b7aaa8b4a7841d..e39bf64c5c715b 100644 +--- a/drivers/media/pci/ivtv/ivtv-irq.c ++++ b/drivers/media/pci/ivtv/ivtv-irq.c +@@ -351,7 +351,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) + + /* Insert buffer block for YUV if needed */ + if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) { +- if (yi->blanking_dmaptr) { ++ if (yi->blanking_ptr) { + s->sg_pending[idx].src = yi->blanking_dmaptr; + s->sg_pending[idx].dst = offset; + s->sg_pending[idx].size = 720 * 16; +diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c +index 2d9274537725af..71f0401066471a 100644 +--- a/drivers/media/pci/ivtv/ivtv-yuv.c ++++ b/drivers/media/pci/ivtv/ivtv-yuv.c +@@ -125,7 +125,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, + ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size); + + /* If we've offset the y plane, ensure top area is blanked */ +- if (f->offset_y && yi->blanking_dmaptr) { ++ if (f->offset_y && yi->blanking_ptr) { + dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); + dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr); + dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]); +@@ -929,6 +929,12 @@ static void ivtv_yuv_init(struct ivtv *itv) + yi->blanking_dmaptr = dma_map_single(&itv->pdev->dev, + yi->blanking_ptr, + 720 * 16, DMA_TO_DEVICE); ++ if (dma_mapping_error(&itv->pdev->dev, yi->blanking_dmaptr)) { ++ kfree(yi->blanking_ptr); ++ yi->blanking_ptr = NULL; ++ yi->blanking_dmaptr = 0; ++ IVTV_DEBUG_WARN("Failed to dma_map yuv blanking buffer\n"); ++ } + } else { + yi->blanking_dmaptr = 0; + IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); +diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c +index fe7da2b3048299..01461b2fed51d8 100644 +--- a/drivers/media/platform/qcom/venus/firmware.c ++++ b/drivers/media/platform/qcom/venus/firmware.c +@@ -30,7 +30,7 @@ static void venus_reset_cpu(struct venus_core *core) + u32 fw_size = core->fw.mapped_mem_size; + void __iomem *wrapper_base; + +- if (IS_IRIS2_1(core)) ++ if (IS_IRIS2(core) || IS_IRIS2_1(core)) + wrapper_base = core->wrapper_tz_base; + else + wrapper_base = core->wrapper_base; +@@ -42,7 +42,7 @@ static void venus_reset_cpu(struct venus_core *core) + writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR); + writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR); + +- if (IS_IRIS2_1(core)) { ++ if (IS_IRIS2(core) || IS_IRIS2_1(core)) { + /* Bring XTSS out of reset */ + writel(0, wrapper_base + WRAPPER_TZ_XTSS_SW_RESET); + } else { +@@ -68,7 +68,7 @@ int venus_set_hw_state(struct venus_core *core, bool resume) + if (resume) { + venus_reset_cpu(core); + } else { +- if (IS_IRIS2_1(core)) ++ if (IS_IRIS2(core) || IS_IRIS2_1(core)) + writel(WRAPPER_XTSS_SW_RESET_BIT, + core->wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); + else +@@ -181,7 +181,7 @@ static int venus_shutdown_no_tz(struct venus_core *core) + void __iomem *wrapper_base = core->wrapper_base; + void __iomem *wrapper_tz_base = core->wrapper_tz_base; + +- if (IS_IRIS2_1(core)) { ++ if (IS_IRIS2(core) || IS_IRIS2_1(core)) { + /* Assert the reset to XTSS */ + reg = readl(wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); + reg |= WRAPPER_XTSS_SW_RESET_BIT; +diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c +index f8901d6fbe9bf1..ff3088691d5e18 100644 +--- a/drivers/media/rc/lirc_dev.c ++++ b/drivers/media/rc/lirc_dev.c +@@ -735,11 +735,11 @@ int lirc_register(struct rc_dev *dev) + + cdev_init(&dev->lirc_cdev, &lirc_fops); + ++ get_device(&dev->dev); ++ + err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev); + if (err) +- goto out_ida; +- +- get_device(&dev->dev); ++ goto out_put_device; + + switch (dev->driver_type) { + case RC_DRIVER_SCANCODE: +@@ -763,7 +763,8 @@ int lirc_register(struct rc_dev *dev) + + return 0; + +-out_ida: ++out_put_device: ++ put_device(&dev->lirc_dev); + ida_free(&lirc_ida, minor); + return err; + } +diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c +index e73dd330af477d..d913fb901973f0 100644 +--- a/drivers/memory/samsung/exynos-srom.c ++++ b/drivers/memory/samsung/exynos-srom.c +@@ -121,20 +121,18 @@ static int exynos_srom_probe(struct platform_device *pdev) + return -ENOMEM; + + srom->dev = dev; +- srom->reg_base = of_iomap(np, 0); +- if (!srom->reg_base) { ++ srom->reg_base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(srom->reg_base)) { + dev_err(&pdev->dev, "iomap of exynos srom controller failed\n"); +- return -ENOMEM; ++ return PTR_ERR(srom->reg_base); + } + + platform_set_drvdata(pdev, srom); + + srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, + ARRAY_SIZE(exynos_srom_offsets)); +- if (!srom->reg_offset) { +- iounmap(srom->reg_base); ++ if (!srom->reg_offset) + return -ENOMEM; +- } + + for_each_child_of_node(np, child) { + if (exynos_srom_configure_bank(srom, child)) { +diff --git a/drivers/mfd/intel_soc_pmic_chtdc_ti.c b/drivers/mfd/intel_soc_pmic_chtdc_ti.c +index 992855bfda3e47..6daf33e07ea0a8 100644 +--- a/drivers/mfd/intel_soc_pmic_chtdc_ti.c ++++ b/drivers/mfd/intel_soc_pmic_chtdc_ti.c +@@ -81,8 +81,9 @@ static struct mfd_cell chtdc_ti_dev[] = { + static const struct regmap_config chtdc_ti_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +- .max_register = 128, +- .cache_type = REGCACHE_NONE, ++ .max_register = 0xff, ++ /* The hardware does not support reading multiple registers at once */ ++ .use_single_read = true, + }; + + static const struct regmap_irq chtdc_ti_irqs[] = { +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index 5e03a6ba55711a..a85442d74e0928 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -322,11 +322,11 @@ static void fastrpc_free_map(struct kref *ref) + + perm.vmid = QCOM_SCM_VMID_HLOS; + perm.perm = QCOM_SCM_PERM_RWX; +- err = qcom_scm_assign_mem(map->phys, map->size, ++ err = qcom_scm_assign_mem(map->phys, map->len, + &src_perms, &perm, 1); + if (err) { +- dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", +- map->phys, map->size, err); ++ dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", ++ map->phys, map->len, err); + return; + } + } +@@ -752,7 +752,8 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, + struct fastrpc_session_ctx *sess = fl->sctx; + struct fastrpc_map *map = NULL; + struct sg_table *table; +- int err = 0; ++ struct scatterlist *sgl = NULL; ++ int err = 0, sgl_index = 0; + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) +@@ -789,7 +790,15 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, + map->phys = sg_dma_address(map->table->sgl); + map->phys += ((u64)fl->sctx->sid << 32); + } +- map->size = len; ++ for_each_sg(map->table->sgl, sgl, map->table->nents, ++ sgl_index) ++ map->size += sg_dma_len(sgl); ++ if (len > map->size) { ++ dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n", ++ len, map->size); ++ err = -EINVAL; ++ goto map_err; ++ } + map->va = sg_virt(map->table->sgl); + map->len = len; + +@@ -806,10 +815,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, + dst_perms[1].vmid = fl->cctx->vmperms[0].vmid; + dst_perms[1].perm = QCOM_SCM_PERM_RWX; + map->attr = attr; +- err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2); ++ err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2); + if (err) { +- dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", +- map->phys, map->size, err); ++ dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", ++ map->phys, map->len, err); + goto map_err; + } + } +@@ -1240,7 +1249,7 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques + * that does not support unsigned PD offload + */ + if (!fl->cctx->unsigned_support || !unsigned_pd_request) { +- dev_err(&fl->cctx->rpdev->dev, "Error: Untrusted application trying to offload to signed PD"); ++ dev_err(&fl->cctx->rpdev->dev, "Error: Untrusted application trying to offload to signed PD\n"); + return true; + } + } +@@ -1304,7 +1313,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, + &src_perms, + fl->cctx->vmperms, fl->cctx->vmcount); + if (err) { +- dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", ++ dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", + fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + goto err_map; + } +@@ -1358,7 +1367,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, + (u64)fl->cctx->remote_heap->size, + &src_perms, &dst_perms, 1); + if (err) +- dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", ++ dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + } + err_map: +@@ -2063,7 +2072,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) + args[0].length = sizeof(req_msg); + + pages.addr = map->phys; +- pages.size = map->size; ++ pages.size = map->len; + + args[1].ptr = (u64) (uintptr_t) &pages; + args[1].length = sizeof(pages); +@@ -2078,7 +2087,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); + if (err) { + dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n", +- req.fd, req.vaddrin, map->size); ++ req.fd, req.vaddrin, map->len); + goto err_invoke; + } + +@@ -2091,7 +2100,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) + if (copy_to_user((void __user *)argp, &req, sizeof(req))) { + /* unmap the memory and release the buffer */ + req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr; +- req_unmap.length = map->size; ++ req_unmap.length = map->len; + fastrpc_req_mem_unmap_impl(fl, &req_unmap); + return -EFAULT; + } +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index cb87e827377934..2c58df6855f2a5 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -945,7 +945,11 @@ static void mmc_sdio_remove(struct mmc_host *host) + */ + static int mmc_sdio_alive(struct mmc_host *host) + { +- return mmc_select_card(host->card); ++ if (!mmc_host_is_spi(host)) ++ return mmc_select_card(host->card); ++ else ++ return mmc_io_rw_direct(host->card, 0, 0, SDIO_CCCR_CCCR, 0, ++ NULL); + } + + /* +diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c +index fe5912d31beea4..b0a70badf3eb77 100644 +--- a/drivers/mtd/nand/raw/fsmc_nand.c ++++ b/drivers/mtd/nand/raw/fsmc_nand.c +@@ -876,10 +876,14 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev, + if (!of_property_read_u32(np, "bank-width", &val)) { + if (val == 2) { + nand->options |= NAND_BUSWIDTH_16; +- } else if (val != 1) { ++ } else if (val == 1) { ++ nand->options |= NAND_BUSWIDTH_AUTO; ++ } else { + dev_err(&pdev->dev, "invalid bank-width %u\n", val); + return -EINVAL; + } ++ } else { ++ nand->options |= NAND_BUSWIDTH_AUTO; + } + + if (of_property_read_bool(np, "nand-skip-bbtscan")) +diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c +index eee675a25b2c3c..ef9adecb639aec 100644 +--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c ++++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c +@@ -483,10 +483,12 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) + "missing 'reg' property in node %pOF\n", + tbi); + err = -EBUSY; ++ of_node_put(tbi); + goto error; + } + set_tbipa(*prop, pdev, + data->get_tbipa, priv->map, &res); ++ of_node_put(tbi); + } + } + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index 33bbcced81059a..275561272721e4 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -1177,9 +1177,9 @@ static void mlx4_en_do_uc_filter(struct mlx4_en_priv *priv, + mlx4_unregister_mac(mdev->dev, priv->port, mac); + + hlist_del_rcu(&entry->hlist); +- kfree_rcu(entry, rcu); + en_dbg(DRV, priv, "Removed MAC %pM on port:%d\n", + entry->mac, priv->port); ++ kfree_rcu(entry, rcu); + ++removed; + } + } +diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c +index 0e8ff839cae234..3a340cb2b205f4 100644 +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -1763,14 +1763,10 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) + mutex_unlock(&ab->core_lock); + + ath11k_dp_free(ab); +- ath11k_hal_srng_deinit(ab); ++ ath11k_hal_srng_clear(ab); + + ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1; + +- ret = ath11k_hal_srng_init(ab); +- if (ret) +- return ret; +- + clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); + + ret = ath11k_core_qmi_firmware_ready(ab); +diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c +index 1215408d1a6abb..79cf65bc2e1724 100644 +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -1356,6 +1356,22 @@ void ath11k_hal_srng_deinit(struct ath11k_base *ab) + } + EXPORT_SYMBOL(ath11k_hal_srng_deinit); + ++void ath11k_hal_srng_clear(struct ath11k_base *ab) ++{ ++ /* No need to memset rdp and wrp memory since each individual ++ * segment would get cleared in ath11k_hal_srng_src_hw_init() ++ * and ath11k_hal_srng_dst_hw_init(). ++ */ ++ memset(ab->hal.srng_list, 0, ++ sizeof(ab->hal.srng_list)); ++ memset(ab->hal.shadow_reg_addr, 0, ++ sizeof(ab->hal.shadow_reg_addr)); ++ ab->hal.avail_blk_resource = 0; ++ ab->hal.current_blk_index = 0; ++ ab->hal.num_shadow_reg_configured = 0; ++} ++EXPORT_SYMBOL(ath11k_hal_srng_clear); ++ + void ath11k_hal_dump_srng_stats(struct ath11k_base *ab) + { + struct hal_srng *srng; +diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h +index 80447f488954a8..aa21eb1fdce159 100644 +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -962,6 +962,7 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type, + struct hal_srng_params *params); + int ath11k_hal_srng_init(struct ath11k_base *ath11k); + void ath11k_hal_srng_deinit(struct ath11k_base *ath11k); ++void ath11k_hal_srng_clear(struct ath11k_base *ab); + void ath11k_hal_dump_srng_stats(struct ath11k_base *ab); + void ath11k_hal_srng_get_shadow_config(struct ath11k_base *ab, + u32 **cfg, u32 *len); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +index 13e892d788b277..92281811103ef9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +@@ -21,6 +21,9 @@ static const struct usb_device_id mt7921u_device_table[] = { + /* Netgear, Inc. [A8000,AXE3000] */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, ++ /* Netgear, Inc. A7500 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9065, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, + /* TP-Link TXE50UH */ + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 136dba6221d86a..053385c84bf848 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2986,10 +2986,12 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + * Exclude Samsung 990 Evo from NVME_QUIRK_SIMPLE_SUSPEND + * because of high power consumption (> 2 Watt) in s2idle + * sleep. Only some boards with Intel CPU are affected. ++ * (Note for testing: Samsung 990 Evo Plus has same PCI ID) + */ + if (dmi_match(DMI_BOARD_NAME, "DN50Z-140HC-YD") || + dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + dmi_match(DMI_BOARD_NAME, "GXxMRXx") || ++ dmi_match(DMI_BOARD_NAME, "NS5X_NS7XAU") || + dmi_match(DMI_BOARD_NAME, "PH4PG31") || + dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || + dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index 5bfec440b4fd70..aae4e8ef9e3654 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -3957,6 +3957,7 @@ static int of_unittest_pci_node_verify(struct pci_dev *pdev, bool add) + unittest(!np, "Child device tree node is not removed\n"); + child_dev = device_find_any_child(&pdev->dev); + unittest(!child_dev, "Child device is not removed\n"); ++ put_device(child_dev); + } + + failed: +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index bf9a961c9f2766..9055ce34c636bd 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1213,8 +1213,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- ret = request_irq(irq, ks_pcie_err_irq_handler, IRQF_SHARED, +- "ks-pcie-error-irq", ks_pcie); ++ ret = devm_request_irq(dev, irq, ks_pcie_err_irq_handler, IRQF_SHARED, ++ "ks-pcie-error-irq", ks_pcie); + if (ret < 0) { + dev_err(dev, "failed to request error IRQ %d\n", + irq); +diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c +index 115a21cf869ae6..c7d3e248a59a20 100644 +--- a/drivers/pci/controller/dwc/pcie-tegra194.c ++++ b/drivers/pci/controller/dwc/pcie-tegra194.c +@@ -1218,6 +1218,7 @@ static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie, + struct mrq_uphy_response resp; + struct tegra_bpmp_message msg; + struct mrq_uphy_request req; ++ int err; + + /* + * Controller-5 doesn't need to have its state set by BPMP-FW in +@@ -1240,7 +1241,13 @@ static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie, + msg.rx.data = &resp; + msg.rx.size = sizeof(resp); + +- return tegra_bpmp_transfer(pcie->bpmp, &msg); ++ err = tegra_bpmp_transfer(pcie->bpmp, &msg); ++ if (err) ++ return err; ++ if (msg.rx.ret) ++ return -EINVAL; ++ ++ return 0; + } + + static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, +@@ -1249,6 +1256,7 @@ static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, + struct mrq_uphy_response resp; + struct tegra_bpmp_message msg; + struct mrq_uphy_request req; ++ int err; + + memset(&req, 0, sizeof(req)); + memset(&resp, 0, sizeof(resp)); +@@ -1268,7 +1276,13 @@ static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, + msg.rx.data = &resp; + msg.rx.size = sizeof(resp); + +- return tegra_bpmp_transfer(pcie->bpmp, &msg); ++ err = tegra_bpmp_transfer(pcie->bpmp, &msg); ++ if (err) ++ return err; ++ if (msg.rx.ret) ++ return -EINVAL; ++ ++ return 0; + } + + static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie) +@@ -1963,10 +1977,10 @@ static int tegra_pcie_ep_raise_legacy_irq(struct tegra_pcie_dw *pcie, u16 irq) + + static int tegra_pcie_ep_raise_msi_irq(struct tegra_pcie_dw *pcie, u16 irq) + { +- if (unlikely(irq > 31)) ++ if (unlikely(irq > 32)) + return -EINVAL; + +- appl_writel(pcie, BIT(irq), APPL_MSI_CTRL_1); ++ appl_writel(pcie, BIT(irq - 1), APPL_MSI_CTRL_1); + + return 0; + } +diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c +index 80d975dcb2ee27..da37569460b1ad 100644 +--- a/drivers/pci/controller/pci-tegra.c ++++ b/drivers/pci/controller/pci-tegra.c +@@ -14,6 +14,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -269,7 +270,7 @@ struct tegra_msi { + DECLARE_BITMAP(used, INT_PCI_MSI_NR); + struct irq_domain *domain; + struct mutex map_lock; +- spinlock_t mask_lock; ++ raw_spinlock_t mask_lock; + void *virt; + dma_addr_t phys; + int irq; +@@ -1604,14 +1605,13 @@ static void tegra_msi_irq_mask(struct irq_data *d) + struct tegra_msi *msi = irq_data_get_irq_chip_data(d); + struct tegra_pcie *pcie = msi_to_pcie(msi); + unsigned int index = d->hwirq / 32; +- unsigned long flags; + u32 value; + +- spin_lock_irqsave(&msi->mask_lock, flags); +- value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); +- value &= ~BIT(d->hwirq % 32); +- afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); +- spin_unlock_irqrestore(&msi->mask_lock, flags); ++ scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { ++ value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); ++ value &= ~BIT(d->hwirq % 32); ++ afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); ++ } + } + + static void tegra_msi_irq_unmask(struct irq_data *d) +@@ -1619,14 +1619,13 @@ static void tegra_msi_irq_unmask(struct irq_data *d) + struct tegra_msi *msi = irq_data_get_irq_chip_data(d); + struct tegra_pcie *pcie = msi_to_pcie(msi); + unsigned int index = d->hwirq / 32; +- unsigned long flags; + u32 value; + +- spin_lock_irqsave(&msi->mask_lock, flags); +- value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); +- value |= BIT(d->hwirq % 32); +- afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); +- spin_unlock_irqrestore(&msi->mask_lock, flags); ++ scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { ++ value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); ++ value |= BIT(d->hwirq % 32); ++ afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); ++ } + } + + static int tegra_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +@@ -1742,7 +1741,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) + int err; + + mutex_init(&msi->map_lock); +- spin_lock_init(&msi->mask_lock); ++ raw_spin_lock_init(&msi->mask_lock); + + if (IS_ENABLED(CONFIG_PCI_MSI)) { + err = tegra_allocate_domains(msi); +diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c +index 704ab5d723a959..77f6366e7db107 100644 +--- a/drivers/pci/controller/pcie-rcar-host.c ++++ b/drivers/pci/controller/pcie-rcar-host.c +@@ -12,6 +12,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -36,7 +37,7 @@ struct rcar_msi { + DECLARE_BITMAP(used, INT_PCI_MSI_NR); + struct irq_domain *domain; + struct mutex map_lock; +- spinlock_t mask_lock; ++ raw_spinlock_t mask_lock; + int irq1; + int irq2; + }; +@@ -50,20 +51,13 @@ struct rcar_pcie_host { + int (*phy_init_fn)(struct rcar_pcie_host *host); + }; + +-static DEFINE_SPINLOCK(pmsr_lock); +- + static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base) + { +- unsigned long flags; + u32 pmsr, val; + int ret = 0; + +- spin_lock_irqsave(&pmsr_lock, flags); +- +- if (!pcie_base || pm_runtime_suspended(pcie_dev)) { +- ret = -EINVAL; +- goto unlock_exit; +- } ++ if (!pcie_base || pm_runtime_suspended(pcie_dev)) ++ return -EINVAL; + + pmsr = readl(pcie_base + PMSR); + +@@ -85,8 +79,6 @@ static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base) + writel(L1FAEG | PMEL1RX, pcie_base + PMSR); + } + +-unlock_exit: +- spin_unlock_irqrestore(&pmsr_lock, flags); + return ret; + } + +@@ -633,28 +625,26 @@ static void rcar_msi_irq_mask(struct irq_data *d) + { + struct rcar_msi *msi = irq_data_get_irq_chip_data(d); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; +- unsigned long flags; + u32 value; + +- spin_lock_irqsave(&msi->mask_lock, flags); +- value = rcar_pci_read_reg(pcie, PCIEMSIIER); +- value &= ~BIT(d->hwirq); +- rcar_pci_write_reg(pcie, value, PCIEMSIIER); +- spin_unlock_irqrestore(&msi->mask_lock, flags); ++ scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { ++ value = rcar_pci_read_reg(pcie, PCIEMSIIER); ++ value &= ~BIT(d->hwirq); ++ rcar_pci_write_reg(pcie, value, PCIEMSIIER); ++ } + } + + static void rcar_msi_irq_unmask(struct irq_data *d) + { + struct rcar_msi *msi = irq_data_get_irq_chip_data(d); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; +- unsigned long flags; + u32 value; + +- spin_lock_irqsave(&msi->mask_lock, flags); +- value = rcar_pci_read_reg(pcie, PCIEMSIIER); +- value |= BIT(d->hwirq); +- rcar_pci_write_reg(pcie, value, PCIEMSIIER); +- spin_unlock_irqrestore(&msi->mask_lock, flags); ++ scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { ++ value = rcar_pci_read_reg(pcie, PCIEMSIIER); ++ value |= BIT(d->hwirq); ++ rcar_pci_write_reg(pcie, value, PCIEMSIIER); ++ } + } + + static int rcar_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +@@ -770,7 +760,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host) + int err; + + mutex_init(&msi->map_lock); +- spin_lock_init(&msi->mask_lock); ++ raw_spin_lock_init(&msi->mask_lock); + + err = of_address_to_resource(dev->of_node, 0, &res); + if (err) +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index ac1dae113f2d9f..4cf20ca25ea74e 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -282,17 +282,20 @@ static void pci_epf_test_clean_dma_chan(struct pci_epf_test *epf_test) + if (!epf_test->dma_supported) + return; + +- dma_release_channel(epf_test->dma_chan_tx); +- if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { ++ if (epf_test->dma_chan_tx) { ++ dma_release_channel(epf_test->dma_chan_tx); ++ if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { ++ epf_test->dma_chan_tx = NULL; ++ epf_test->dma_chan_rx = NULL; ++ return; ++ } + epf_test->dma_chan_tx = NULL; +- epf_test->dma_chan_rx = NULL; +- return; + } + +- dma_release_channel(epf_test->dma_chan_rx); +- epf_test->dma_chan_rx = NULL; +- +- return; ++ if (epf_test->dma_chan_rx) { ++ dma_release_channel(epf_test->dma_chan_rx); ++ epf_test->dma_chan_rx = NULL; ++ } + } + + static void pci_epf_test_print_rate(struct pci_epf_test *epf_test, +diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c +index 25dbe85c421758..f97c4f0e1c7a3d 100644 +--- a/drivers/pci/iov.c ++++ b/drivers/pci/iov.c +@@ -581,15 +581,18 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) + if (dev->no_vf_scan) + return 0; + ++ pci_lock_rescan_remove(); + for (i = 0; i < num_vfs; i++) { + rc = pci_iov_add_virtfn(dev, i); + if (rc) + goto failed; + } ++ pci_unlock_rescan_remove(); + return 0; + failed: + while (i--) + pci_iov_remove_virtfn(dev, i); ++ pci_unlock_rescan_remove(); + + return rc; + } +@@ -709,8 +712,10 @@ static void sriov_del_vfs(struct pci_dev *dev) + struct pci_sriov *iov = dev->sriov; + int i; + ++ pci_lock_rescan_remove(); + for (i = 0; i < iov->num_VFs; i++) + pci_iov_remove_virtfn(dev, i); ++ pci_unlock_rescan_remove(); + } + + static void sriov_disable(struct pci_dev *dev) +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 9c59bf03d6579f..1705d2d0ed1268 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -1612,6 +1612,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type) + switch (err_type) { + case PCI_ERS_RESULT_NONE: + case PCI_ERS_RESULT_CAN_RECOVER: ++ case PCI_ERS_RESULT_NEED_RESET: + envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; + envp[idx++] = "DEVICE_ONLINE=0"; + break; +diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c +index 92e8ac85f58e86..449d42744d336f 100644 +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -196,8 +196,14 @@ static ssize_t max_link_width_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct pci_dev *pdev = to_pci_dev(dev); ++ ssize_t ret; + +- return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev)); ++ /* We read PCI_EXP_LNKCAP, so we need the device to be accessible. */ ++ pci_config_pm_runtime_get(pdev); ++ ret = sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev)); ++ pci_config_pm_runtime_put(pdev); ++ ++ return ret; + } + static DEVICE_ATTR_RO(max_link_width); + +@@ -209,7 +215,10 @@ static ssize_t current_link_speed_show(struct device *dev, + int err; + enum pci_bus_speed speed; + ++ pci_config_pm_runtime_get(pci_dev); + err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); ++ pci_config_pm_runtime_put(pci_dev); ++ + if (err) + return -EINVAL; + +@@ -226,7 +235,10 @@ static ssize_t current_link_width_show(struct device *dev, + u16 linkstat; + int err; + ++ pci_config_pm_runtime_get(pci_dev); + err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); ++ pci_config_pm_runtime_put(pci_dev); ++ + if (err) + return -EINVAL; + +@@ -242,7 +254,10 @@ static ssize_t secondary_bus_number_show(struct device *dev, + u8 sec_bus; + int err; + ++ pci_config_pm_runtime_get(pci_dev); + err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, &sec_bus); ++ pci_config_pm_runtime_put(pci_dev); ++ + if (err) + return -EINVAL; + +@@ -258,7 +273,10 @@ static ssize_t subordinate_bus_number_show(struct device *dev, + u8 sub_bus; + int err; + ++ pci_config_pm_runtime_get(pci_dev); + err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, &sub_bus); ++ pci_config_pm_runtime_put(pci_dev); ++ + if (err) + return -EINVAL; + +diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c +index eeb9ea9044b43d..8e700020ee0bc3 100644 +--- a/drivers/pci/pcie/aer.c ++++ b/drivers/pci/pcie/aer.c +@@ -38,7 +38,7 @@ + #define AER_ERROR_SOURCES_MAX 128 + + #define AER_MAX_TYPEOF_COR_ERRS 16 /* as per PCI_ERR_COR_STATUS */ +-#define AER_MAX_TYPEOF_UNCOR_ERRS 27 /* as per PCI_ERR_UNCOR_STATUS*/ ++#define AER_MAX_TYPEOF_UNCOR_ERRS 32 /* as per PCI_ERR_UNCOR_STATUS*/ + + struct aer_err_source { + unsigned int status; +@@ -510,11 +510,11 @@ static const char *aer_uncorrectable_error_string[] = { + "AtomicOpBlocked", /* Bit Position 24 */ + "TLPBlockedErr", /* Bit Position 25 */ + "PoisonTLPBlocked", /* Bit Position 26 */ +- NULL, /* Bit Position 27 */ +- NULL, /* Bit Position 28 */ +- NULL, /* Bit Position 29 */ +- NULL, /* Bit Position 30 */ +- NULL, /* Bit Position 31 */ ++ "DMWrReqBlocked", /* Bit Position 27 */ ++ "IDECheck", /* Bit Position 28 */ ++ "MisIDETLP", /* Bit Position 29 */ ++ "PCRC_CHECK", /* Bit Position 30 */ ++ "TLPXlatBlocked", /* Bit Position 31 */ + }; + + static const char *aer_agent_string[] = { +diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c +index 705893b5f7b09b..197191178cddc2 100644 +--- a/drivers/pci/pcie/err.c ++++ b/drivers/pci/pcie/err.c +@@ -108,6 +108,12 @@ static int report_normal_detected(struct pci_dev *dev, void *data) + return report_error_detected(dev, pci_channel_io_normal, data); + } + ++static int report_perm_failure_detected(struct pci_dev *dev, void *data) ++{ ++ pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT); ++ return 0; ++} ++ + static int report_mmio_enabled(struct pci_dev *dev, void *data) + { + struct pci_driver *pdrv; +@@ -275,7 +281,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, + failed: + pci_walk_bridge(bridge, pci_pm_runtime_put, NULL); + +- pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT); ++ pci_walk_bridge(bridge, report_perm_failure_detected, NULL); + + /* TODO: Should kernel panic here? */ + pci_info(bridge, "device recovery failed\n"); +diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h +index 9af93e3d8d9ff3..1efbae6c99876e 100644 +--- a/drivers/pinctrl/samsung/pinctrl-samsung.h ++++ b/drivers/pinctrl/samsung/pinctrl-samsung.h +@@ -352,10 +352,6 @@ extern const struct samsung_pinctrl_of_match_data exynos850_of_data; + extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data; + extern const struct samsung_pinctrl_of_match_data fsd_of_data; + extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data; +-extern const struct samsung_pinctrl_of_match_data s3c2412_of_data; +-extern const struct samsung_pinctrl_of_match_data s3c2416_of_data; +-extern const struct samsung_pinctrl_of_match_data s3c2440_of_data; +-extern const struct samsung_pinctrl_of_match_data s3c2450_of_data; + extern const struct samsung_pinctrl_of_match_data s5pv210_of_data; + + #endif /* __PINCTRL_SAMSUNG_H */ +diff --git a/drivers/power/supply/max77976_charger.c b/drivers/power/supply/max77976_charger.c +index 99659dc8f5a6df..56ab502e1a80b5 100644 +--- a/drivers/power/supply/max77976_charger.c ++++ b/drivers/power/supply/max77976_charger.c +@@ -292,10 +292,10 @@ static int max77976_get_property(struct power_supply *psy, + case POWER_SUPPLY_PROP_ONLINE: + err = max77976_get_online(chg, &val->intval); + break; +- case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: ++ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + val->intval = MAX77976_CHG_CC_MAX; + break; +- case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: ++ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + err = max77976_get_integer(chg, CHG_CC, + MAX77976_CHG_CC_MIN, + MAX77976_CHG_CC_MAX, +@@ -330,7 +330,7 @@ static int max77976_set_property(struct power_supply *psy, + int err = 0; + + switch (psp) { +- case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: ++ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + err = max77976_set_integer(chg, CHG_CC, + MAX77976_CHG_CC_MIN, + MAX77976_CHG_CC_MAX, +@@ -355,7 +355,7 @@ static int max77976_property_is_writeable(struct power_supply *psy, + enum power_supply_property psp) + { + switch (psp) { +- case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: ++ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return true; + default: +@@ -368,8 +368,8 @@ static enum power_supply_property max77976_psy_props[] = { + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_ONLINE, +- POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, +- POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, ++ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, ++ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, +diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c +index 0971c666afd134..14729a6ae09a98 100644 +--- a/drivers/pwm/pwm-berlin.c ++++ b/drivers/pwm/pwm-berlin.c +@@ -273,7 +273,7 @@ static int berlin_pwm_suspend(struct device *dev) + if (!channel) + continue; + +- channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE); ++ channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_EN); + channel->ctrl = berlin_pwm_readl(bpc, i, BERLIN_PWM_CONTROL); + channel->duty = berlin_pwm_readl(bpc, i, BERLIN_PWM_DUTY); + channel->tcnt = berlin_pwm_readl(bpc, i, BERLIN_PWM_TCNT); +@@ -304,7 +304,7 @@ static int berlin_pwm_resume(struct device *dev) + berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL); + berlin_pwm_writel(bpc, i, channel->duty, BERLIN_PWM_DUTY); + berlin_pwm_writel(bpc, i, channel->tcnt, BERLIN_PWM_TCNT); +- berlin_pwm_writel(bpc, i, channel->enable, BERLIN_PWM_ENABLE); ++ berlin_pwm_writel(bpc, i, channel->enable, BERLIN_PWM_EN); + } + + return 0; +diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c +index 4a7c41a6c21e7d..93baffe110c00a 100644 +--- a/drivers/rtc/interface.c ++++ b/drivers/rtc/interface.c +@@ -443,6 +443,29 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + else + err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + ++ /* ++ * Check for potential race described above. If the waiting for next ++ * second, and the second just ticked since the check above, either ++ * ++ * 1) It ticked after the alarm was set, and an alarm irq should be ++ * generated. ++ * ++ * 2) It ticked before the alarm was set, and alarm irq most likely will ++ * not be generated. ++ * ++ * While we cannot easily check for which of these two scenarios we ++ * are in, we can return -ETIME to signal that the timer has already ++ * expired, which is true in both cases. ++ */ ++ if ((scheduled - now) <= 1) { ++ err = __rtc_read_time(rtc, &tm); ++ if (err) ++ return err; ++ now = rtc_tm_to_time64(&tm); ++ if (scheduled <= now) ++ return -ETIME; ++ } ++ + trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err); + return err; + } +@@ -594,6 +617,10 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) + rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); + rtc->uie_rtctimer.period = ktime_set(1, 0); + err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); ++ if (!err && rtc->ops && rtc->ops->alarm_irq_enable) ++ err = rtc->ops->alarm_irq_enable(rtc->dev.parent, 1); ++ if (err) ++ goto out; + } else { + rtc_timer_remove(rtc, &rtc->uie_rtctimer); + } +diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c +index 9f8b5d4a8f6b65..6b77c122fdc109 100644 +--- a/drivers/rtc/rtc-optee.c ++++ b/drivers/rtc/rtc-optee.c +@@ -320,6 +320,7 @@ static int optee_rtc_remove(struct device *dev) + { + struct optee_rtc *priv = dev_get_drvdata(dev); + ++ tee_shm_free(priv->shm); + tee_client_close_session(priv->ctx, priv->session_id); + tee_client_close_context(priv->ctx); + +diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c +index 807f953ae0aedc..b7a7ea036f7adc 100644 +--- a/drivers/rtc/rtc-x1205.c ++++ b/drivers/rtc/rtc-x1205.c +@@ -669,7 +669,7 @@ static const struct i2c_device_id x1205_id[] = { + MODULE_DEVICE_TABLE(i2c, x1205_id); + + static const struct of_device_id x1205_dt_ids[] = { +- { .compatible = "xircom,x1205", }, ++ { .compatible = "xicor,x1205", }, + {}, + }; + MODULE_DEVICE_TABLE(of, x1205_dt_ids); +diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c +index 49c57a9c110b5f..42a89ab33e1c78 100644 +--- a/drivers/scsi/hpsa.c ++++ b/drivers/scsi/hpsa.c +@@ -6528,18 +6528,21 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, + while (left) { + sz = (left > ioc->malloc_size) ? ioc->malloc_size : left; + buff_size[sg_used] = sz; +- buff[sg_used] = kmalloc(sz, GFP_KERNEL); +- if (buff[sg_used] == NULL) { +- status = -ENOMEM; +- goto cleanup1; +- } ++ + if (ioc->Request.Type.Direction & XFER_WRITE) { +- if (copy_from_user(buff[sg_used], data_ptr, sz)) { +- status = -EFAULT; ++ buff[sg_used] = memdup_user(data_ptr, sz); ++ if (IS_ERR(buff[sg_used])) { ++ status = PTR_ERR(buff[sg_used]); + goto cleanup1; + } +- } else +- memset(buff[sg_used], 0, sz); ++ } else { ++ buff[sg_used] = kzalloc(sz, GFP_KERNEL); ++ if (!buff[sg_used]) { ++ status = -ENOMEM; ++ goto cleanup1; ++ } ++ } ++ + left -= sz; + data_ptr += sz; + sg_used++; +diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c +index 43ebb331e21673..47c4434dc7e796 100644 +--- a/drivers/scsi/mvsas/mv_init.c ++++ b/drivers/scsi/mvsas/mv_init.c +@@ -139,7 +139,7 @@ static void mvs_free(struct mvs_info *mvi) + if (mvi->shost) + scsi_host_put(mvi->shost); + list_for_each_entry(mwq, &mvi->wq_list, entry) +- cancel_delayed_work(&mwq->work_q); ++ cancel_delayed_work_sync(&mwq->work_q); + kfree(mvi->rsvd_tags); + kfree(mvi); + } +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index bf9b816637d02e..7b809644436eb7 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -687,6 +687,7 @@ static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata, + reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; + reg |= (op->addr.nbytes - 1); + writel(reg, reg_base + CQSPI_REG_SIZE); ++ readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */ + return 0; + } + +@@ -726,6 +727,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + reinit_completion(&cqspi->transfer_complete); + writel(CQSPI_REG_INDIRECTRD_START_MASK, + reg_base + CQSPI_REG_INDIRECTRD); ++ readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */ + + while (remaining > 0) { + if (!wait_for_completion_timeout(&cqspi->transfer_complete, +@@ -1004,6 +1006,7 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata, + reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; + reg |= (op->addr.nbytes - 1); + writel(reg, reg_base + CQSPI_REG_SIZE); ++ readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */ + return 0; + } + +@@ -1029,6 +1032,8 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata, + reinit_completion(&cqspi->transfer_complete); + writel(CQSPI_REG_INDIRECTWR_START_MASK, + reg_base + CQSPI_REG_INDIRECTWR); ++ readl(reg_base + CQSPI_REG_INDIRECTWR); /* Flush posted write. */ ++ + /* + * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access + * Controller programming sequence, couple of cycles of +diff --git a/drivers/video/fbdev/core/fb_cmdline.c b/drivers/video/fbdev/core/fb_cmdline.c +index 4d1634c492ec4d..594b60424d1c64 100644 +--- a/drivers/video/fbdev/core/fb_cmdline.c ++++ b/drivers/video/fbdev/core/fb_cmdline.c +@@ -40,7 +40,7 @@ int fb_get_options(const char *name, char **option) + bool enabled; + + if (name) +- is_of = strncmp(name, "offb", 4); ++ is_of = !strncmp(name, "offb", 4); + + enabled = __video_get_options(name, &options, is_of); + +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 9e3b5d21d09877..3a8f2e659e008d 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -1326,14 +1326,17 @@ int bind_interdomain_evtchn_to_irq_lateeoi(struct xenbus_device *dev, + } + EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi); + +-static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn) ++static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn, ++ bool percpu) + { + struct evtchn_status status; + evtchn_port_t port; +- int rc = -ENOENT; ++ bool exists = false; + + memset(&status, 0, sizeof(status)); + for (port = 0; port < xen_evtchn_max_channels(); port++) { ++ int rc; ++ + status.dom = DOMID_SELF; + status.port = port; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); +@@ -1341,12 +1344,16 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn) + continue; + if (status.status != EVTCHNSTAT_virq) + continue; +- if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(cpu)) { ++ if (status.u.virq != virq) ++ continue; ++ if (status.vcpu == xen_vcpu_nr(cpu)) { + *evtchn = port; +- break; ++ return 0; ++ } else if (!percpu) { ++ exists = true; + } + } +- return rc; ++ return exists ? -EEXIST : -ENOENT; + } + + /** +@@ -1393,8 +1400,11 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu) + evtchn = bind_virq.port; + else { + if (ret == -EEXIST) +- ret = find_virq(virq, cpu, &evtchn); +- BUG_ON(ret < 0); ++ ret = find_virq(virq, cpu, &evtchn, percpu); ++ if (ret) { ++ __unbind_from_irq(info, info->irq); ++ goto out; ++ } + } + + ret = xen_irq_info_virq_setup(info, cpu, evtchn, virq); +@@ -1799,9 +1809,20 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu) + * virq or IPI channel, which don't actually need to be rebound. Ignore + * it, but don't do the xenlinux-level rebind in that case. + */ +- if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) ++ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) { ++ int old_cpu = info->cpu; ++ + bind_evtchn_to_cpu(info, tcpu, false); + ++ if (info->type == IRQT_VIRQ) { ++ int virq = info->u.virq; ++ int irq = per_cpu(virq_to_irq, old_cpu)[virq]; ++ ++ per_cpu(virq_to_irq, old_cpu)[virq] = -1; ++ per_cpu(virq_to_irq, tcpu)[virq] = irq; ++ } ++ } ++ + do_unmask(info, EVT_MASK_REASON_TEMPORARY); + + return 0; +diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c +index c16df629907e13..55537b673990de 100644 +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -116,7 +116,7 @@ static void do_suspend(void) + err = dpm_suspend_start(PMSG_FREEZE); + if (err) { + pr_err("%s: dpm_suspend_start %d\n", __func__, err); +- goto out_thaw; ++ goto out_resume_end; + } + + printk(KERN_DEBUG "suspending xenstore...\n"); +@@ -156,6 +156,7 @@ static void do_suspend(void) + else + xs_suspend_cancel(); + ++out_resume_end: + dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); + + out_thaw: +diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c +index 203e5964c9b0fc..5e46f8cd7ea073 100644 +--- a/fs/btrfs/export.c ++++ b/fs/btrfs/export.c +@@ -24,7 +24,11 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, + int type; + + if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) { +- *max_len = BTRFS_FID_SIZE_CONNECTABLE; ++ if (btrfs_root_id(BTRFS_I(inode)->root) != ++ btrfs_root_id(BTRFS_I(parent)->root)) ++ *max_len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; ++ else ++ *max_len = BTRFS_FID_SIZE_CONNECTABLE; + return FILEID_INVALID; + } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { + *max_len = BTRFS_FID_SIZE_NON_CONNECTABLE; +@@ -46,6 +50,8 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, + parent_root_id = BTRFS_I(parent)->root->root_key.objectid; + + if (parent_root_id != fid->root_objectid) { ++ if (*max_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT) ++ return FILEID_INVALID; + fid->parent_root_objectid = parent_root_id; + len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; + type = FILEID_BTRFS_WITH_PARENT_ROOT; +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index ccf94c5fbfdfd6..88ba277bc3a79e 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -364,6 +364,13 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, + /* step one, find a bunch of delalloc bytes starting at start */ + delalloc_start = *start; + delalloc_end = 0; ++ ++ /* ++ * If @max_bytes is smaller than a block, btrfs_find_delalloc_range() can ++ * return early without handling any dirty ranges. ++ */ ++ ASSERT(max_bytes >= fs_info->sectorsize); ++ + found = btrfs_find_delalloc_range(tree, &delalloc_start, &delalloc_end, + max_bytes, &cached_state); + if (!found || delalloc_end <= *start || delalloc_start > orig_end) { +@@ -394,13 +401,14 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, + delalloc_start, delalloc_end); + ASSERT(!ret || ret == -EAGAIN); + if (ret == -EAGAIN) { +- /* some of the pages are gone, lets avoid looping by +- * shortening the size of the delalloc range we're searching ++ /* ++ * Some of the pages are gone, lets avoid looping by ++ * shortening the size of the delalloc range we're searching. + */ + free_extent_state(cached_state); + cached_state = NULL; + if (!loops) { +- max_bytes = PAGE_SIZE; ++ max_bytes = fs_info->sectorsize; + loops = 1; + goto again; + } else { +diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c +index 2fbf97077ce910..3f06362985b5a6 100644 +--- a/fs/cramfs/inode.c ++++ b/fs/cramfs/inode.c +@@ -117,9 +117,18 @@ static struct inode *get_cramfs_inode(struct super_block *sb, + inode_nohighmem(inode); + inode->i_data.a_ops = &cramfs_aops; + break; +- default: ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: + init_special_inode(inode, cramfs_inode->mode, + old_decode_dev(cramfs_inode->size)); ++ break; ++ default: ++ printk(KERN_DEBUG "CRAMFS: Invalid file type 0%04o for inode %lu.\n", ++ inode->i_mode, inode->i_ino); ++ iget_failed(inode); ++ return ERR_PTR(-EIO); + } + + inode->i_mode = cramfs_inode->mode; +diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c +index 1b68586f73f3fe..c970f41c50483e 100644 +--- a/fs/ext4/fsmap.c ++++ b/fs/ext4/fsmap.c +@@ -74,7 +74,8 @@ static int ext4_getfsmap_dev_compare(const void *p1, const void *p2) + static bool ext4_getfsmap_rec_before_low_key(struct ext4_getfsmap_info *info, + struct ext4_fsmap *rec) + { +- return rec->fmr_physical < info->gfi_low.fmr_physical; ++ return rec->fmr_physical + rec->fmr_length <= ++ info->gfi_low.fmr_physical; + } + + /* +@@ -200,15 +201,18 @@ static int ext4_getfsmap_meta_helper(struct super_block *sb, + ext4_group_first_block_no(sb, agno)); + fs_end = fs_start + EXT4_C2B(sbi, len); + +- /* Return relevant extents from the meta_list */ ++ /* ++ * Return relevant extents from the meta_list. We emit all extents that ++ * partially/fully overlap with the query range ++ */ + list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) { +- if (p->fmr_physical < info->gfi_next_fsblk) { ++ if (p->fmr_physical + p->fmr_length <= info->gfi_next_fsblk) { + list_del(&p->fmr_list); + kfree(p); + continue; + } +- if (p->fmr_physical <= fs_start || +- p->fmr_physical + p->fmr_length <= fs_end) { ++ if (p->fmr_physical <= fs_end && ++ p->fmr_physical + p->fmr_length > fs_start) { + /* Emit the retained free extent record if present */ + if (info->gfi_lastfree.fmr_owner) { + error = ext4_getfsmap_helper(sb, info, +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 63b1384823ba56..91a9fa6f1ad4f0 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3871,7 +3871,11 @@ int ext4_can_truncate(struct inode *inode) + * We have to make sure i_disksize gets properly updated before we truncate + * page cache due to hole punching or zero range. Otherwise i_disksize update + * can get lost as it may have been postponed to submission of writeback but +- * that will never happen after we truncate page cache. ++ * that will never happen if we remove the folio containing i_size from the ++ * page cache. Also if we punch hole within i_size but above i_disksize, ++ * following ext4_page_mkwrite() may mistakenly allocate written blocks over ++ * the hole and thus introduce allocated blocks beyond i_disksize which is ++ * not allowed (e2fsck would complain in case of crash). + */ + int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, + loff_t len) +@@ -3882,9 +3886,11 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, + loff_t size = i_size_read(inode); + + WARN_ON(!inode_is_locked(inode)); +- if (offset > size || offset + len < size) ++ if (offset > size) + return 0; + ++ if (offset + len < size) ++ size = offset + len; + if (EXT4_I(inode)->i_disksize >= size) + return 0; + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 5e6b07b3496006..c566161127cd7a 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -225,7 +225,7 @@ static int mext_page_mkuptodate(struct folio *folio, size_t from, size_t to) + do { + if (bh_offset(bh) + blocksize <= from) + continue; +- if (bh_offset(bh) > to) ++ if (bh_offset(bh) >= to) + break; + wait_on_buffer(bh); + if (buffer_uptodate(bh)) +diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c +index c53918768cb256..05997b4d012038 100644 +--- a/fs/ext4/orphan.c ++++ b/fs/ext4/orphan.c +@@ -513,7 +513,7 @@ void ext4_release_orphan_info(struct super_block *sb) + return; + for (i = 0; i < oi->of_blocks; i++) + brelse(oi->of_binfo[i].ob_bh); +- kfree(oi->of_binfo); ++ kvfree(oi->of_binfo); + } + + static struct ext4_orphan_block_tail *ext4_orphan_block_tail( +@@ -584,9 +584,20 @@ int ext4_init_orphan_info(struct super_block *sb) + ext4_msg(sb, KERN_ERR, "get orphan inode failed"); + return PTR_ERR(inode); + } ++ /* ++ * This is just an artificial limit to prevent corrupted fs from ++ * consuming absurd amounts of memory when pinning blocks of orphan ++ * file in memory. ++ */ ++ if (inode->i_size > 8 << 20) { ++ ext4_msg(sb, KERN_ERR, "orphan file too big: %llu", ++ (unsigned long long)inode->i_size); ++ ret = -EFSCORRUPTED; ++ goto out_put; ++ } + oi->of_blocks = inode->i_size >> sb->s_blocksize_bits; + oi->of_csum_seed = EXT4_I(inode)->i_csum_seed; +- oi->of_binfo = kmalloc_array(oi->of_blocks, ++ oi->of_binfo = kvmalloc_array(oi->of_blocks, + sizeof(struct ext4_orphan_block), + GFP_KERNEL); + if (!oi->of_binfo) { +@@ -627,7 +638,7 @@ int ext4_init_orphan_info(struct super_block *sb) + out_free: + for (i--; i >= 0; i--) + brelse(oi->of_binfo[i].ob_bh); +- kfree(oi->of_binfo); ++ kvfree(oi->of_binfo); + out_put: + iput(inode); + return ret; +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index ca22aa9e04b4b1..66933e55efb3bd 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -251,6 +251,10 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, + err_str = "invalid ea_ino"; + goto errout; + } ++ if (ea_ino && !size) { ++ err_str = "invalid size in ea xattr"; ++ goto errout; ++ } + if (size > EXT4_XATTR_SIZE_MAX) { + err_str = "e_value size too large"; + goto errout; +@@ -1036,7 +1040,7 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, + int ref_change) + { + struct ext4_iloc iloc; +- s64 ref_count; ++ u64 ref_count; + int ret; + + inode_lock_nested(ea_inode, I_MUTEX_XATTR); +@@ -1046,13 +1050,17 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, + goto out; + + ref_count = ext4_xattr_inode_get_ref(ea_inode); ++ if ((ref_count == 0 && ref_change < 0) || (ref_count == U64_MAX && ref_change > 0)) { ++ ext4_error_inode(ea_inode, __func__, __LINE__, 0, ++ "EA inode %lu ref wraparound: ref_count=%lld ref_change=%d", ++ ea_inode->i_ino, ref_count, ref_change); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } + ref_count += ref_change; + ext4_xattr_inode_set_ref(ea_inode, ref_count); + + if (ref_change > 0) { +- WARN_ONCE(ref_count <= 0, "EA inode %lu ref_count=%lld", +- ea_inode->i_ino, ref_count); +- + if (ref_count == 1) { + WARN_ONCE(ea_inode->i_nlink, "EA inode %lu i_nlink=%u", + ea_inode->i_ino, ea_inode->i_nlink); +@@ -1061,9 +1069,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, + ext4_orphan_del(handle, ea_inode); + } + } else { +- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld", +- ea_inode->i_ino, ref_count); +- + if (ref_count == 0) { + WARN_ONCE(ea_inode->i_nlink != 1, + "EA inode %lu i_nlink=%u", +diff --git a/fs/file.c b/fs/file.c +index 0ce6a6930276d3..9b76b9644ac275 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -1138,7 +1138,10 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) + err = expand_files(files, fd); + if (unlikely(err < 0)) + goto out_unlock; +- return do_dup2(files, file, fd, flags); ++ err = do_dup2(files, file, fd, flags); ++ if (err < 0) ++ return err; ++ return 0; + + out_unlock: + spin_unlock(&files->file_lock); +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index ed110568d6127f..274fae88b498e4 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -422,22 +422,23 @@ static bool inode_do_switch_wbs(struct inode *inode, + * Transfer to @new_wb's IO list if necessary. If the @inode is dirty, + * the specific list @inode was on is ignored and the @inode is put on + * ->b_dirty which is always correct including from ->b_dirty_time. +- * The transfer preserves @inode->dirtied_when ordering. If the @inode +- * was clean, it means it was on the b_attached list, so move it onto +- * the b_attached list of @new_wb. ++ * If the @inode was clean, it means it was on the b_attached list, so ++ * move it onto the b_attached list of @new_wb. + */ + if (!list_empty(&inode->i_io_list)) { + inode->i_wb = new_wb; + + if (inode->i_state & I_DIRTY_ALL) { +- struct inode *pos; +- +- list_for_each_entry(pos, &new_wb->b_dirty, i_io_list) +- if (time_after_eq(inode->dirtied_when, +- pos->dirtied_when)) +- break; ++ /* ++ * We need to keep b_dirty list sorted by ++ * dirtied_time_when. However properly sorting the ++ * inode in the list gets too expensive when switching ++ * many inodes. So just attach inode at the end of the ++ * dirty list and clobber the dirtied_time_when. ++ */ ++ inode->dirtied_time_when = jiffies; + inode_io_list_move_locked(inode, new_wb, +- pos->i_io_list.prev); ++ &new_wb->b_dirty); + } else { + inode_cgwb_move_to_attached(inode, new_wb); + } +@@ -479,6 +480,7 @@ static void inode_switch_wbs_work_fn(struct work_struct *work) + */ + down_read(&bdi->wb_switch_rwsem); + ++ inodep = isw->inodes; + /* + * By the time control reaches here, RCU grace period has passed + * since I_WB_SWITCH assertion and all wb stat update transactions +@@ -489,6 +491,7 @@ static void inode_switch_wbs_work_fn(struct work_struct *work) + * gives us exclusion against all wb related operations on @inode + * including IO list manipulations and stat updates. + */ ++relock: + if (old_wb < new_wb) { + spin_lock(&old_wb->list_lock); + spin_lock_nested(&new_wb->list_lock, SINGLE_DEPTH_NESTING); +@@ -497,10 +500,17 @@ static void inode_switch_wbs_work_fn(struct work_struct *work) + spin_lock_nested(&old_wb->list_lock, SINGLE_DEPTH_NESTING); + } + +- for (inodep = isw->inodes; *inodep; inodep++) { ++ while (*inodep) { + WARN_ON_ONCE((*inodep)->i_wb != old_wb); + if (inode_do_switch_wbs(*inodep, old_wb, new_wb)) + nr_switched++; ++ inodep++; ++ if (*inodep && need_resched()) { ++ spin_unlock(&new_wb->list_lock); ++ spin_unlock(&old_wb->list_lock); ++ cond_resched(); ++ goto relock; ++ } + } + + spin_unlock(&new_wb->list_lock); +diff --git a/fs/fsopen.c b/fs/fsopen.c +index ce03f6521c8870..3576b1084ec2fb 100644 +--- a/fs/fsopen.c ++++ b/fs/fsopen.c +@@ -18,50 +18,56 @@ + #include "internal.h" + #include "mount.h" + ++static inline const char *fetch_message_locked(struct fc_log *log, size_t len, ++ bool *need_free) ++{ ++ const char *p; ++ int index; ++ ++ if (unlikely(log->head == log->tail)) ++ return ERR_PTR(-ENODATA); ++ ++ index = log->tail & (ARRAY_SIZE(log->buffer) - 1); ++ p = log->buffer[index]; ++ if (unlikely(strlen(p) > len)) ++ return ERR_PTR(-EMSGSIZE); ++ ++ log->buffer[index] = NULL; ++ *need_free = log->need_free & (1 << index); ++ log->need_free &= ~(1 << index); ++ log->tail++; ++ ++ return p; ++} ++ + /* + * Allow the user to read back any error, warning or informational messages. ++ * Only one message is returned for each read(2) call. + */ + static ssize_t fscontext_read(struct file *file, + char __user *_buf, size_t len, loff_t *pos) + { + struct fs_context *fc = file->private_data; +- struct fc_log *log = fc->log.log; +- unsigned int logsize = ARRAY_SIZE(log->buffer); +- ssize_t ret; +- char *p; ++ ssize_t err; ++ const char *p __free(kfree) = NULL, *message; + bool need_free; +- int index, n; ++ int n; + +- ret = mutex_lock_interruptible(&fc->uapi_mutex); +- if (ret < 0) +- return ret; +- +- if (log->head == log->tail) { +- mutex_unlock(&fc->uapi_mutex); +- return -ENODATA; +- } +- +- index = log->tail & (logsize - 1); +- p = log->buffer[index]; +- need_free = log->need_free & (1 << index); +- log->buffer[index] = NULL; +- log->need_free &= ~(1 << index); +- log->tail++; ++ err = mutex_lock_interruptible(&fc->uapi_mutex); ++ if (err < 0) ++ return err; ++ message = fetch_message_locked(fc->log.log, len, &need_free); + mutex_unlock(&fc->uapi_mutex); ++ if (IS_ERR(message)) ++ return PTR_ERR(message); + +- ret = -EMSGSIZE; +- n = strlen(p); +- if (n > len) +- goto err_free; +- ret = -EFAULT; +- if (copy_to_user(_buf, p, n) != 0) +- goto err_free; +- ret = n; +- +-err_free: + if (need_free) +- kfree(p); +- return ret; ++ p = message; ++ ++ n = strlen(message); ++ if (copy_to_user(_buf, message, n)) ++ return -EFAULT; ++ return n; + } + + static int fscontext_release(struct inode *inode, struct file *file) +diff --git a/fs/minix/inode.c b/fs/minix/inode.c +index df575473c1cc0b..ee8a6fe360e728 100644 +--- a/fs/minix/inode.c ++++ b/fs/minix/inode.c +@@ -470,8 +470,14 @@ void minix_set_inode(struct inode *inode, dev_t rdev) + inode->i_op = &minix_symlink_inode_operations; + inode_nohighmem(inode); + inode->i_mapping->a_ops = &minix_aops; +- } else ++ } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || ++ S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { + init_special_inode(inode, inode->i_mode, rdev); ++ } else { ++ printk(KERN_DEBUG "MINIX-fs: Invalid file type 0%04o for inode %lu.\n", ++ inode->i_mode, inode->i_ino); ++ make_bad_inode(inode); ++ } + } + + /* +diff --git a/fs/namei.c b/fs/namei.c +index 155e4d09a5fb2c..02b0c273129824 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1364,6 +1364,10 @@ static int follow_automount(struct path *path, int *count, unsigned lookup_flags + dentry->d_inode) + return -EISDIR; + ++ /* No need to trigger automounts if mountpoint crossing is disabled. */ ++ if (lookup_flags & LOOKUP_NO_XDEV) ++ return -EXDEV; ++ + if (count && (*count)++ >= MAXSYMLINKS) + return -ELOOP; + +@@ -1387,6 +1391,10 @@ static int __traverse_mounts(struct path *path, unsigned flags, bool *jumped, + /* Allow the filesystem to manage the transit without i_mutex + * being held. */ + if (flags & DCACHE_MANAGE_TRANSIT) { ++ if (lookup_flags & LOOKUP_NO_XDEV) { ++ ret = -EXDEV; ++ break; ++ } + ret = path->dentry->d_op->d_manage(path, false); + flags = smp_load_acquire(&path->dentry->d_flags); + if (ret < 0) +diff --git a/fs/namespace.c b/fs/namespace.c +index f79226472251ba..646d9e7d41ee8a 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -64,6 +64,15 @@ static int __init set_mphash_entries(char *str) + } + __setup("mphash_entries=", set_mphash_entries); + ++static char * __initdata initramfs_options; ++static int __init initramfs_options_setup(char *str) ++{ ++ initramfs_options = str; ++ return 1; ++} ++ ++__setup("initramfs_options=", initramfs_options_setup); ++ + static u64 event; + static DEFINE_IDA(mnt_id_ida); + static DEFINE_IDA(mnt_group_ida); +@@ -4728,7 +4737,7 @@ static void __init init_mount_tree(void) + struct mnt_namespace *ns; + struct path root; + +- mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", NULL); ++ mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", initramfs_options); + if (IS_ERR(mnt)) + panic("Can't create rootfs"); + +diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c +index 46a7f9b813e527..b02886f38925f8 100644 +--- a/fs/nfsd/lockd.c ++++ b/fs/nfsd/lockd.c +@@ -48,6 +48,21 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp, + switch (nfserr) { + case nfs_ok: + return 0; ++ case nfserr_jukebox: ++ /* this error can indicate a presence of a conflicting ++ * delegation to an NLM lock request. Options are: ++ * (1) For now, drop this request and make the client ++ * retry. When delegation is returned, client's lock retry ++ * will complete. ++ * (2) NLM4_DENIED as per "spec" signals to the client ++ * that the lock is unavailable now but client can retry. ++ * Linux client implementation does not. It treats ++ * NLM4_DENIED same as NLM4_FAILED and errors the request. ++ * (3) For the future, treat this as blocked lock and try ++ * to callback when the delegation is returned but might ++ * not have a proper lock request to block on. ++ */ ++ fallthrough; + case nfserr_dropit: + return nlm_drop_reply; + case nfserr_stale: +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index cd78b7ecbd4325..e9c1271b7ecc39 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1368,7 +1368,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, + return 0; + } + if (work) { +- strscpy(work->nsui_ipaddr, ipaddr, sizeof(work->nsui_ipaddr) - 1); ++ strscpy(work->nsui_ipaddr, ipaddr, sizeof(work->nsui_ipaddr)); + refcount_set(&work->nsui_refcnt, 2); + work->nsui_busy = true; + list_add_tail(&work->nsui_list, &nn->nfsd_ssc_mount_list); +diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c +index cf4fe21a50399b..29b585f443f3eb 100644 +--- a/fs/ntfs3/bitmap.c ++++ b/fs/ntfs3/bitmap.c +@@ -1399,6 +1399,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits) + mark_buffer_dirty(bh); + unlock_buffer(bh); + /* err = sync_dirty_buffer(bh); */ ++ put_bh(bh); + + b0 = 0; + bits -= op; +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index e62d9cc592e0c8..c80b291a14a576 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -671,14 +671,72 @@ static int cifs_query_path_info(const unsigned int xid, + } + + #ifdef CONFIG_CIFS_XATTR ++ /* ++ * For non-symlink WSL reparse points it is required to fetch ++ * EA $LXMOD which contains in its S_DT part the mandatory file type. ++ */ ++ if (!rc && data->reparse_point) { ++ struct smb2_file_full_ea_info *ea; ++ u32 next = 0; ++ ++ ea = (struct smb2_file_full_ea_info *)data->wsl.eas; ++ do { ++ ea = (void *)((u8 *)ea + next); ++ next = le32_to_cpu(ea->next_entry_offset); ++ } while (next); ++ if (le16_to_cpu(ea->ea_value_length)) { ++ ea->next_entry_offset = cpu_to_le32(ALIGN(sizeof(*ea) + ++ ea->ea_name_length + 1 + ++ le16_to_cpu(ea->ea_value_length), 4)); ++ ea = (void *)((u8 *)ea + le32_to_cpu(ea->next_entry_offset)); ++ } ++ ++ rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_MODE, ++ &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1], ++ SMB2_WSL_XATTR_MODE_SIZE, cifs_sb); ++ if (rc == SMB2_WSL_XATTR_MODE_SIZE) { ++ ea->next_entry_offset = cpu_to_le32(0); ++ ea->flags = 0; ++ ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN; ++ ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_MODE_SIZE); ++ memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_MODE, SMB2_WSL_XATTR_NAME_LEN + 1); ++ data->wsl.eas_len += ALIGN(sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 + ++ SMB2_WSL_XATTR_MODE_SIZE, 4); ++ rc = 0; ++ } else if (rc >= 0) { ++ /* It is an error if EA $LXMOD has wrong size. */ ++ rc = -EINVAL; ++ } else { ++ /* ++ * In all other cases ignore error if fetching ++ * of EA $LXMOD failed. It is needed only for ++ * non-symlink WSL reparse points and wsl_to_fattr() ++ * handle the case when EA is missing. ++ */ ++ rc = 0; ++ } ++ } ++ + /* + * For WSL CHR and BLK reparse points it is required to fetch + * EA $LXDEV which contains major and minor device numbers. + */ + if (!rc && data->reparse_point) { + struct smb2_file_full_ea_info *ea; ++ u32 next = 0; + + ea = (struct smb2_file_full_ea_info *)data->wsl.eas; ++ do { ++ ea = (void *)((u8 *)ea + next); ++ next = le32_to_cpu(ea->next_entry_offset); ++ } while (next); ++ if (le16_to_cpu(ea->ea_value_length)) { ++ ea->next_entry_offset = cpu_to_le32(ALIGN(sizeof(*ea) + ++ ea->ea_name_length + 1 + ++ le16_to_cpu(ea->ea_value_length), 4)); ++ ea = (void *)((u8 *)ea + le32_to_cpu(ea->next_entry_offset)); ++ } ++ + rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_DEV, + &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1], + SMB2_WSL_XATTR_DEV_SIZE, cifs_sb); +@@ -688,8 +746,8 @@ static int cifs_query_path_info(const unsigned int xid, + ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN; + ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_DEV_SIZE); + memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_DEV, SMB2_WSL_XATTR_NAME_LEN + 1); +- data->wsl.eas_len = sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 + +- SMB2_WSL_XATTR_DEV_SIZE; ++ data->wsl.eas_len += ALIGN(sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 + ++ SMB2_WSL_XATTR_MODE_SIZE, 4); + rc = 0; + } else if (rc >= 0) { + /* It is an error if EA $LXDEV has wrong size. */ +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 79641d1ee86757..232a3c28905568 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -1216,31 +1216,33 @@ int + smb2_set_file_info(struct inode *inode, const char *full_path, + FILE_BASIC_INFO *buf, const unsigned int xid) + { +- struct cifs_open_parms oparms; ++ struct kvec in_iov = { .iov_base = buf, .iov_len = sizeof(*buf), }; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); ++ struct cifsFileInfo *cfile = NULL; ++ struct cifs_open_parms oparms; + struct tcon_link *tlink; + struct cifs_tcon *tcon; +- struct cifsFileInfo *cfile; +- struct kvec in_iov = { .iov_base = buf, .iov_len = sizeof(*buf), }; +- int rc; +- +- if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && +- (buf->LastWriteTime == 0) && (buf->ChangeTime == 0) && +- (buf->Attributes == 0)) +- return 0; /* would be a no op, no sense sending this */ ++ int rc = 0; + + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + tcon = tlink_tcon(tlink); + +- cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); ++ if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && ++ (buf->LastWriteTime == 0) && (buf->ChangeTime == 0)) { ++ if (buf->Attributes == 0) ++ goto out; /* would be a no op, no sense sending this */ ++ cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); ++ } ++ + oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_ATTRIBUTES, + FILE_OPEN, 0, ACL_NO_MODE); + rc = smb2_compound_op(xid, tcon, cifs_sb, + full_path, &oparms, &in_iov, + &(int){SMB2_OP_SET_INFO}, 1, + cfile, NULL, NULL, NULL); ++out: + cifs_put_tlink(tlink); + return rc; + } +diff --git a/fs/smb/server/ksmbd_netlink.h b/fs/smb/server/ksmbd_netlink.h +index f4e55199938d58..c6c1844d444822 100644 +--- a/fs/smb/server/ksmbd_netlink.h ++++ b/fs/smb/server/ksmbd_netlink.h +@@ -108,10 +108,11 @@ struct ksmbd_startup_request { + __u32 smb2_max_credits; /* MAX credits */ + __u32 smbd_max_io_size; /* smbd read write size */ + __u32 max_connections; /* Number of maximum simultaneous connections */ +- __u32 reserved[126]; /* Reserved room */ ++ __u32 max_ip_connections; /* Number of maximum connection per ip address */ ++ __u32 reserved[125]; /* Reserved room */ + __u32 ifc_list_sz; /* interfaces list size */ + __s8 ____payload[]; +-}; ++} __packed; + + #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) + +diff --git a/fs/smb/server/server.h b/fs/smb/server/server.h +index 4d06f2eb0d6adb..d0744498ceed66 100644 +--- a/fs/smb/server/server.h ++++ b/fs/smb/server/server.h +@@ -43,6 +43,7 @@ struct ksmbd_server_config { + unsigned int auth_mechs; + unsigned int max_connections; + unsigned int max_inflight_req; ++ unsigned int max_ip_connections; + + char *conf[SERVER_CONF_WORK_GROUP + 1]; + }; +diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c +index 281101fd1f76f1..80581a7bc1bcc7 100644 +--- a/fs/smb/server/transport_ipc.c ++++ b/fs/smb/server/transport_ipc.c +@@ -321,6 +321,9 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) + if (req->max_connections) + server_conf.max_connections = req->max_connections; + ++ if (req->max_ip_connections) ++ server_conf.max_ip_connections = req->max_ip_connections; ++ + ret = ksmbd_set_netbios_name(req->netbios_name); + ret |= ksmbd_set_server_string(req->server_string); + ret |= ksmbd_set_work_group(req->work_group); +diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c +index 53c536f2ce9f9c..c43a465114289b 100644 +--- a/fs/smb/server/transport_tcp.c ++++ b/fs/smb/server/transport_tcp.c +@@ -240,6 +240,7 @@ static int ksmbd_kthread_fn(void *p) + struct interface *iface = (struct interface *)p; + struct ksmbd_conn *conn; + int ret; ++ unsigned int max_ip_conns; + + while (!kthread_should_stop()) { + mutex_lock(&iface->sock_release_lock); +@@ -257,34 +258,39 @@ static int ksmbd_kthread_fn(void *p) + continue; + } + ++ if (!server_conf.max_ip_connections) ++ goto skip_max_ip_conns_limit; ++ + /* + * Limits repeated connections from clients with the same IP. + */ ++ max_ip_conns = 0; + down_read(&conn_list_lock); +- list_for_each_entry(conn, &conn_list, conns_list) ++ list_for_each_entry(conn, &conn_list, conns_list) { + #if IS_ENABLED(CONFIG_IPV6) + if (client_sk->sk->sk_family == AF_INET6) { + if (memcmp(&client_sk->sk->sk_v6_daddr, +- &conn->inet6_addr, 16) == 0) { +- ret = -EAGAIN; +- break; +- } ++ &conn->inet6_addr, 16) == 0) ++ max_ip_conns++; + } else if (inet_sk(client_sk->sk)->inet_daddr == +- conn->inet_addr) { +- ret = -EAGAIN; +- break; +- } ++ conn->inet_addr) ++ max_ip_conns++; + #else + if (inet_sk(client_sk->sk)->inet_daddr == +- conn->inet_addr) { ++ conn->inet_addr) ++ max_ip_conns++; ++#endif ++ if (server_conf.max_ip_connections <= max_ip_conns) { + ret = -EAGAIN; + break; + } +-#endif ++ } + up_read(&conn_list_lock); + if (ret == -EAGAIN) + continue; + ++skip_max_ip_conns_limit: ++ + if (server_conf.max_connections && + atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { + pr_info_ratelimited("Limit the maximum number of connections(%u)\n", +diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c +index 53104f25de5116..f5dcb8353f862f 100644 +--- a/fs/squashfs/inode.c ++++ b/fs/squashfs/inode.c +@@ -140,8 +140,17 @@ int squashfs_read_inode(struct inode *inode, long long ino) + if (err < 0) + goto failed_read; + ++ inode->i_size = le32_to_cpu(sqsh_ino->file_size); + frag = le32_to_cpu(sqsh_ino->fragment); + if (frag != SQUASHFS_INVALID_FRAG) { ++ /* ++ * the file cannot have a fragment (tailend) and have a ++ * file size a multiple of the block size ++ */ ++ if ((inode->i_size & (msblk->block_size - 1)) == 0) { ++ err = -EINVAL; ++ goto failed_read; ++ } + frag_offset = le32_to_cpu(sqsh_ino->offset); + frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); + if (frag_size < 0) { +@@ -155,7 +164,6 @@ int squashfs_read_inode(struct inode *inode, long long ino) + } + + set_nlink(inode, 1); +- inode->i_size = le32_to_cpu(sqsh_ino->file_size); + inode->i_fop = &generic_ro_fops; + inode->i_mode |= S_IFREG; + inode->i_blocks = ((inode->i_size - 1) >> 9) + 1; +@@ -184,8 +192,21 @@ int squashfs_read_inode(struct inode *inode, long long ino) + if (err < 0) + goto failed_read; + ++ inode->i_size = le64_to_cpu(sqsh_ino->file_size); ++ if (inode->i_size < 0) { ++ err = -EINVAL; ++ goto failed_read; ++ } + frag = le32_to_cpu(sqsh_ino->fragment); + if (frag != SQUASHFS_INVALID_FRAG) { ++ /* ++ * the file cannot have a fragment (tailend) and have a ++ * file size a multiple of the block size ++ */ ++ if ((inode->i_size & (msblk->block_size - 1)) == 0) { ++ err = -EINVAL; ++ goto failed_read; ++ } + frag_offset = le32_to_cpu(sqsh_ino->offset); + frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); + if (frag_size < 0) { +@@ -200,7 +221,6 @@ int squashfs_read_inode(struct inode *inode, long long ino) + + xattr_id = le32_to_cpu(sqsh_ino->xattr); + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); +- inode->i_size = le64_to_cpu(sqsh_ino->file_size); + inode->i_op = &squashfs_inode_ops; + inode->i_fop = &generic_ro_fops; + inode->i_mode |= S_IFREG; +diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h +index 7e9e7e76904369..2b5891515f3d82 100644 +--- a/include/acpi/acpixf.h ++++ b/include/acpi/acpixf.h +@@ -213,6 +213,12 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0); + */ + ACPI_INIT_GLOBAL(u8, acpi_gbl_reduced_hardware, FALSE); + ++/* ++ * ACPI Global Lock is mainly used for systems with SMM, so no-SMM systems ++ * (such as loong_arch) may not have and not use Global Lock. ++ */ ++ACPI_INIT_GLOBAL(u8, acpi_gbl_use_global_lock, TRUE); ++ + /* + * Maximum timeout for While() loop iterations before forced method abort. + * This mechanism is intended to prevent infinite loops during interpreter +diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h +index bac63e874c7bf9..52db695436bb0b 100644 +--- a/include/asm-generic/io.h ++++ b/include/asm-generic/io.h +@@ -74,6 +74,7 @@ + #if IS_ENABLED(CONFIG_TRACE_MMIO_ACCESS) && !(defined(__DISABLE_TRACE_MMIO__)) + #include + ++#define rwmmio_tracepoint_enabled(tracepoint) tracepoint_enabled(tracepoint) + DECLARE_TRACEPOINT(rwmmio_write); + DECLARE_TRACEPOINT(rwmmio_post_write); + DECLARE_TRACEPOINT(rwmmio_read); +@@ -90,6 +91,7 @@ void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr, + + #else + ++#define rwmmio_tracepoint_enabled(tracepoint) false + static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr, + unsigned long caller_addr, unsigned long caller_addr0) {} + static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr, +@@ -188,11 +190,13 @@ static inline u8 readb(const volatile void __iomem *addr) + { + u8 val; + +- log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); + __io_br(); + val = __raw_readb(addr); + __io_ar(val); +- log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -203,11 +207,13 @@ static inline u16 readw(const volatile void __iomem *addr) + { + u16 val; + +- log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); + __io_br(); + val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); + __io_ar(val); +- log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -218,11 +224,13 @@ static inline u32 readl(const volatile void __iomem *addr) + { + u32 val; + +- log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); + __io_br(); + val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); + __io_ar(val); +- log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -234,11 +242,13 @@ static inline u64 readq(const volatile void __iomem *addr) + { + u64 val; + +- log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); + __io_br(); + val = __le64_to_cpu((__le64 __force)__raw_readq(addr)); + __io_ar(val); +- log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -248,11 +258,13 @@ static inline u64 readq(const volatile void __iomem *addr) + #define writeb writeb + static inline void writeb(u8 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); + __io_bw(); + __raw_writeb(value, addr); + __io_aw(); +- log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -260,11 +272,13 @@ static inline void writeb(u8 value, volatile void __iomem *addr) + #define writew writew + static inline void writew(u16 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); + __io_bw(); + __raw_writew((u16 __force)cpu_to_le16(value), addr); + __io_aw(); +- log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -272,11 +286,13 @@ static inline void writew(u16 value, volatile void __iomem *addr) + #define writel writel + static inline void writel(u32 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); + __io_bw(); + __raw_writel((u32 __force)__cpu_to_le32(value), addr); + __io_aw(); +- log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -285,11 +301,13 @@ static inline void writel(u32 value, volatile void __iomem *addr) + #define writeq writeq + static inline void writeq(u64 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); + __io_bw(); + __raw_writeq((u64 __force)__cpu_to_le64(value), addr); + __io_aw(); +- log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); + } + #endif + #endif /* CONFIG_64BIT */ +@@ -305,9 +323,11 @@ static inline u8 readb_relaxed(const volatile void __iomem *addr) + { + u8 val; + +- log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); + val = __raw_readb(addr); +- log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -318,9 +338,11 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr) + { + u16 val; + +- log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); + val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); +- log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -331,9 +353,11 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr) + { + u32 val; + +- log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); + val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); +- log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -344,9 +368,11 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr) + { + u64 val; + +- log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_read)) ++ log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); + val = __le64_to_cpu((__le64 __force)__raw_readq(addr)); +- log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_read)) ++ log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); + return val; + } + #endif +@@ -355,9 +381,11 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr) + #define writeb_relaxed writeb_relaxed + static inline void writeb_relaxed(u8 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); + __raw_writeb(value, addr); +- log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -365,9 +393,11 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr) + #define writew_relaxed writew_relaxed + static inline void writew_relaxed(u16 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); + __raw_writew((u16 __force)cpu_to_le16(value), addr); +- log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -375,9 +405,11 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr) + #define writel_relaxed writel_relaxed + static inline void writel_relaxed(u32 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); + __raw_writel((u32 __force)__cpu_to_le32(value), addr); +- log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); + } + #endif + +@@ -385,9 +417,11 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr) + #define writeq_relaxed writeq_relaxed + static inline void writeq_relaxed(u64 value, volatile void __iomem *addr) + { +- log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_write)) ++ log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); + __raw_writeq((u64 __force)__cpu_to_le64(value), addr); +- log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); ++ if (rwmmio_tracepoint_enabled(rwmmio_post_write)) ++ log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); + } + #endif + +diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h +index de45cf2ee1e4f8..ce2086f97e3fcf 100644 +--- a/include/linux/iio/frequency/adf4350.h ++++ b/include/linux/iio/frequency/adf4350.h +@@ -51,7 +51,7 @@ + + /* REG3 Bit Definitions */ + #define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3) +-#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 16) ++#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 15) + #define ADF4350_REG3_12BIT_CSR_EN (1 << 18) + #define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21) + #define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22) +diff --git a/include/linux/ksm.h b/include/linux/ksm.h +index b9cdeba03668ae..f74c5222484017 100644 +--- a/include/linux/ksm.h ++++ b/include/linux/ksm.h +@@ -59,6 +59,12 @@ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) + int ret; + + if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags)) { ++ long nr_ksm_zero_pages = atomic_long_read(&mm->ksm_zero_pages); ++ ++ mm->ksm_merging_pages = 0; ++ mm->ksm_rmap_items = 0; ++ atomic_long_add(nr_ksm_zero_pages, &ksm_zero_pages); ++ + ret = __ksm_enter(mm); + if (ret) + return ret; +diff --git a/include/linux/sched.h b/include/linux/sched.h +index cb38eee732fd02..9559501236af08 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -2343,6 +2343,12 @@ enum rseq_event_mask { + RSEQ_EVENT_MIGRATE = (1U << RSEQ_EVENT_MIGRATE_BIT), + }; + ++#ifdef CONFIG_MEMBARRIER ++# define RSEQ_EVENT_GUARD irq ++#else ++# define RSEQ_EVENT_GUARD preempt ++#endif ++ + static inline void rseq_set_notify_resume(struct task_struct *t) + { + if (t->rseq) +@@ -2361,9 +2367,8 @@ static inline void rseq_handle_notify_resume(struct ksignal *ksig, + static inline void rseq_signal_deliver(struct ksignal *ksig, + struct pt_regs *regs) + { +- preempt_disable(); +- __set_bit(RSEQ_EVENT_SIGNAL_BIT, ¤t->rseq_event_mask); +- preempt_enable(); ++ scoped_guard(RSEQ_EVENT_GUARD) ++ __set_bit(RSEQ_EVENT_SIGNAL_BIT, ¤t->rseq_event_mask); + rseq_handle_notify_resume(ksig, regs); + } + +diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h +index 0740dfc6c04881..61a497ec5a2a96 100644 +--- a/include/media/v4l2-subdev.h ++++ b/include/media/v4l2-subdev.h +@@ -1881,19 +1881,23 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers; + * + * Note: only legacy non-MC drivers may need this macro. + */ +-#define v4l2_subdev_call_state_try(sd, o, f, args...) \ +- ({ \ +- int __result; \ +- static struct lock_class_key __key; \ +- const char *name = KBUILD_BASENAME \ +- ":" __stringify(__LINE__) ":state->lock"; \ +- struct v4l2_subdev_state *state = \ +- __v4l2_subdev_state_alloc(sd, name, &__key); \ +- v4l2_subdev_lock_state(state); \ +- __result = v4l2_subdev_call(sd, o, f, state, ##args); \ +- v4l2_subdev_unlock_state(state); \ +- __v4l2_subdev_state_free(state); \ +- __result; \ ++#define v4l2_subdev_call_state_try(sd, o, f, args...) \ ++ ({ \ ++ int __result; \ ++ static struct lock_class_key __key; \ ++ const char *name = KBUILD_BASENAME \ ++ ":" __stringify(__LINE__) ":state->lock"; \ ++ struct v4l2_subdev_state *state = \ ++ __v4l2_subdev_state_alloc(sd, name, &__key); \ ++ if (IS_ERR(state)) { \ ++ __result = PTR_ERR(state); \ ++ } else { \ ++ v4l2_subdev_lock_state(state); \ ++ __result = v4l2_subdev_call(sd, o, f, state, ##args); \ ++ v4l2_subdev_unlock_state(state); \ ++ __v4l2_subdev_state_free(state); \ ++ } \ ++ __result; \ + }) + + /** +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index c0f4b91e4f5ece..32606d54306057 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -955,8 +955,7 @@ struct nft_expr_ops { + const struct nft_expr *expr, + bool reset); + int (*validate)(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data); ++ const struct nft_expr *expr); + bool (*reduce)(struct nft_regs_track *track, + const struct nft_expr *expr); + bool (*gc)(struct net *net, +diff --git a/include/net/netfilter/nft_fib.h b/include/net/netfilter/nft_fib.h +index 167640b843ef8a..38cae7113de462 100644 +--- a/include/net/netfilter/nft_fib.h ++++ b/include/net/netfilter/nft_fib.h +@@ -21,9 +21,7 @@ nft_fib_is_loopback(const struct sk_buff *skb, const struct net_device *in) + int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset); + int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + const struct nlattr * const tb[]); +-int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, +- const struct nft_data **data); +- ++int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr); + + void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs, + const struct nft_pktinfo *pkt); +diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h +index ba1238f12a487a..d602263590fed5 100644 +--- a/include/net/netfilter/nft_meta.h ++++ b/include/net/netfilter/nft_meta.h +@@ -41,8 +41,7 @@ void nft_meta_set_destroy(const struct nft_ctx *ctx, + const struct nft_expr *expr); + + int nft_meta_set_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data); ++ const struct nft_expr *expr); + + bool nft_meta_get_reduce(struct nft_regs_track *track, + const struct nft_expr *expr); +diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h +index 6d9ba62efd7504..19060212988a1e 100644 +--- a/include/net/netfilter/nft_reject.h ++++ b/include/net/netfilter/nft_reject.h +@@ -15,8 +15,7 @@ struct nft_reject { + extern const struct nla_policy nft_reject_policy[]; + + int nft_reject_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data); ++ const struct nft_expr *expr); + + int nft_reject_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, +diff --git a/init/main.c b/init/main.c +index c787e94cc8982b..20d2dd4d9b40f0 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -530,6 +530,12 @@ static int __init unknown_bootoption(char *param, char *val, + const char *unused, void *arg) + { + size_t len = strlen(param); ++ /* ++ * Well-known bootloader identifiers: ++ * 1. LILO/Grub pass "BOOT_IMAGE=..."; ++ * 2. kexec/kdump (kexec-tools) pass "kexec". ++ */ ++ const char *bootloader[] = { "BOOT_IMAGE=", "kexec", NULL }; + + /* Handle params aliased to sysctls */ + if (sysctl_is_alias(param)) +@@ -537,6 +543,12 @@ static int __init unknown_bootoption(char *param, char *val, + + repair_env_string(param, val); + ++ /* Handle bootloader identifier */ ++ for (int i = 0; bootloader[i]; i++) { ++ if (strstarts(param, bootloader[i])) ++ return 0; ++ } ++ + /* Handle obsolete-style parameters */ + if (obsolete_checksetup(param)) + return 0; +diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c +index 99d0625b6c828f..9a9630adcba4f6 100644 +--- a/kernel/bpf/inode.c ++++ b/kernel/bpf/inode.c +@@ -607,7 +607,7 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root) + return 0; + } + +-static void bpf_free_inode(struct inode *inode) ++static void bpf_destroy_inode(struct inode *inode) + { + enum bpf_type type; + +@@ -622,7 +622,7 @@ static const struct super_operations bpf_super_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + .show_options = bpf_show_options, +- .free_inode = bpf_free_inode, ++ .destroy_inode = bpf_destroy_inode, + }; + + enum { +diff --git a/kernel/fork.c b/kernel/fork.c +index 0e20d7e9460848..2141ebb2ef92ad 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1799,7 +1799,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk, + return 0; + } + +-static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) ++static int copy_sighand(u64 clone_flags, struct task_struct *tsk) + { + struct sighand_struct *sig; + +diff --git a/kernel/pid.c b/kernel/pid.c +index 6500ef956f2f88..e57adc00cb779b 100644 +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -477,7 +477,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) + struct upid *upid; + pid_t nr = 0; + +- if (pid && ns->level <= pid->level) { ++ if (pid && ns && ns->level <= pid->level) { + upid = &pid->numbers[ns->level]; + if (upid->ns == ns) + nr = upid->nr; +diff --git a/kernel/rseq.c b/kernel/rseq.c +index 23894ba8250cf9..810005f927d7cc 100644 +--- a/kernel/rseq.c ++++ b/kernel/rseq.c +@@ -255,12 +255,12 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags) + + /* + * Load and clear event mask atomically with respect to +- * scheduler preemption. ++ * scheduler preemption and membarrier IPIs. + */ +- preempt_disable(); +- event_mask = t->rseq_event_mask; +- t->rseq_event_mask = 0; +- preempt_enable(); ++ scoped_guard(RSEQ_EVENT_GUARD) { ++ event_mask = t->rseq_event_mask; ++ t->rseq_event_mask = 0; ++ } + + return !!event_mask; + } +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index a15cf7969953a5..5bb9735e19d2f5 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -2214,6 +2214,25 @@ static int find_later_rq(struct task_struct *task) + return -1; + } + ++static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) ++{ ++ struct task_struct *p; ++ ++ if (!has_pushable_dl_tasks(rq)) ++ return NULL; ++ ++ p = __node_2_pdl(rb_first_cached(&rq->dl.pushable_dl_tasks_root)); ++ ++ WARN_ON_ONCE(rq->cpu != task_cpu(p)); ++ WARN_ON_ONCE(task_current(rq, p)); ++ WARN_ON_ONCE(p->nr_cpus_allowed <= 1); ++ ++ WARN_ON_ONCE(!task_on_rq_queued(p)); ++ WARN_ON_ONCE(!dl_task(p)); ++ ++ return p; ++} ++ + /* Locks the rq it finds */ + static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) + { +@@ -2241,12 +2260,37 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) + + /* Retry if something changed. */ + if (double_lock_balance(rq, later_rq)) { +- if (unlikely(task_rq(task) != rq || ++ /* ++ * double_lock_balance had to release rq->lock, in the ++ * meantime, task may no longer be fit to be migrated. ++ * Check the following to ensure that the task is ++ * still suitable for migration: ++ * 1. It is possible the task was scheduled, ++ * migrate_disabled was set and then got preempted, ++ * so we must check the task migration disable ++ * flag. ++ * 2. The CPU picked is in the task's affinity. ++ * 3. For throttled task (dl_task_offline_migration), ++ * check the following: ++ * - the task is not on the rq anymore (it was ++ * migrated) ++ * - the task is not on CPU anymore ++ * - the task is still a dl task ++ * - the task is not queued on the rq anymore ++ * 4. For the non-throttled task (push_dl_task), the ++ * check to ensure that this task is still at the ++ * head of the pushable tasks list is enough. ++ */ ++ if (unlikely(is_migration_disabled(task) || + !cpumask_test_cpu(later_rq->cpu, &task->cpus_mask) || +- task_on_cpu(rq, task) || +- !dl_task(task) || +- is_migration_disabled(task) || +- !task_on_rq_queued(task))) { ++ (task->dl.dl_throttled && ++ (task_rq(task) != rq || ++ task_on_cpu(rq, task) || ++ !dl_task(task) || ++ !task_on_rq_queued(task))) || ++ (!task->dl.dl_throttled && ++ task != pick_next_pushable_dl_task(rq)))) { ++ + double_unlock_balance(rq, later_rq); + later_rq = NULL; + break; +@@ -2269,25 +2313,6 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) + return later_rq; + } + +-static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) +-{ +- struct task_struct *p; +- +- if (!has_pushable_dl_tasks(rq)) +- return NULL; +- +- p = __node_2_pdl(rb_first_cached(&rq->dl.pushable_dl_tasks_root)); +- +- WARN_ON_ONCE(rq->cpu != task_cpu(p)); +- WARN_ON_ONCE(task_current(rq, p)); +- WARN_ON_ONCE(p->nr_cpus_allowed <= 1); +- +- WARN_ON_ONCE(!task_on_rq_queued(p)); +- WARN_ON_ONCE(!dl_task(p)); +- +- return p; +-} +- + /* + * See if the non running -deadline tasks on this rq + * can be sent to some other CPU where they can preempt +diff --git a/kernel/sys.c b/kernel/sys.c +index 355de0b65c2358..47cb10a16b009d 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -1689,6 +1689,7 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, + struct rlimit old, new; + struct task_struct *tsk; + unsigned int checkflags = 0; ++ bool need_tasklist; + int ret; + + if (old_rlim) +@@ -1715,8 +1716,25 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, + get_task_struct(tsk); + rcu_read_unlock(); + +- ret = do_prlimit(tsk, resource, new_rlim ? &new : NULL, +- old_rlim ? &old : NULL); ++ need_tasklist = !same_thread_group(tsk, current); ++ if (need_tasklist) { ++ /* ++ * Ensure we can't race with group exit or de_thread(), ++ * so tsk->group_leader can't be freed or changed until ++ * read_unlock(tasklist_lock) below. ++ */ ++ read_lock(&tasklist_lock); ++ if (!pid_alive(tsk)) ++ ret = -ESRCH; ++ } ++ ++ if (!ret) { ++ ret = do_prlimit(tsk, resource, new_rlim ? &new : NULL, ++ old_rlim ? &old : NULL); ++ } ++ ++ if (need_tasklist) ++ read_unlock(&tasklist_lock); + + if (!ret && old_rlim) { + rlim_to_rlim64(&old, &old64); +diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c +index 93620a78358769..a233262f858c86 100644 +--- a/kernel/trace/trace_fprobe.c ++++ b/kernel/trace/trace_fprobe.c +@@ -342,12 +342,14 @@ static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip, + void *entry_data) + { + struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); ++ unsigned int flags = trace_probe_load_flag(&tf->tp); + int ret = 0; + +- if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) ++ if (flags & TP_FLAG_TRACE) + fentry_trace_func(tf, entry_ip, regs); ++ + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tf->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + ret = fentry_perf_func(tf, entry_ip, regs); + #endif + return ret; +@@ -359,11 +361,12 @@ static void fexit_dispatcher(struct fprobe *fp, unsigned long entry_ip, + void *entry_data) + { + struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); ++ unsigned int flags = trace_probe_load_flag(&tf->tp); + +- if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) ++ if (flags & TP_FLAG_TRACE) + fexit_trace_func(tf, entry_ip, ret_ip, regs, entry_data); + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tf->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + fexit_perf_func(tf, entry_ip, ret_ip, regs, entry_data); + #endif + } +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 46491f3c1569cd..20dbe40ab15e8e 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -1713,14 +1713,15 @@ static int kprobe_register(struct trace_event_call *event, + static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) + { + struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); ++ unsigned int flags = trace_probe_load_flag(&tk->tp); + int ret = 0; + + raw_cpu_inc(*tk->nhit); + +- if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) ++ if (flags & TP_FLAG_TRACE) + kprobe_trace_func(tk, regs); + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + ret = kprobe_perf_func(tk, regs); + #endif + return ret; +@@ -1732,6 +1733,7 @@ kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) + { + struct kretprobe *rp = get_kretprobe(ri); + struct trace_kprobe *tk; ++ unsigned int flags; + + /* + * There is a small chance that get_kretprobe(ri) returns NULL when +@@ -1744,10 +1746,11 @@ kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) + tk = container_of(rp, struct trace_kprobe, rp); + raw_cpu_inc(*tk->nhit); + +- if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) ++ flags = trace_probe_load_flag(&tk->tp); ++ if (flags & TP_FLAG_TRACE) + kretprobe_trace_func(tk, ri, regs); + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + kretprobe_perf_func(tk, ri, regs); + #endif + return 0; /* We don't tweak kernel, so just return 0 */ +diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h +index 48afed3c3f88ec..c71fa9c2f3815b 100644 +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -268,16 +268,21 @@ struct event_file_link { + struct list_head list; + }; + ++static inline unsigned int trace_probe_load_flag(struct trace_probe *tp) ++{ ++ return smp_load_acquire(&tp->event->flags); ++} ++ + static inline bool trace_probe_test_flag(struct trace_probe *tp, + unsigned int flag) + { +- return !!(tp->event->flags & flag); ++ return !!(trace_probe_load_flag(tp) & flag); + } + + static inline void trace_probe_set_flag(struct trace_probe *tp, + unsigned int flag) + { +- tp->event->flags |= flag; ++ smp_store_release(&tp->event->flags, tp->event->flags | flag); + } + + static inline void trace_probe_clear_flag(struct trace_probe *tp, +diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c +index ecf04e81ddf705..03d79a9ebd8c82 100644 +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -1514,6 +1514,7 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) + struct trace_uprobe *tu; + struct uprobe_dispatch_data udd; + struct uprobe_cpu_buffer *ucb = NULL; ++ unsigned int flags; + int ret = 0; + + tu = container_of(con, struct trace_uprobe, consumer); +@@ -1527,11 +1528,12 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) + if (WARN_ON_ONCE(!uprobe_cpu_buffer)) + return 0; + +- if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) ++ flags = trace_probe_load_flag(&tu->tp); ++ if (flags & TP_FLAG_TRACE) + ret |= uprobe_trace_func(tu, regs, &ucb); + + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + ret |= uprobe_perf_func(tu, regs, &ucb); + #endif + uprobe_buffer_put(ucb); +@@ -1544,6 +1546,7 @@ static int uretprobe_dispatcher(struct uprobe_consumer *con, + struct trace_uprobe *tu; + struct uprobe_dispatch_data udd; + struct uprobe_cpu_buffer *ucb = NULL; ++ unsigned int flags; + + tu = container_of(con, struct trace_uprobe, consumer); + +@@ -1555,11 +1558,12 @@ static int uretprobe_dispatcher(struct uprobe_consumer *con, + if (WARN_ON_ONCE(!uprobe_cpu_buffer)) + return 0; + +- if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) ++ flags = trace_probe_load_flag(&tu->tp); ++ if (flags & TP_FLAG_TRACE) + uretprobe_trace_func(tu, func, regs, &ucb); + + #ifdef CONFIG_PERF_EVENTS +- if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) ++ if (flags & TP_FLAG_PROFILE) + uretprobe_perf_func(tu, func, regs, &ucb); + #endif + uprobe_buffer_put(ucb); +diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile +index 8d1446c2be7193..88246000c9d8eb 100644 +--- a/lib/crypto/Makefile ++++ b/lib/crypto/Makefile +@@ -30,6 +30,10 @@ obj-$(CONFIG_CRYPTO_LIB_CURVE25519_GENERIC) += libcurve25519-generic.o + libcurve25519-generic-y := curve25519-fiat32.o + libcurve25519-generic-$(CONFIG_ARCH_SUPPORTS_INT128) := curve25519-hacl64.o + libcurve25519-generic-y += curve25519-generic.o ++# clang versions prior to 18 may blow out the stack with KASAN ++ifeq ($(call clang-min-version, 180000),) ++KASAN_SANITIZE_curve25519-hacl64.o := n ++endif + + obj-$(CONFIG_CRYPTO_LIB_CURVE25519) += libcurve25519.o + libcurve25519-y += curve25519.o +diff --git a/lib/genalloc.c b/lib/genalloc.c +index 4fa5635bf81bd6..841f2978383334 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -899,8 +899,11 @@ struct gen_pool *of_gen_pool_get(struct device_node *np, + if (!name) + name = of_node_full_name(np_pool); + } +- if (pdev) ++ if (pdev) { + pool = gen_pool_get(&pdev->dev, name); ++ put_device(&pdev->dev); ++ } ++ + of_node_put(np_pool); + + return pool; +diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c +index 5764b9885e7d21..4d7dc9f65f682e 100644 +--- a/mm/damon/vaddr.c ++++ b/mm/damon/vaddr.c +@@ -324,10 +324,8 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr, + } + + pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); +- if (!pte) { +- walk->action = ACTION_AGAIN; ++ if (!pte) + return 0; +- } + if (!pte_present(ptep_get(pte))) + goto out; + damon_ptep_mkold(pte, walk->vma, addr); +@@ -479,10 +477,8 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr, + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + + pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); +- if (!pte) { +- walk->action = ACTION_AGAIN; ++ if (!pte) + return 0; +- } + ptent = ptep_get(pte); + if (!pte_present(ptent)) + goto out; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 0c6745a6a13a59..532a840a426646 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -3298,6 +3298,9 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h) + return; + } + ++ if (!h->max_huge_pages) ++ return; ++ + /* do node specific alloc */ + for_each_online_node(i) { + if (h->max_huge_pages_node[i] > 0) { +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 44011ebecddf01..93cb65c6553ec3 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3738,7 +3738,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask, unsigned int order) + if (!(gfp_mask & __GFP_NOMEMALLOC)) { + alloc_flags |= ALLOC_NON_BLOCK; + +- if (order > 0) ++ if (order > 0 && (alloc_flags & ALLOC_MIN_RESERVE)) + alloc_flags |= ALLOC_HIGHATOMIC; + } + +diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c +index a1c22eab71ffec..cc54b8267bcc7b 100644 +--- a/net/bridge/br_vlan.c ++++ b/net/bridge/br_vlan.c +@@ -1455,7 +1455,7 @@ void br_vlan_fill_forward_path_pvid(struct net_bridge *br, + if (!br_opt_get(br, BROPT_VLAN_ENABLED)) + return; + +- vg = br_vlan_group(br); ++ vg = br_vlan_group_rcu(br); + + if (idx >= 0 && + ctx->vlan[idx].proto == br->vlan_proto) { +diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c +index bd4d1b4d745f64..affb740c8685eb 100644 +--- a/net/bridge/netfilter/nft_meta_bridge.c ++++ b/net/bridge/netfilter/nft_meta_bridge.c +@@ -168,8 +168,7 @@ static bool nft_meta_bridge_set_reduce(struct nft_regs_track *track, + } + + static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + struct nft_meta *priv = nft_expr_priv(expr); + unsigned int hooks; +@@ -179,7 +178,7 @@ static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx, + hooks = 1 << NF_BR_PRE_ROUTING; + break; + default: +- return nft_meta_set_validate(ctx, expr, data); ++ return nft_meta_set_validate(ctx, expr); + } + + return nft_chain_validate_hooks(ctx->chain, hooks); +diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c +index 71b54fed7263df..1cb5c16e97b7fa 100644 +--- a/net/bridge/netfilter/nft_reject_bridge.c ++++ b/net/bridge/netfilter/nft_reject_bridge.c +@@ -170,8 +170,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr, + } + + static int nft_reject_bridge_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + return nft_chain_validate_hooks(ctx->chain, (1 << NF_BR_PRE_ROUTING) | + (1 << NF_BR_LOCAL_IN)); +diff --git a/net/core/filter.c b/net/core/filter.c +index b6dbcef649654c..c2e888ea54abbf 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2273,6 +2273,7 @@ static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev, + if (IS_ERR(dst)) + goto out_drop; + ++ skb_dst_drop(skb); + skb_dst_set(skb, dst); + } else if (nh->nh_family != AF_INET6) { + goto out_drop; +@@ -2382,6 +2383,7 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev, + goto out_drop; + } + ++ skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 7d824578f217a8..5dde0aed314405 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1724,6 +1724,7 @@ EXPORT_SYMBOL(tcp_peek_len); + /* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ + int tcp_set_rcvlowat(struct sock *sk, int val) + { ++ struct tcp_sock *tp = tcp_sk(sk); + int space, cap; + + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) +@@ -1742,7 +1743,9 @@ int tcp_set_rcvlowat(struct sock *sk, int val) + space = tcp_space_from_win(sk, val); + if (space > sk->sk_rcvbuf) { + WRITE_ONCE(sk->sk_rcvbuf, space); +- WRITE_ONCE(tcp_sk(sk)->window_clamp, val); ++ ++ if (tp->window_clamp && tp->window_clamp < val) ++ WRITE_ONCE(tp->window_clamp, val); + } + return 0; + } +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index c6d00817ad3fd9..8834cd41b38408 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -7200,7 +7200,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, + &foc, TCP_SYNACK_FASTOPEN, skb); + /* Add the child socket directly into the accept queue */ + if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { +- reqsk_fastopen_remove(fastopen_sk, req, false); + bh_unlock_sock(fastopen_sk); + sock_put(fastopen_sk); + goto drop_and_free; +diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c +index 29c167e5fc0255..ab7bdb6531816d 100644 +--- a/net/mptcp/pm.c ++++ b/net/mptcp/pm.c +@@ -227,9 +227,12 @@ void mptcp_pm_add_addr_received(const struct sock *ssk, + } else { + __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); + } +- /* id0 should not have a different address */ ++ /* - id0 should not have a different address ++ * - special case for C-flag: linked to fill_local_addresses_vec() ++ */ + } else if ((addr->id == 0 && !mptcp_pm_nl_is_init_remote_addr(msk, addr)) || +- (addr->id > 0 && !READ_ONCE(pm->accept_addr))) { ++ (addr->id > 0 && !READ_ONCE(pm->accept_addr) && ++ !mptcp_pm_add_addr_c_flag_case(msk))) { + mptcp_pm_announce_addr(msk, addr, true); + mptcp_pm_add_addr_send_ack(msk); + } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index de24989b05a600..9d2c38421f7a2b 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -675,10 +675,12 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk, + struct mptcp_addr_info mpc_addr; + struct pm_nl_pernet *pernet; + unsigned int subflows_max; ++ bool c_flag_case; + int i = 0; + + pernet = pm_nl_get_pernet_from_msk(msk); + subflows_max = mptcp_pm_get_subflows_max(msk); ++ c_flag_case = remote->id && mptcp_pm_add_addr_c_flag_case(msk); + + mptcp_local_address((struct sock_common *)msk, &mpc_addr); + +@@ -691,11 +693,26 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk, + continue; + + if (msk->pm.subflows < subflows_max) { ++ bool is_id0; ++ + msk->pm.subflows++; + addrs[i] = entry->addr; + ++ is_id0 = mptcp_addresses_equal(&entry->addr, ++ &mpc_addr, ++ entry->addr.port); ++ ++ if (c_flag_case && ++ (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)) { ++ __clear_bit(addrs[i].id, ++ msk->pm.id_avail_bitmap); ++ ++ if (!is_id0) ++ msk->pm.local_addr_used++; ++ } ++ + /* Special case for ID0: set the correct ID */ +- if (mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port)) ++ if (is_id0) + addrs[i].id = 0; + + i++; +@@ -703,6 +720,39 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk, + } + rcu_read_unlock(); + ++ /* Special case: peer sets the C flag, accept one ADD_ADDR if default ++ * limits are used -- accepting no ADD_ADDR -- and use subflow endpoints ++ */ ++ if (!i && c_flag_case) { ++ unsigned int local_addr_max = mptcp_pm_get_local_addr_max(msk); ++ ++ while (msk->pm.local_addr_used < local_addr_max && ++ msk->pm.subflows < subflows_max) { ++ struct mptcp_pm_addr_entry local; ++ ++ if (!select_local_address(pernet, msk, &local)) ++ break; ++ ++ __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); ++ ++ if (!mptcp_pm_addr_families_match(sk, &local.addr, ++ remote)) ++ continue; ++ ++ if (mptcp_addresses_equal(&local.addr, &mpc_addr, ++ local.addr.port)) ++ continue; ++ ++ addrs[i] = local.addr; ++ ++ msk->pm.local_addr_used++; ++ msk->pm.subflows++; ++ i++; ++ } ++ ++ return i; ++ } ++ + /* If the array is empty, fill in the single + * 'IPADDRANY' local address + */ +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index c5f41cdb36c4b1..1f213706dfaa52 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -1080,6 +1080,14 @@ static inline void mptcp_pm_close_subflow(struct mptcp_sock *msk) + spin_unlock_bh(&msk->pm.lock); + } + ++static inline bool mptcp_pm_add_addr_c_flag_case(struct mptcp_sock *msk) ++{ ++ return READ_ONCE(msk->pm.remote_deny_join_id0) && ++ msk->pm.local_addr_used == 0 && ++ mptcp_pm_get_add_addr_accept_max(msk) == 0 && ++ msk->pm.subflows < mptcp_pm_get_subflows_max(msk); ++} ++ + void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk); + void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk); + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 4ffb5ef79ca13f..5ca1d775e976d4 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3793,7 +3793,6 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + { + struct nft_expr *expr, *last; +- const struct nft_data *data; + struct nft_rule *rule; + int err; + +@@ -3814,7 +3813,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + /* This may call nft_chain_validate() recursively, + * callers that do so must increment ctx->level. + */ +- err = expr->ops->validate(ctx, expr, &data); ++ err = expr->ops->validate(ctx, expr); + if (err < 0) + return err; + } +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index d3d11dede54507..52cdfee17f73f1 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -350,8 +350,7 @@ static int nft_target_dump(struct sk_buff *skb, + } + + static int nft_target_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + struct xt_target *target = expr->ops->data; + unsigned int hook_mask = 0; +@@ -611,8 +610,7 @@ static int nft_match_large_dump(struct sk_buff *skb, + } + + static int nft_match_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + struct xt_match *match = expr->ops->data; + unsigned int hook_mask = 0; +diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c +index bf825f6cb974ea..507b7eba9bcdcb 100644 +--- a/net/netfilter/nft_fib.c ++++ b/net/netfilter/nft_fib.c +@@ -26,8 +26,7 @@ const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = { + }; + EXPORT_SYMBOL(nft_fib_policy); + +-int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, +- const struct nft_data **data) ++int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr) + { + const struct nft_fib *priv = nft_expr_priv(expr); + unsigned int hooks; +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 5a3d6854204202..1894032a7971c6 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -385,8 +385,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, + } + + static int nft_flow_offload_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + unsigned int hook_mask = (1 << NF_INET_FORWARD); + +diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c +index a5268e6dd32f1b..fa9e4ae00b16a9 100644 +--- a/net/netfilter/nft_fwd_netdev.c ++++ b/net/netfilter/nft_fwd_netdev.c +@@ -204,8 +204,7 @@ static int nft_fwd_neigh_dump(struct sk_buff *skb, + } + + static int nft_fwd_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS) | + (1 << NF_NETDEV_EGRESS)); +diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c +index ac2422c215e545..02ee5fb69871f8 100644 +--- a/net/netfilter/nft_immediate.c ++++ b/net/netfilter/nft_immediate.c +@@ -244,8 +244,7 @@ static int nft_immediate_dump(struct sk_buff *skb, + } + + static int nft_immediate_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **d) ++ const struct nft_expr *expr) + { + const struct nft_immediate_expr *priv = nft_expr_priv(expr); + struct nft_ctx *pctx = (struct nft_ctx *)ctx; +diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c +index 1b9edf2b339373..dd5441f92fdb06 100644 +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -206,8 +206,7 @@ static int nft_lookup_dump(struct sk_buff *skb, + } + + static int nft_lookup_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **d) ++ const struct nft_expr *expr) + { + const struct nft_lookup *priv = nft_expr_priv(expr); + struct nft_set_iter iter; +diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c +index 8a14aaca93bbdf..eee05394c53390 100644 +--- a/net/netfilter/nft_masq.c ++++ b/net/netfilter/nft_masq.c +@@ -27,8 +27,7 @@ static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { + }; + + static int nft_masq_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + int err; + +diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c +index 9139ce38ea7b9a..dec76d28a0ac64 100644 +--- a/net/netfilter/nft_meta.c ++++ b/net/netfilter/nft_meta.c +@@ -581,8 +581,7 @@ static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx) + } + + static int nft_meta_get_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + const struct nft_meta *priv = nft_expr_priv(expr); + +@@ -600,8 +599,7 @@ static int nft_meta_get_validate(const struct nft_ctx *ctx, + } + + int nft_meta_set_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + struct nft_meta *priv = nft_expr_priv(expr); + unsigned int hooks; +diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c +index 808f5802c2704a..3d3e639a7a8370 100644 +--- a/net/netfilter/nft_nat.c ++++ b/net/netfilter/nft_nat.c +@@ -137,8 +137,7 @@ static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = { + }; + + static int nft_nat_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + struct nft_nat *priv = nft_expr_priv(expr); + int err; +diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c +index 509011b1ef597c..08a27433e2f5fc 100644 +--- a/net/netfilter/nft_objref.c ++++ b/net/netfilter/nft_objref.c +@@ -22,6 +22,35 @@ void nft_objref_eval(const struct nft_expr *expr, + obj->ops->eval(obj, regs, pkt); + } + ++static int nft_objref_validate_obj_type(const struct nft_ctx *ctx, u32 type) ++{ ++ unsigned int hooks; ++ ++ switch (type) { ++ case NFT_OBJECT_SYNPROXY: ++ if (ctx->family != NFPROTO_IPV4 && ++ ctx->family != NFPROTO_IPV6 && ++ ctx->family != NFPROTO_INET) ++ return -EOPNOTSUPP; ++ ++ hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD); ++ ++ return nft_chain_validate_hooks(ctx->chain, hooks); ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int nft_objref_validate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ struct nft_object *obj = nft_objref_priv(expr); ++ ++ return nft_objref_validate_obj_type(ctx, obj->ops->type->type); ++} ++ + static int nft_objref_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) +@@ -93,6 +122,7 @@ static const struct nft_expr_ops nft_objref_ops = { + .activate = nft_objref_activate, + .deactivate = nft_objref_deactivate, + .dump = nft_objref_dump, ++ .validate = nft_objref_validate, + .reduce = NFT_REDUCE_READONLY, + }; + +@@ -198,6 +228,14 @@ static void nft_objref_map_destroy(const struct nft_ctx *ctx, + nf_tables_destroy_set(ctx, priv->set); + } + ++static int nft_objref_map_validate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ const struct nft_objref_map *priv = nft_expr_priv(expr); ++ ++ return nft_objref_validate_obj_type(ctx, priv->set->objtype); ++} ++ + static const struct nft_expr_ops nft_objref_map_ops = { + .type = &nft_objref_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_objref_map)), +@@ -207,6 +245,7 @@ static const struct nft_expr_ops nft_objref_map_ops = { + .deactivate = nft_objref_map_deactivate, + .destroy = nft_objref_map_destroy, + .dump = nft_objref_map_dump, ++ .validate = nft_objref_map_validate, + .reduce = NFT_REDUCE_READONLY, + }; + +diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c +index 7f61506e5b44bd..123b4f47ccef4c 100644 +--- a/net/netfilter/nft_osf.c ++++ b/net/netfilter/nft_osf.c +@@ -113,8 +113,7 @@ static int nft_osf_dump(struct sk_buff *skb, + } + + static int nft_osf_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + unsigned int hooks; + +diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c +index b2b8127c8d4381..b8ebb187814f29 100644 +--- a/net/netfilter/nft_queue.c ++++ b/net/netfilter/nft_queue.c +@@ -69,8 +69,7 @@ static void nft_queue_sreg_eval(const struct nft_expr *expr, + } + + static int nft_queue_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + static const unsigned int supported_hooks = ((1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN) | +diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c +index a58bd8d291ff2d..9051863509f319 100644 +--- a/net/netfilter/nft_redir.c ++++ b/net/netfilter/nft_redir.c +@@ -27,8 +27,7 @@ static const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = { + }; + + static int nft_redir_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + int err; + +diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c +index ed2e668474d677..196a92c7ea09b7 100644 +--- a/net/netfilter/nft_reject.c ++++ b/net/netfilter/nft_reject.c +@@ -24,8 +24,7 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { + EXPORT_SYMBOL_GPL(nft_reject_policy); + + int nft_reject_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + return nft_chain_validate_hooks(ctx->chain, + (1 << NF_INET_LOCAL_IN) | +diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c +index 973fa31a9dd6cd..49020e67304ad7 100644 +--- a/net/netfilter/nft_reject_inet.c ++++ b/net/netfilter/nft_reject_inet.c +@@ -61,8 +61,7 @@ static void nft_reject_inet_eval(const struct nft_expr *expr, + } + + static int nft_reject_inet_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + return nft_chain_validate_hooks(ctx->chain, + (1 << NF_INET_LOCAL_IN) | +diff --git a/net/netfilter/nft_reject_netdev.c b/net/netfilter/nft_reject_netdev.c +index 7865cd8b11bb6a..2558ce1505d989 100644 +--- a/net/netfilter/nft_reject_netdev.c ++++ b/net/netfilter/nft_reject_netdev.c +@@ -145,8 +145,7 @@ static void nft_reject_netdev_eval(const struct nft_expr *expr, + } + + static int nft_reject_netdev_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS)); + } +diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c +index 2434c624aafde1..9525f1e02a7d83 100644 +--- a/net/netfilter/nft_rt.c ++++ b/net/netfilter/nft_rt.c +@@ -160,8 +160,7 @@ static int nft_rt_get_dump(struct sk_buff *skb, + return -1; + } + +-static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, +- const struct nft_data **data) ++static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expr) + { + const struct nft_rt *priv = nft_expr_priv(expr); + unsigned int hooks; +diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c +index 187b667bad6c34..35d0409b009501 100644 +--- a/net/netfilter/nft_socket.c ++++ b/net/netfilter/nft_socket.c +@@ -275,8 +275,7 @@ static bool nft_socket_reduce(struct nft_regs_track *track, + } + + static int nft_socket_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && +diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c +index 1d737f89dfc18c..5d3e5182598596 100644 +--- a/net/netfilter/nft_synproxy.c ++++ b/net/netfilter/nft_synproxy.c +@@ -248,8 +248,7 @@ static void nft_synproxy_eval(const struct nft_expr *expr, + } + + static int nft_synproxy_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && +diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c +index 71412adb73d414..ed344af2a439be 100644 +--- a/net/netfilter/nft_tproxy.c ++++ b/net/netfilter/nft_tproxy.c +@@ -313,8 +313,7 @@ static int nft_tproxy_dump(struct sk_buff *skb, + } + + static int nft_tproxy_validate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- const struct nft_data **data) ++ const struct nft_expr *expr) + { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && +diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c +index 1c866757db5524..8a07b46cc8fb73 100644 +--- a/net/netfilter/nft_xfrm.c ++++ b/net/netfilter/nft_xfrm.c +@@ -229,8 +229,7 @@ static int nft_xfrm_get_dump(struct sk_buff *skb, + return 0; + } + +-static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, +- const struct nft_data **data) ++static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *expr) + { + const struct nft_xfrm *priv = nft_expr_priv(expr); + unsigned int hooks; +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index 08527d882e56ef..eb2ed7db3fe16b 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -31,6 +31,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include ++#include + #include + #include + #include +@@ -1796,7 +1797,7 @@ struct sctp_association *sctp_unpack_cookie( + } + } + +- if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { ++ if (crypto_memneq(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { + *error = -SCTP_IERROR_BAD_SIG; + goto fail; + } +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 808863e047e0c0..cd18b22b2bbaee 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -30,6 +30,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -884,7 +885,8 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, + return SCTP_DISPOSITION_CONSUME; + + nomem_authev: +- sctp_ulpevent_free(ai_ev); ++ if (ai_ev) ++ sctp_ulpevent_free(ai_ev); + nomem_aiev: + sctp_ulpevent_free(ev); + nomem_ev: +@@ -4415,7 +4417,7 @@ static enum sctp_ierror sctp_sf_authenticate( + sh_key, GFP_ATOMIC); + + /* Discard the packet if the digests do not match */ +- if (memcmp(save_digest, digest, sig_len)) { ++ if (crypto_memneq(save_digest, digest, sig_len)) { + kfree(save_digest); + return SCTP_IERROR_BAD_SIG; + } +diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c +index aa108bea6739b3..ddcbfaede6849a 100644 +--- a/security/keys/trusted-keys/trusted_tpm1.c ++++ b/security/keys/trusted-keys/trusted_tpm1.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -241,7 +242,7 @@ int TSS_checkhmac1(unsigned char *buffer, + if (ret < 0) + goto out; + +- if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) ++ if (crypto_memneq(testhmac, authdata, SHA1_DIGEST_SIZE)) + ret = -EINVAL; + out: + kfree_sensitive(sdesc); +@@ -334,7 +335,7 @@ static int TSS_checkhmac2(unsigned char *buffer, + TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0); + if (ret < 0) + goto out; +- if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { ++ if (crypto_memneq(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { + ret = -EINVAL; + goto out; + } +@@ -343,7 +344,7 @@ static int TSS_checkhmac2(unsigned char *buffer, + TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0); + if (ret < 0) + goto out; +- if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) ++ if (crypto_memneq(testhmac2, authdata2, SHA1_DIGEST_SIZE)) + ret = -EINVAL; + out: + kfree_sensitive(sdesc); +diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h +index 0fb759c6eeaf94..07bd84204baa7f 100644 +--- a/sound/soc/sof/ipc4-topology.h ++++ b/sound/soc/sof/ipc4-topology.h +@@ -59,8 +59,8 @@ + + #define SOF_IPC4_INVALID_NODE_ID 0xffffffff + +-/* FW requires minimum 2ms DMA buffer size */ +-#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 2 ++/* FW requires minimum 4ms DMA buffer size */ ++#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 4 + + /* + * The base of multi-gateways. Multi-gateways addressing starts from +diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile +index 4f869fff28fe43..17e03236e3461c 100644 +--- a/tools/build/feature/Makefile ++++ b/tools/build/feature/Makefile +@@ -306,10 +306,10 @@ $(OUTPUT)test-libbabeltrace.bin: + $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace) + + $(OUTPUT)test-compile-32.bin: +- $(CC) -m32 -o $@ test-compile.c ++ $(CC) -m32 -Wall -Werror -o $@ test-compile.c + + $(OUTPUT)test-compile-x32.bin: +- $(CC) -mx32 -o $@ test-compile.c ++ $(CC) -mx32 -Wall -Werror -o $@ test-compile.c + + $(OUTPUT)test-zlib.bin: + $(BUILD) -lz +diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h +index ae64090184d328..b50960cce23f24 100644 +--- a/tools/lib/perf/include/perf/event.h ++++ b/tools/lib/perf/include/perf/event.h +@@ -285,6 +285,7 @@ struct perf_record_header_event_type { + struct perf_record_header_tracing_data { + struct perf_event_header header; + __u32 size; ++ __u32 pad; + }; + + #define PERF_RECORD_MISC_BUILD_ID_SIZE (1 << 15) +diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c +index 9692ebdd7f11e9..1512fedd90cf9a 100644 +--- a/tools/perf/builtin-stat.c ++++ b/tools/perf/builtin-stat.c +@@ -638,8 +638,7 @@ static enum counter_recovery stat_handle_error(struct evsel *counter) + * (behavior changed with commit b0a873e). + */ + if (errno == EINVAL || errno == ENOSYS || +- errno == ENOENT || errno == EOPNOTSUPP || +- errno == ENXIO) { ++ errno == ENOENT || errno == ENXIO) { + if (verbose > 0) + ui__warning("%s event is not supported by the kernel.\n", + evsel__name(counter)); +@@ -657,7 +656,7 @@ static enum counter_recovery stat_handle_error(struct evsel *counter) + if (verbose > 0) + ui__warning("%s\n", msg); + return COUNTER_RETRY; +- } else if (target__has_per_thread(&target) && ++ } else if (target__has_per_thread(&target) && errno != EOPNOTSUPP && + evsel_list->core.threads && + evsel_list->core.threads->err_thread != -1) { + /* +@@ -678,6 +677,19 @@ static enum counter_recovery stat_handle_error(struct evsel *counter) + return COUNTER_SKIP; + } + ++ if (errno == EOPNOTSUPP) { ++ if (verbose > 0) { ++ ui__warning("%s event is not supported by the kernel.\n", ++ evsel__name(counter)); ++ } ++ counter->supported = false; ++ counter->errored = true; ++ ++ if ((evsel__leader(counter) != counter) || ++ !(counter->core.leader->nr_members > 1)) ++ return COUNTER_SKIP; ++ } ++ + evsel__open_strerror(counter, &target, errno, msg, sizeof(msg)); + ui__error("%s\n", msg); + +diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c +index 1c4feec1adff11..6e7f053006b4ff 100644 +--- a/tools/perf/tests/perf-record.c ++++ b/tools/perf/tests/perf-record.c +@@ -115,6 +115,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest + if (err < 0) { + pr_debug("sched__get_first_possible_cpu: %s\n", + str_error_r(errno, sbuf, sizeof(sbuf))); ++ evlist__cancel_workload(evlist); + goto out_delete_evlist; + } + +@@ -126,6 +127,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest + if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { + pr_debug("sched_setaffinity: %s\n", + str_error_r(errno, sbuf, sizeof(sbuf))); ++ evlist__cancel_workload(evlist); + goto out_delete_evlist; + } + +@@ -137,6 +139,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", + str_error_r(errno, sbuf, sizeof(sbuf))); ++ evlist__cancel_workload(evlist); + goto out_delete_evlist; + } + +@@ -149,6 +152,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest + if (err < 0) { + pr_debug("evlist__mmap: %s\n", + str_error_r(errno, sbuf, sizeof(sbuf))); ++ evlist__cancel_workload(evlist); + goto out_delete_evlist; + } + +diff --git a/tools/perf/tests/shell/stat.sh b/tools/perf/tests/shell/stat.sh +index 3f1e67795490a0..62f13dfeae8e4d 100755 +--- a/tools/perf/tests/shell/stat.sh ++++ b/tools/perf/tests/shell/stat.sh +@@ -146,6 +146,34 @@ test_cputype() { + echo "cputype test [Success]" + } + ++test_hybrid() { ++ # Test the default stat command on hybrid devices opens one cycles event for ++ # each CPU type. ++ echo "hybrid test" ++ ++ # Count the number of core PMUs, assume minimum of 1 ++ pmus=$(ls /sys/bus/event_source/devices/*/cpus 2>/dev/null | wc -l) ++ if [ "$pmus" -lt 1 ] ++ then ++ pmus=1 ++ fi ++ ++ # Run default Perf stat ++ cycles_events=$(perf stat -- true 2>&1 | grep -E "/cycles/[uH]*| cycles[:uH]* " -c) ++ ++ # The expectation is that default output will have a cycles events on each ++ # hybrid PMU. In situations with no cycles PMU events, like virtualized, this ++ # can fall back to task-clock and so the end count may be 0. Fail if neither ++ # condition holds. ++ if [ "$pmus" -ne "$cycles_events" ] && [ "0" -ne "$cycles_events" ] ++ then ++ echo "hybrid test [Found $pmus PMUs but $cycles_events cycles events. Failed]" ++ err=1 ++ return ++ fi ++ echo "hybrid test [Success]" ++} ++ + test_default_stat + test_stat_record_report + test_stat_record_script +@@ -153,4 +181,5 @@ test_stat_repeat_weak_groups + test_topdown_groups + test_topdown_weak_groups + test_cputype ++test_hybrid + exit $err +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h +index 1443c28545a946..358c611eeddbb3 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h +@@ -56,15 +56,15 @@ enum arm_spe_op_type { + ARM_SPE_OP_BR_INDIRECT = 1 << 17, + }; + +-enum arm_spe_neoverse_data_source { +- ARM_SPE_NV_L1D = 0x0, +- ARM_SPE_NV_L2 = 0x8, +- ARM_SPE_NV_PEER_CORE = 0x9, +- ARM_SPE_NV_LOCAL_CLUSTER = 0xa, +- ARM_SPE_NV_SYS_CACHE = 0xb, +- ARM_SPE_NV_PEER_CLUSTER = 0xc, +- ARM_SPE_NV_REMOTE = 0xd, +- ARM_SPE_NV_DRAM = 0xe, ++enum arm_spe_common_data_source { ++ ARM_SPE_COMMON_DS_L1D = 0x0, ++ ARM_SPE_COMMON_DS_L2 = 0x8, ++ ARM_SPE_COMMON_DS_PEER_CORE = 0x9, ++ ARM_SPE_COMMON_DS_LOCAL_CLUSTER = 0xa, ++ ARM_SPE_COMMON_DS_SYS_CACHE = 0xb, ++ ARM_SPE_COMMON_DS_PEER_CLUSTER = 0xc, ++ ARM_SPE_COMMON_DS_REMOTE = 0xd, ++ ARM_SPE_COMMON_DS_DRAM = 0xe, + }; + + struct arm_spe_record { +diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c +index 9848310cee5f35..0302e6407b5a20 100644 +--- a/tools/perf/util/arm-spe.c ++++ b/tools/perf/util/arm-spe.c +@@ -411,15 +411,15 @@ static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq, + return arm_spe_deliver_synth_event(spe, speq, event, &sample); + } + +-static const struct midr_range neoverse_spe[] = { ++static const struct midr_range common_ds_encoding_cpus[] = { + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), + {}, + }; + +-static void arm_spe__synth_data_source_neoverse(const struct arm_spe_record *record, +- union perf_mem_data_src *data_src) ++static void arm_spe__synth_data_source_common(const struct arm_spe_record *record, ++ union perf_mem_data_src *data_src) + { + /* + * Even though four levels of cache hierarchy are possible, no known +@@ -441,17 +441,17 @@ static void arm_spe__synth_data_source_neoverse(const struct arm_spe_record *rec + } + + switch (record->source) { +- case ARM_SPE_NV_L1D: ++ case ARM_SPE_COMMON_DS_L1D: + data_src->mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1; + data_src->mem_snoop = PERF_MEM_SNOOP_NONE; + break; +- case ARM_SPE_NV_L2: ++ case ARM_SPE_COMMON_DS_L2: + data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2; + data_src->mem_snoop = PERF_MEM_SNOOP_NONE; + break; +- case ARM_SPE_NV_PEER_CORE: ++ case ARM_SPE_COMMON_DS_PEER_CORE: + data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2; + data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER; +@@ -460,8 +460,8 @@ static void arm_spe__synth_data_source_neoverse(const struct arm_spe_record *rec + * We don't know if this is L1, L2 but we do know it was a cache-2-cache + * transfer, so set SNOOPX_PEER + */ +- case ARM_SPE_NV_LOCAL_CLUSTER: +- case ARM_SPE_NV_PEER_CLUSTER: ++ case ARM_SPE_COMMON_DS_LOCAL_CLUSTER: ++ case ARM_SPE_COMMON_DS_PEER_CLUSTER: + data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3; + data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER; +@@ -469,7 +469,7 @@ static void arm_spe__synth_data_source_neoverse(const struct arm_spe_record *rec + /* + * System cache is assumed to be L3 + */ +- case ARM_SPE_NV_SYS_CACHE: ++ case ARM_SPE_COMMON_DS_SYS_CACHE: + data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3; + data_src->mem_snoop = PERF_MEM_SNOOP_HIT; +@@ -478,13 +478,13 @@ static void arm_spe__synth_data_source_neoverse(const struct arm_spe_record *rec + * We don't know what level it hit in, except it came from the other + * socket + */ +- case ARM_SPE_NV_REMOTE: +- data_src->mem_lvl = PERF_MEM_LVL_REM_CCE1; +- data_src->mem_lvl_num = PERF_MEM_LVLNUM_ANY_CACHE; ++ case ARM_SPE_COMMON_DS_REMOTE: ++ data_src->mem_lvl = PERF_MEM_LVL_NA; ++ data_src->mem_lvl_num = PERF_MEM_LVLNUM_NA; + data_src->mem_remote = PERF_MEM_REMOTE_REMOTE; + data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER; + break; +- case ARM_SPE_NV_DRAM: ++ case ARM_SPE_COMMON_DS_DRAM: + data_src->mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT; + data_src->mem_lvl_num = PERF_MEM_LVLNUM_RAM; + data_src->mem_snoop = PERF_MEM_SNOOP_NONE; +@@ -514,13 +514,13 @@ static void arm_spe__synth_data_source_generic(const struct arm_spe_record *reco + } + + if (record->type & ARM_SPE_REMOTE_ACCESS) +- data_src->mem_lvl |= PERF_MEM_LVL_REM_CCE1; ++ data_src->mem_remote = PERF_MEM_REMOTE_REMOTE; + } + + static u64 arm_spe__synth_data_source(const struct arm_spe_record *record, u64 midr) + { + union perf_mem_data_src data_src = { .mem_op = PERF_MEM_OP_NA }; +- bool is_neoverse = is_midr_in_range_list(midr, neoverse_spe); ++ bool is_common = is_midr_in_range_list(midr, common_ds_encoding_cpus); + + /* Only synthesize data source for LDST operations */ + if (!is_ldst_op(record->op)) +@@ -533,8 +533,8 @@ static u64 arm_spe__synth_data_source(const struct arm_spe_record *record, u64 m + else + return 0; + +- if (is_neoverse) +- arm_spe__synth_data_source_neoverse(record, &data_src); ++ if (is_common) ++ arm_spe__synth_data_source_common(record, &data_src); + else + arm_spe__synth_data_source_generic(record, &data_src); + +diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c +index 2a6295f1ac1bc0..6d1327f8c6043a 100644 +--- a/tools/perf/util/evsel.c ++++ b/tools/perf/util/evsel.c +@@ -2874,7 +2874,7 @@ bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) + + /* If event has exclude user then don't exclude kernel. */ + if (evsel->core.attr.exclude_user) +- return false; ++ goto no_fallback; + + /* Is there already the separator in the name. */ + if (strchr(name, '/') || +@@ -2882,7 +2882,7 @@ bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) + sep = ""; + + if (asprintf(&new_name, "%s%su", name, sep) < 0) +- return false; ++ goto no_fallback; + + free(evsel->name); + evsel->name = new_name; +@@ -2893,8 +2893,31 @@ bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) + evsel->core.attr.exclude_hv = 1; + + return true; +- } ++ } else if (err == EOPNOTSUPP && !evsel->core.attr.exclude_guest && ++ !evsel->exclude_GH) { ++ const char *name = evsel__name(evsel); ++ char *new_name; ++ const char *sep = ":"; ++ ++ /* Is there already the separator in the name. */ ++ if (strchr(name, '/') || ++ (strchr(name, ':') && !evsel->is_libpfm_event)) ++ sep = ""; ++ ++ if (asprintf(&new_name, "%s%sH", name, sep) < 0) ++ goto no_fallback; + ++ free(evsel->name); ++ evsel->name = new_name; ++ /* Apple M1 requires exclude_guest */ ++ scnprintf(msg, msgsize, "Trying to fall back to excluding guest samples"); ++ evsel->core.attr.exclude_guest = 1; ++ ++ return true; ++ } ++no_fallback: ++ scnprintf(msg, msgsize, "No fallback found for '%s' for error %d", ++ evsel__name(evsel), err); + return false; + } + +@@ -3131,6 +3154,8 @@ bool evsel__is_hybrid(const struct evsel *evsel) + + struct evsel *evsel__leader(const struct evsel *evsel) + { ++ if (evsel->core.leader == NULL) ++ return NULL; + return container_of(evsel->core.leader, struct evsel, core); + } + +diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c +index af9a97612f9df3..f61574d1581e3c 100644 +--- a/tools/perf/util/lzma.c ++++ b/tools/perf/util/lzma.c +@@ -113,7 +113,7 @@ bool lzma_is_compressed(const char *input) + ssize_t rc; + + if (fd < 0) +- return -1; ++ return false; + + rc = read(fd, buf, sizeof(buf)); + close(fd); +diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c +index 277b2cbd518611..e4d57e7df7ae10 100644 +--- a/tools/perf/util/session.c ++++ b/tools/perf/util/session.c +@@ -1662,7 +1662,7 @@ static s64 perf_session__process_user_event(struct perf_session *session, + struct perf_tool *tool = session->tool; + struct perf_sample sample = { .time = 0, }; + int fd = perf_data__fd(session->data); +- int err; ++ s64 err; + + if (event->header.type != PERF_RECORD_COMPRESSED || + tool->compressed == perf_session__process_compressed_event_stub) +diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py +index e837132d5031bd..eecb462c021cd9 100644 +--- a/tools/perf/util/setup.py ++++ b/tools/perf/util/setup.py +@@ -1,6 +1,7 @@ + from os import getenv, path + from subprocess import Popen, PIPE + from re import sub ++import shlex + + cc = getenv("CC") + +@@ -16,7 +17,9 @@ cc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline + src_feature_tests = getenv('srctree') + '/tools/build/feature' + + def clang_has_option(option): +- cc_output = Popen([cc, cc_options + option, path.join(src_feature_tests, "test-hello.c") ], stderr=PIPE).stderr.readlines() ++ cmd = shlex.split(f"{cc} {cc_options} {option}") ++ cmd.append(path.join(src_feature_tests, "test-hello.c")) ++ cc_output = Popen(cmd, stderr=PIPE).stderr.readlines() + return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o) or (b"unknown warning option" in o))] == [ ] + + if cc_is_clang: +diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c +index 78d2297c1b6746..1f7c065230599d 100644 +--- a/tools/perf/util/zlib.c ++++ b/tools/perf/util/zlib.c +@@ -88,7 +88,7 @@ bool gzip_is_compressed(const char *input) + ssize_t rc; + + if (fd < 0) +- return -1; ++ return false; + + rc = read(fd, buf, sizeof(buf)); + close(fd); +diff --git a/tools/testing/selftests/mm/madv_populate.c b/tools/testing/selftests/mm/madv_populate.c +index 17bcb07f19f349..7278623acf8c54 100644 +--- a/tools/testing/selftests/mm/madv_populate.c ++++ b/tools/testing/selftests/mm/madv_populate.c +@@ -264,23 +264,6 @@ static void test_softdirty(void) + munmap(addr, SIZE); + } + +-static int system_has_softdirty(void) +-{ +- /* +- * There is no way to check if the kernel supports soft-dirty, other +- * than by writing to a page and seeing if the bit was set. But the +- * tests are intended to check that the bit gets set when it should, so +- * doing that check would turn a potentially legitimate fail into a +- * skip. Fortunately, we know for sure that arm64 does not support +- * soft-dirty. So for now, let's just use the arch as a corse guide. +- */ +-#if defined(__aarch64__) +- return 0; +-#else +- return 1; +-#endif +-} +- + int main(int argc, char **argv) + { + int nr_tests = 16; +@@ -288,7 +271,7 @@ int main(int argc, char **argv) + + pagesize = getpagesize(); + +- if (system_has_softdirty()) ++ if (softdirty_supported()) + nr_tests += 5; + + ksft_print_header(); +@@ -300,7 +283,7 @@ int main(int argc, char **argv) + test_holes(); + test_populate_read(); + test_populate_write(); +- if (system_has_softdirty()) ++ if (softdirty_supported()) + test_softdirty(); + + err = ksft_get_fail_cnt(); +diff --git a/tools/testing/selftests/mm/soft-dirty.c b/tools/testing/selftests/mm/soft-dirty.c +index 7dbfa53d93a05f..7095b95d19ae2d 100644 +--- a/tools/testing/selftests/mm/soft-dirty.c ++++ b/tools/testing/selftests/mm/soft-dirty.c +@@ -193,8 +193,11 @@ int main(int argc, char **argv) + int pagesize; + + ksft_print_header(); +- ksft_set_plan(15); + ++ if (!softdirty_supported()) ++ ksft_exit_skip("soft-dirty is not support\n"); ++ ++ ksft_set_plan(15); + pagemap_fd = open(PAGEMAP_FILE_PATH, O_RDONLY); + if (pagemap_fd < 0) + ksft_exit_fail_msg("Failed to open %s\n", PAGEMAP_FILE_PATH); +diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c +index 558c9cd8901c5a..b2af70d75711aa 100644 +--- a/tools/testing/selftests/mm/vm_util.c ++++ b/tools/testing/selftests/mm/vm_util.c +@@ -97,6 +97,42 @@ uint64_t read_pmd_pagesize(void) + return strtoul(buf, NULL, 10); + } + ++char *__get_smap_entry(void *addr, const char *pattern, char *buf, size_t len) ++{ ++ int ret; ++ FILE *fp; ++ char *entry = NULL; ++ char addr_pattern[MAX_LINE_LENGTH]; ++ ++ ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "%08lx-", ++ (unsigned long)addr); ++ if (ret >= MAX_LINE_LENGTH) ++ ksft_exit_fail_msg("%s: Pattern is too long\n", __func__); ++ ++ fp = fopen(SMAP_FILE_PATH, "r"); ++ if (!fp) ++ ksft_exit_fail_msg("%s: Failed to open file %s\n", __func__, ++ SMAP_FILE_PATH); ++ ++ if (!check_for_pattern(fp, addr_pattern, buf, len)) ++ goto err_out; ++ ++ /* Fetch the pattern in the same block */ ++ if (!check_for_pattern(fp, pattern, buf, len)) ++ goto err_out; ++ ++ /* Trim trailing newline */ ++ entry = strchr(buf, '\n'); ++ if (entry) ++ *entry = '\0'; ++ ++ entry = buf + strlen(pattern); ++ ++err_out: ++ fclose(fp); ++ return entry; ++} ++ + bool __check_huge(void *addr, char *pattern, int nr_hpages, + uint64_t hpage_size) + { +@@ -269,3 +305,44 @@ int uffd_unregister(int uffd, void *addr, uint64_t len) + + return ret; + } ++ ++static bool check_vmflag(void *addr, const char *flag) ++{ ++ char buffer[MAX_LINE_LENGTH]; ++ const char *flags; ++ size_t flaglen; ++ ++ flags = __get_smap_entry(addr, "VmFlags:", buffer, sizeof(buffer)); ++ if (!flags) ++ ksft_exit_fail_msg("%s: No VmFlags for %p\n", __func__, addr); ++ ++ while (true) { ++ flags += strspn(flags, " "); ++ ++ flaglen = strcspn(flags, " "); ++ if (!flaglen) ++ return false; ++ ++ if (flaglen == strlen(flag) && !memcmp(flags, flag, flaglen)) ++ return true; ++ ++ flags += flaglen; ++ } ++} ++ ++bool softdirty_supported(void) ++{ ++ char *addr; ++ bool supported = false; ++ const size_t pagesize = getpagesize(); ++ ++ /* New mappings are expected to be marked with VM_SOFTDIRTY (sd). */ ++ addr = mmap(0, pagesize, PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); ++ if (!addr) ++ ksft_exit_fail_msg("mmap failed\n"); ++ ++ supported = check_vmflag(addr, "sd"); ++ munmap(addr, pagesize); ++ return supported; ++} +diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h +index 0c603bec5e209c..9816d6e9bce6c9 100644 +--- a/tools/testing/selftests/mm/vm_util.h ++++ b/tools/testing/selftests/mm/vm_util.h +@@ -51,6 +51,7 @@ int uffd_register(int uffd, void *addr, uint64_t len, + int uffd_unregister(int uffd, void *addr, uint64_t len); + int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len, + bool miss, bool wp, bool minor, uint64_t *ioctls); ++bool softdirty_supported(void); + + /* + * On ppc64 this will only work with radix 2M hugepage size +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index 442b7220468afc..9a907d8260c9c7 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -3234,6 +3234,17 @@ deny_join_id0_tests() + run_tests $ns1 $ns2 10.0.1.1 + chk_join_nr 1 1 1 + fi ++ ++ # default limits, server deny join id 0 + signal ++ if reset_with_allow_join_id0 "default limits, server deny join id 0" 0 1; then ++ pm_nl_set_limits $ns1 0 2 ++ pm_nl_set_limits $ns2 0 2 ++ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal ++ pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow ++ pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow ++ run_tests $ns1 $ns2 10.0.1.1 ++ chk_join_nr 2 2 2 ++ fi + } + + fullmesh_tests() +diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c +index f6156790c3b4df..05dc77fd527b3b 100644 +--- a/tools/testing/selftests/rseq/rseq.c ++++ b/tools/testing/selftests/rseq/rseq.c +@@ -40,9 +40,9 @@ + * Define weak versions to play nice with binaries that are statically linked + * against a libc that doesn't support registering its own rseq. + */ +-__weak ptrdiff_t __rseq_offset; +-__weak unsigned int __rseq_size; +-__weak unsigned int __rseq_flags; ++extern __weak ptrdiff_t __rseq_offset; ++extern __weak unsigned int __rseq_size; ++extern __weak unsigned int __rseq_flags; + + static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; + static const unsigned int *libc_rseq_size_p = &__rseq_size; +@@ -198,7 +198,7 @@ void rseq_init(void) + * libc not having registered a restartable sequence. Try to find the + * symbols if that's the case. + */ +- if (!*libc_rseq_size_p) { ++ if (!libc_rseq_size_p || !*libc_rseq_size_p) { + libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); + libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); + libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); diff --git a/patch/kernel/archive/qcs6490-6.16/0001-arm64-dts-qcom-qcs6490-audioreach-Add-gpr-node.patch b/patch/kernel/archive/qcs6490-6.16/0001-arm64-dts-qcom-qcs6490-audioreach-Add-gpr-node.patch deleted file mode 100644 index 18604998e..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0001-arm64-dts-qcom-qcs6490-audioreach-Add-gpr-node.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:07 +0530 -Subject: arm64: dts: qcom: qcs6490-audioreach: Add gpr node - -Add GPR(Generic Pack router) node along with -APM(Audio Process Manager) and PRM(Proxy resource -Manager) audio services. - -A new qcs6490-audioreach.dtsi file has been added to -update AudioReach specific device tree configurations. -The existing audio nodes in sc7280.dtsi, which were designed -for the ADSP Bypass solution. The audio nodes now being updated -in qcs6490-audioreach.dtsi to support the ADSP-based AudioReach -architecture. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla -Reviewed-by: Konrad Dybcio ---- - arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi | 54 ++++++++++ - arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +- - 2 files changed, 55 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi -@@ -0,0 +1,54 @@ -+// SPDX-License-Identifier: BSD-3-Clause -+/* -+ * qcs6490 device tree source for Audioreach Solution. -+ * This file will configure and manage nodes from sc7280.dtsi to -+ * support the AudioReach solution. -+ * -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+&remoteproc_adsp_glink { -+ /delete-node/ apr; -+ -+ gpr { -+ compatible = "qcom,gpr"; -+ qcom,glink-channels = "adsp_apps"; -+ qcom,domain = ; -+ qcom,intents = <512 20>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ q6apm: service@1 { -+ compatible = "qcom,q6apm"; -+ reg = ; -+ #sound-dai-cells = <0>; -+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; -+ -+ q6apmdai: dais { -+ compatible = "qcom,q6apm-dais"; -+ iommus = <&apps_smmu 0x1801 0x0>; -+ }; -+ -+ q6apmbedai: bedais { -+ compatible = "qcom,q6apm-lpass-dais"; -+ #sound-dai-cells = <1>; -+ }; -+ }; -+ -+ q6prm: service@2 { -+ compatible = "qcom,q6prm"; -+ reg = ; -+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; -+ -+ q6prmcc: clock-controller { -+ compatible = "qcom,q6prm-lpass-clocks"; -+ #clock-cells = <2>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -3814,7 +3814,7 @@ remoteproc_adsp: remoteproc@3700000 { - - status = "disabled"; - -- glink-edge { -+ remoteproc_adsp_glink: glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0002-dt-bindings-pinctrl-qcom-sc7280-lpass-lpi-pinctrl-Do.patch b/patch/kernel/archive/qcs6490-6.16/0002-dt-bindings-pinctrl-qcom-sc7280-lpass-lpi-pinctrl-Do.patch deleted file mode 100644 index 9b81147ff..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0002-dt-bindings-pinctrl-qcom-sc7280-lpass-lpi-pinctrl-Do.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:08 +0530 -Subject: dt-bindings: pinctrl: qcom,sc7280-lpass-lpi-pinctrl: Document the - clock property - -Document the clock property in sc7280 LPASS LPI pinctrl node. -Clock settings required for Audioreach solution. - -The existing SC7280 platform only supports non-ADSP audio solutions. -To enable audio functionality on ADSP with the AudioReach solution. -additional core and audio hardware clocks must be configured. -Without these clocks, the ADSP will crash. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla ---- - Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml | 16 ++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml -index 111111111111..222222222222 100644 ---- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml -+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml -@@ -20,6 +20,16 @@ properties: - reg: - maxItems: 2 - -+ clocks: -+ items: -+ - description: LPASS Core voting clock -+ - description: LPASS Audio voting clock -+ -+ clock-names: -+ items: -+ - const: core -+ - const: audio -+ - patternProperties: - "-state$": - oneOf: -@@ -70,10 +80,16 @@ unevaluatedProperties: false - - examples: - - | -+ #include - lpass_tlmm: pinctrl@33c0000 { - compatible = "qcom,sc7280-lpass-lpi-pinctrl"; - reg = <0x33c0000 0x20000>, - <0x3550000 0x10000>; -+ -+ clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, -+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; -+ clock-names = "core", "audio"; -+ - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&lpass_tlmm 0 0 15>; --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0003-arm64-dts-qcom-sc7280-Add-WSA-SoundWire-and-LPASS-su.patch b/patch/kernel/archive/qcs6490-6.16/0003-arm64-dts-qcom-sc7280-Add-WSA-SoundWire-and-LPASS-su.patch deleted file mode 100644 index 4ed6b15ba..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0003-arm64-dts-qcom-sc7280-Add-WSA-SoundWire-and-LPASS-su.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:10 +0530 -Subject: arm64: dts: qcom: sc7280: Add WSA SoundWire and LPASS support - -Add WSA LPASS macro Codec along with SoundWire controller. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla -Reviewed-by: Konrad Dybcio ---- - arch/arm64/boot/dts/qcom/sc7280.dtsi | 77 ++++++++++ - 1 file changed, 77 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - - / { -@@ -2636,6 +2637,66 @@ swr1: soundwire@3230000 { - status = "disabled"; - }; - -+ lpass_wsa_macro: codec@3240000 { -+ compatible = "qcom,sc7280-lpass-wsa-macro"; -+ reg = <0x0 0x03240000 0x0 0x1000>; -+ -+ clocks = <&lpass_aon LPASS_AON_CC_TX_MCLK_CLK>, -+ <&lpass_aon LPASS_AON_CC_TX_MCLK_2X_CLK>, -+ <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, -+ <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, -+ <&lpass_va_macro>; -+ clock-names = "mclk", -+ "npl", -+ "macro", -+ "dcodec", -+ "fsgen"; -+ -+ pinctrl-0 = <&lpass_wsa_swr_clk>, <&lpass_wsa_swr_data>; -+ pinctrl-names = "default"; -+ -+ #clock-cells = <0>; -+ clock-output-names = "mclk"; -+ #sound-dai-cells = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ swr2: soundwire@3250000 { -+ compatible = "qcom,soundwire-v1.6.0"; -+ reg = <0x0 0x03250000 0x0 0x2000>; -+ -+ interrupts = ; -+ clocks = <&lpass_wsa_macro>; -+ clock-names = "iface"; -+ -+ resets = <&lpass_audiocc LPASS_AUDIO_SWR_WSA_CGCR>; -+ reset-names = "swr_audio_cgcr"; -+ -+ qcom,din-ports = <2>; -+ qcom,dout-ports = <6>; -+ -+ qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1f 0x3f 0x07 -+ 0x1f 0x3f 0x0f 0x0f>; -+ qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0c 0x06 0x12 0x0d 0x07 0x0a>; -+ qcom,ports-offset2 = /bits/ 8 <0xff 0x00 0x1f 0xff 0x00 0x1f 0x00 0x00>; -+ qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; -+ qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; -+ qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; -+ qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0x01 0xff 0xff 0x01 -+ 0xff 0xff>; -+ qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff -+ 0xff 0xff>; -+ qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff -+ 0xff 0xff>; -+ -+ #address-cells = <2>; -+ #size-cells = <0>; -+ #sound-dai-cells = <1>; -+ -+ status = "disabled"; -+ }; -+ - lpass_audiocc: clock-controller@3300000 { - compatible = "qcom,sc7280-lpassaudiocc"; - reg = <0 0x03300000 0 0x30000>, -@@ -2839,6 +2900,22 @@ lpass_tx_swr_data: tx-swr-data-state { - pins = "gpio1", "gpio2", "gpio14"; - function = "swr_tx_data"; - }; -+ -+ lpass_wsa_swr_clk: wsa-swr-clk-state { -+ pins = "gpio10"; -+ function = "wsa_swr_clk"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-disable; -+ }; -+ -+ lpass_wsa_swr_data: wsa-swr-data-state { -+ pins = "gpio11"; -+ function = "wsa_swr_data"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-bus-hold; -+ }; - }; - - gpu: gpu@3d00000 { --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0005-arm64-dts-qcom-qcs6490-rb3gen2-Add-WSA8830-speakers-.patch b/patch/kernel/archive/qcs6490-6.16/0005-arm64-dts-qcom-qcs6490-rb3gen2-Add-WSA8830-speakers-.patch deleted file mode 100644 index 60cf55afe..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0005-arm64-dts-qcom-qcs6490-rb3gen2-Add-WSA8830-speakers-.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:12 +0530 -Subject: arm64: dts: qcom: qcs6490-rb3gen2: Add WSA8830 speakers amplifier - -Add nodes for WSA8830 speakers amplifier on qcs6490-rb3gen2 board. - -Enable lpass_wsa and lpass_va macros along with pinctrl settings -for audio. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla ---- - arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi | 6 ++ - arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 35 ++++++++++ - arch/arm64/boot/dts/qcom/sc7280.dtsi | 6 ++ - 3 files changed, 47 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi -+++ b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi -@@ -58,6 +58,12 @@ &lpass_va_macro { - clock-names = "mclk", - "macro", - "dcodec"; -+ -+ pinctrl-0 = <&lpass_dmic01_clk>, <&lpass_dmic01_data>, -+ <&lpass_dmic23_clk>, <&lpass_dmic23_data>; -+ pinctrl-names = "default"; -+ -+ qcom,dmic-sample-rate = <4800000>; - }; - - &lpass_wsa_macro { -diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -@@ -19,6 +19,7 @@ - #include "pm7325.dtsi" - #include "pm8350c.dtsi" - #include "pmk8350.dtsi" -+#include "qcs6490-audioreach.dtsi" - - /delete-node/ &ipa_fw_mem; - /delete-node/ &rmtfs_mem; -@@ -765,6 +766,14 @@ redriver_usb_con_sbu: endpoint { - }; - }; - -+&lpass_va_macro { -+ status = "okay"; -+}; -+ -+&lpass_wsa_macro { -+ status = "okay"; -+}; -+ - &mdss { - status = "okay"; - }; -@@ -1039,6 +1048,32 @@ &sdhc_2 { - status = "okay"; - }; - -+&swr2 { -+ status = "okay"; -+ -+ left_spkr: speaker@0,1 { -+ compatible = "sdw10217020200"; -+ reg = <0 1>; -+ reset-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>; -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "SpkrLeft"; -+ #thermal-sensor-cells = <0>; -+ vdd-supply = <&vreg_l18b_1p8>; -+ qcom,port-mapping = <1 2 3 7>; -+ }; -+ -+ right_spkr: speaker@0,2 { -+ compatible = "sdw10217020200"; -+ reg = <0 2>; -+ reset-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>; -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "SpkrRight"; -+ #thermal-sensor-cells = <0>; -+ vdd-supply = <&vreg_l18b_1p8>; -+ qcom,port-mapping = <4 5 6 8>; -+ }; -+}; -+ - &tlmm { - gpio-reserved-ranges = <32 2>, /* ADSP */ - <48 4>; /* NFC */ -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -2864,21 +2864,27 @@ lpass_tlmm: pinctrl@33c0000 { - lpass_dmic01_clk: dmic01-clk-state { - pins = "gpio6"; - function = "dmic1_clk"; -+ drive-strength = <8>; -+ bias-disable; - }; - - lpass_dmic01_data: dmic01-data-state { - pins = "gpio7"; - function = "dmic1_data"; -+ bias-pull-down; - }; - - lpass_dmic23_clk: dmic23-clk-state { - pins = "gpio8"; - function = "dmic2_clk"; -+ drive-strength = <8>; -+ bias-disable; - }; - - lpass_dmic23_data: dmic23-data-state { - pins = "gpio9"; - function = "dmic2_data"; -+ bias-pull-down; - }; - - lpass_rx_swr_clk: rx-swr-clk-state { --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0006-arm64-dts-qcom-qcs6490-rb3gen2-Add-sound-card.patch b/patch/kernel/archive/qcs6490-6.16/0006-arm64-dts-qcom-qcs6490-rb3gen2-Add-sound-card.patch deleted file mode 100644 index bc8f5a830..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0006-arm64-dts-qcom-qcs6490-rb3gen2-Add-sound-card.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:13 +0530 -Subject: arm64: dts: qcom: qcs6490-rb3gen2: Add sound card - -Add the sound card node with tested playback over WSA8835 speakers -and digital on-board mics. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla -Reviewed-by: Konrad Dybcio -Reviewed-by: Dmitry Baryshkov ---- - arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 45 ++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts -@@ -1048,6 +1048,51 @@ &sdhc_2 { - status = "okay"; - }; - -+&sound { -+ compatible = "qcom,qcs6490-rb3gen2-sndcard"; -+ model = "QCS6490-RB3Gen2"; -+ -+ audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", -+ "SpkrRight IN", "WSA_SPK2 OUT", -+ "VA DMIC0", "vdd-micb", -+ "VA DMIC1", "vdd-micb", -+ "VA DMIC2", "vdd-micb", -+ "VA DMIC3", "vdd-micb"; -+ -+ wsa-dai-link { -+ link-name = "WSA Playback"; -+ -+ codec { -+ sound-dai = <&left_spkr>, <&right_spkr>, -+ <&swr2 0>, <&lpass_wsa_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+ -+ va-dai-link { -+ link-name = "VA Capture"; -+ -+ codec { -+ sound-dai = <&lpass_va_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+}; -+ - &swr2 { - status = "okay"; - --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0007-arm64-dts-qcom-qcm6490-idp-Add-WSA8830-speakers-and-.patch b/patch/kernel/archive/qcs6490-6.16/0007-arm64-dts-qcom-qcm6490-idp-Add-WSA8830-speakers-and-.patch deleted file mode 100644 index 4ab930011..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0007-arm64-dts-qcom-qcm6490-idp-Add-WSA8830-speakers-and-.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:14 +0530 -Subject: arm64: dts: qcom: qcm6490-idp: Add WSA8830 speakers and WCD9370 - headset codec - -Add nodes for WSA8830 speakers and WCD9370 headset codec -on qcm6490-idp board. - -Enable lpass macros along with audio support pin controls. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla ---- - arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 123 ++++++++++ - arch/arm64/boot/dts/qcom/sc7280.dtsi | 12 + - 2 files changed, 135 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -@@ -18,6 +18,7 @@ - #include "pm7325.dtsi" - #include "pm8350c.dtsi" - #include "pmk8350.dtsi" -+#include "qcs6490-audioreach.dtsi" - - /delete-node/ &ipa_fw_mem; - /delete-node/ &rmtfs_mem; -@@ -169,6 +170,30 @@ vph_pwr: vph-pwr-regulator { - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - }; -+ -+ wcd9370: audio-codec-0 { -+ compatible = "qcom,wcd9370-codec"; -+ -+ pinctrl-0 = <&wcd_default>; -+ pinctrl-names = "default"; -+ -+ reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>; -+ -+ vdd-buck-supply = <&vreg_l17b_1p7>; -+ vdd-rxtx-supply = <&vreg_l18b_1p8>; -+ vdd-px-supply = <&vreg_l18b_1p8>; -+ vdd-mic-bias-supply = <&vreg_bob_3p296>; -+ -+ qcom,micbias1-microvolt = <1800000>; -+ qcom,micbias2-microvolt = <1800000>; -+ qcom,micbias3-microvolt = <1800000>; -+ qcom,micbias4-microvolt = <1800000>; -+ -+ qcom,rx-device = <&wcd937x_rx>; -+ qcom,tx-device = <&wcd937x_tx>; -+ -+ #sound-dai-cells = <1>; -+ }; - }; - - &apps_rsc { -@@ -536,6 +561,22 @@ &gpu_zap_shader { - firmware-name = "qcom/qcm6490/a660_zap.mbn"; - }; - -+&lpass_rx_macro { -+ status = "okay"; -+}; -+ -+&lpass_tx_macro { -+ status = "okay"; -+}; -+ -+&lpass_va_macro { -+ status = "okay"; -+}; -+ -+&lpass_wsa_macro { -+ status = "okay"; -+}; -+ - &mdss { - status = "okay"; - }; -@@ -716,6 +757,81 @@ &sdhc_2 { - cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>; - }; - -+&swr0 { -+ status = "okay"; -+ -+ wcd937x_rx: codec@0,4 { -+ compatible = "sdw20217010a00"; -+ reg = <0 4>; -+ -+ /* -+ * WCD9370 RX Port 1 (HPH_L/R) <==> SWR1 Port 1 (HPH_L/R) -+ * WCD9370 RX Port 2 (CLSH) <==> SWR1 Port 2 (CLSH) -+ * WCD9370 RX Port 3 (COMP_L/R) <==> SWR1 Port 3 (COMP_L/R) -+ * WCD9370 RX Port 4 (LO) <==> SWR1 Port 4 (LO) -+ * WCD9370 RX Port 5 (DSD_L/R) <==> SWR1 Port 5 (DSD) -+ */ -+ qcom,rx-port-mapping = <1 2 3 4 5>; -+ -+ /* -+ * Static channels mapping between slave and master rx port channels. -+ * In the order of slave port channels, which is -+ * hph_l, hph_r, clsh, comp_l, comp_r, lo, dsd_r, dsd_l. -+ */ -+ qcom,rx-channel-mapping = /bits/ 8 <1 2 1 1 2 1 1 2>; -+ }; -+}; -+ -+&swr1 { -+ status = "okay"; -+ -+ wcd937x_tx: codec@0,3 { -+ compatible = "sdw20217010a00"; -+ reg = <0 3>; -+ -+ /* -+ * WCD9370 TX Port 1 (ADC1) <=> SWR2 Port 2 -+ * WCD9370 TX Port 2 (ADC2, 3) <=> SWR2 Port 2 -+ * WCD9370 TX Port 3 (DMIC0,1,2,3 & MBHC) <=> SWR2 Port 3 -+ * WCD9370 TX Port 4 (DMIC4,5,6,7) <=> SWR2 Port 4 -+ */ -+ qcom,tx-port-mapping = <1 1 2 3>; -+ -+ /* -+ * Static channel mapping between slave and master tx port channels. -+ * In the order of slave port channels which is adc1, adc2, adc3, -+ * mic0, dmic1, mbhc, dmic2, dmic3, dmci4, dmic5, dmic6, dmic7. -+ */ -+ qcom,tx-channel-mapping = /bits/ 8 <1 2 1 1 2 3 3 4 1 2 3 4>; -+ }; -+}; -+ -+&swr2 { -+ status = "okay"; -+ -+ left_spkr: speaker@0,1 { -+ compatible = "sdw10217020200"; -+ reg = <0 1>; -+ powerdown-gpios = <&tlmm 63 GPIO_ACTIVE_LOW>; -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "SpkrLeft"; -+ #thermal-sensor-cells = <0>; -+ vdd-supply = <&vreg_l18b_1p8>; -+ qcom,port-mapping = <1 2 3 7>; -+ }; -+ -+ right_spkr: speaker@0,2 { -+ compatible = "sdw10217020200"; -+ reg = <0 2>; -+ powerdown-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "SpkrRight"; -+ #thermal-sensor-cells = <0>; -+ vdd-supply = <&vreg_l18b_1p8>; -+ qcom,port-mapping = <4 5 6 8>; -+ }; -+}; -+ - &tlmm { - gpio-reserved-ranges = <32 2>, /* ADSP */ - <48 4>; /* NFC */ -@@ -725,6 +841,13 @@ sd_cd: sd-cd-state { - function = "gpio"; - bias-pull-up; - }; -+ -+ wcd_default: wcd-reset-n-active-state { -+ pins = "gpio83"; -+ function = "gpio"; -+ drive-strength = <16>; -+ bias-disable; -+ }; - }; - - &uart5 { -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -2890,21 +2890,33 @@ lpass_dmic23_data: dmic23-data-state { - lpass_rx_swr_clk: rx-swr-clk-state { - pins = "gpio3"; - function = "swr_rx_clk"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-disable; - }; - - lpass_rx_swr_data: rx-swr-data-state { - pins = "gpio4", "gpio5"; - function = "swr_rx_data"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-bus-hold; - }; - - lpass_tx_swr_clk: tx-swr-clk-state { - pins = "gpio0"; - function = "swr_tx_clk"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-disable; - }; - - lpass_tx_swr_data: tx-swr-data-state { - pins = "gpio1", "gpio2", "gpio14"; - function = "swr_tx_data"; -+ drive-strength = <2>; -+ slew-rate = <1>; -+ bias-bus-hold; - }; - - lpass_wsa_swr_clk: wsa-swr-clk-state { --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0008-arm64-dts-qcom-qcm6490-idp-Add-sound-card.patch b/patch/kernel/archive/qcs6490-6.16/0008-arm64-dts-qcom-qcm6490-idp-Add-sound-card.patch deleted file mode 100644 index b0ad5acf8..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0008-arm64-dts-qcom-qcm6490-idp-Add-sound-card.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohammad Rafi Shaik -Date: Sun, 20 Jul 2025 23:02:15 +0530 -Subject: arm64: dts: qcom: qcm6490-idp: Add sound card - -Add the sound card node with tested playback over WSA8835 speakers, -digital on-board mics along with wcd9370 headset playabck and record. - -Signed-off-by: Mohammad Rafi Shaik -Co-developed-by: Prasad Kumpatla -Signed-off-by: Prasad Kumpatla -Reviewed-by: Konrad Dybcio ---- - arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 84 ++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts -@@ -757,6 +757,90 @@ &sdhc_2 { - cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>; - }; - -+&sound { -+ compatible = "qcom,qcm6490-idp-sndcard"; -+ model = "QCM6490-IDP"; -+ -+ audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", -+ "SpkrRight IN", "WSA_SPK2 OUT", -+ "IN1_HPHL", "HPHL_OUT", -+ "IN2_HPHR", "HPHR_OUT", -+ "AMIC2", "MIC BIAS2", -+ "TX DMIC0", "MIC BIAS1", -+ "TX DMIC1", "MIC BIAS2", -+ "TX DMIC2", "MIC BIAS3", -+ "TX SWR_ADC1", "ADC2_OUTPUT", -+ "VA DMIC0", "VA MIC BIAS3", -+ "VA DMIC1", "VA MIC BIAS3", -+ "VA DMIC2", "VA MIC BIAS1", -+ "VA DMIC3", "VA MIC BIAS1"; -+ -+ wsa-dai-link { -+ link-name = "WSA Playback"; -+ -+ codec { -+ sound-dai = <&left_spkr>, <&right_spkr>, -+ <&swr2 0>, <&lpass_wsa_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+ -+ wcd-playback-dai-link { -+ link-name = "WCD Playback"; -+ -+ codec { -+ sound-dai = <&wcd9370 0>, <&swr0 0>, <&lpass_rx_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+ -+ wcd-capture-dai-link { -+ link-name = "WCD Capture"; -+ -+ codec { -+ sound-dai = <&wcd9370 1>, <&swr1 0>, <&lpass_tx_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+ -+ va-dai-link { -+ link-name = "VA Capture"; -+ -+ codec { -+ sound-dai = <&lpass_va_macro 0>; -+ }; -+ -+ cpu { -+ sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; -+ }; -+ -+ platform { -+ sound-dai = <&q6apm>; -+ }; -+ }; -+}; -+ - &swr0 { - status = "okay"; - --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0009-arm64-qcom-sc7280-Add-PCIe0-controller.patch b/patch/kernel/archive/qcs6490-6.16/0009-arm64-qcom-sc7280-Add-PCIe0-controller.patch deleted file mode 100644 index d20256cc0..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0009-arm64-qcom-sc7280-Add-PCIe0-controller.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xilin Wu -Date: Fri, 23 May 2025 21:10:39 +0800 -Subject: arm64: qcom: sc7280: Add PCIe0 controller - -Signed-off-by: Xilin Wu ---- - arch/arm64/boot/dts/qcom/sc7280.dtsi | 128 +++++++++- - 1 file changed, 127 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -971,7 +971,7 @@ gcc: clock-controller@100000 { - reg = <0 0x00100000 0 0x1f0000>; - clocks = <&rpmhcc RPMH_CXO_CLK>, - <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, -- <0>, <&pcie1_phy>, -+ <&pcie0_phy>, <&pcie1_phy>, - <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, - <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; - clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", -@@ -2201,6 +2201,127 @@ wifi: wifi@17a10040 { - qcom,smem-state-names = "wlan-smp2p-out"; - }; - -+ pcie0: pcie@1c00000 { -+ compatible = "qcom,pcie-sc7280"; -+ reg = <0 0x01c00000 0 0x3000>, -+ <0 0x60000000 0 0xf1d>, -+ <0 0x60000f20 0 0xa8>, -+ <0 0x60001000 0 0x1000>, -+ <0 0x60100000 0 0x100000>; -+ -+ reg-names = "parf", "dbi", "elbi", "atu", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <0>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>, -+ <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>; -+ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>; -+ -+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>, -+ <&gcc GCC_PCIE_0_PIPE_CLK_SRC>, -+ <&pcie0_phy>, -+ <&rpmhcc RPMH_CXO_CLK>, -+ <&gcc GCC_PCIE_0_AUX_CLK>, -+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>, -+ <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, -+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>, -+ <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>, -+ <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>, -+ <&gcc GCC_DDRSS_PCIE_SF_CLK>, -+ <&gcc GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK>, -+ <&gcc GCC_AGGRE_NOC_PCIE_0_AXI_CLK>; -+ -+ clock-names = "pipe", -+ "pipe_mux", -+ "phy_pipe", -+ "ref", -+ "aux", -+ "cfg", -+ "bus_master", -+ "bus_slave", -+ "slave_q2a", -+ "tbu", -+ "ddrss_sf_tbu", -+ "aggre0", -+ "aggre1"; -+ -+ assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>; -+ assigned-clock-rates = <19200000>; -+ -+ resets = <&gcc GCC_PCIE_0_BCR>; -+ reset-names = "pci"; -+ -+ power-domains = <&gcc GCC_PCIE_0_GDSC>; -+ -+ phys = <&pcie0_phy>; -+ phy-names = "pciephy"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie0_clkreq_n>; -+ -+ dma-coherent; -+ -+ interconnects = <&aggre1_noc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>, -+ <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_PCIE_0 0>; -+ interconnect-names = "pcie-mem", "cpu-pcie"; -+ -+ iommu-map = <0x0 &apps_smmu 0x1c00 0x1>, -+ <0x100 &apps_smmu 0x1c01 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; -+ }; -+ }; -+ -+ pcie0_phy: phy@1c06000 { -+ compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy"; -+ reg = <0 0x01c06000 0 0x1c0>; -+ clocks = <&gcc GCC_PCIE_0_AUX_CLK>, -+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>, -+ <&gcc GCC_PCIE_CLKREF_EN>, -+ <&gcc GCC_PCIE0_PHY_RCHNG_CLK>, -+ <&gcc GCC_PCIE_0_PIPE_CLK>; -+ clock-names = "aux", -+ "cfg_ahb", -+ "ref", -+ "refgen", -+ "pipe"; -+ -+ clock-output-names = "pcie_0_pipe_clk"; -+ #clock-cells = <0>; -+ -+ #phy-cells = <0>; -+ -+ resets = <&gcc GCC_PCIE_0_PHY_BCR>; -+ reset-names = "phy"; -+ -+ assigned-clocks = <&gcc GCC_PCIE0_PHY_RCHNG_CLK>; -+ assigned-clock-rates = <100000000>; -+ -+ status = "disabled"; -+ }; -+ - pcie1: pcie@1c08000 { - compatible = "qcom,pcie-sc7280"; - reg = <0 0x01c08000 0 0x3000>, -@@ -5372,6 +5493,11 @@ mi2s1_ws: mi2s1-ws-state { - function = "mi2s1_ws"; - }; - -+ pcie0_clkreq_n: pcie0-clkreq-n-state { -+ pins = "gpio88"; -+ function = "pcie0_clkreqn"; -+ }; -+ - pcie1_clkreq_n: pcie1-clkreq-n-state { - pins = "gpio79"; - function = "pcie1_clkreqn"; --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0012-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch b/patch/kernel/archive/qcs6490-6.16/0012-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch deleted file mode 100644 index ce687393f..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0012-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch +++ /dev/null @@ -1,736 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Viken Dadhaniya -Date: Tue, 24 Jun 2025 15:20:59 +0530 -Subject: soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux - subsystem - -In Qualcomm SoCs, firmware loading for Serial Engines (SE) within the QUP -hardware has traditionally been managed by TrustZone (TZ). This restriction -poses a significant challenge for developers, as it limits their ability to -enable various protocols on any of the SEs from the Linux side, reducing -flexibility. - -Load the firmware to QUP SE based on the 'firmware-name' property specified -in devicetree at bootup time. - -Co-developed-by: Mukesh Kumar Savaliya -Signed-off-by: Mukesh Kumar Savaliya -Signed-off-by: Viken Dadhaniya ---- - drivers/soc/qcom/qcom-geni-se.c | 407 +++++++++- - include/linux/soc/qcom/geni-se.h | 32 +- - include/linux/soc/qcom/qup-fw-load.h | 93 +++ - 3 files changed, 510 insertions(+), 22 deletions(-) - -diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c -index 111111111111..222222222222 100644 ---- a/drivers/soc/qcom/qcom-geni-se.c -+++ b/drivers/soc/qcom/qcom-geni-se.c -@@ -1,11 +1,15 @@ - // SPDX-License-Identifier: GPL-2.0 --// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. -+/* -+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ - - /* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */ - #define __DISABLE_TRACE_MMIO__ - - #include - #include -+#include - #include - #include - #include -@@ -15,6 +19,7 @@ - #include - #include - #include -+#include - - /** - * DOC: Overview -@@ -80,9 +85,9 @@ - * common to all the serial engines and are independent of serial interfaces. - */ - --#define MAX_CLK_PERF_LEVEL 32 --#define MAX_CLKS 2 -- -+#define MAX_CLK_PERF_LEVEL 32 -+#define MAX_CLKS 2 -+#define MAX_PROTOCOL 6 - /** - * struct geni_wrapper - Data structure to represent the QUP Wrapper Core - * @dev: Device pointer of the QUP wrapper core -@@ -110,28 +115,23 @@ struct geni_se_desc { - static const char * const icc_path_names[] = {"qup-core", "qup-config", - "qup-memory"}; - -+static const char * const protocol_name[MAX_PROTOCOL] = { "None", "SPI", "UART", -+ "I2C", "I3C", "SPI SLAVE"}; -+ - #define QUP_HW_VER_REG 0x4 - - /* Common SE registers */ --#define GENI_INIT_CFG_REVISION 0x0 --#define GENI_S_INIT_CFG_REVISION 0x4 --#define GENI_OUTPUT_CTRL 0x24 --#define GENI_CGC_CTRL 0x28 - #define GENI_CLK_CTRL_RO 0x60 --#define GENI_FW_S_REVISION_RO 0x6c - #define SE_GENI_BYTE_GRAN 0x254 - #define SE_GENI_TX_PACKING_CFG0 0x260 - #define SE_GENI_TX_PACKING_CFG1 0x264 - #define SE_GENI_RX_PACKING_CFG0 0x284 - #define SE_GENI_RX_PACKING_CFG1 0x288 --#define SE_GENI_M_GP_LENGTH 0x910 --#define SE_GENI_S_GP_LENGTH 0x914 - #define SE_DMA_TX_PTR_L 0xc30 - #define SE_DMA_TX_PTR_H 0xc34 - #define SE_DMA_TX_ATTR 0xc38 - #define SE_DMA_TX_LEN 0xc3c - #define SE_DMA_TX_IRQ_EN 0xc48 --#define SE_DMA_TX_IRQ_EN_SET 0xc4c - #define SE_DMA_TX_IRQ_EN_CLR 0xc50 - #define SE_DMA_TX_LEN_IN 0xc54 - #define SE_DMA_TX_MAX_BURST 0xc5c -@@ -140,9 +140,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", - #define SE_DMA_RX_ATTR 0xd38 - #define SE_DMA_RX_LEN 0xd3c - #define SE_DMA_RX_IRQ_EN 0xd48 --#define SE_DMA_RX_IRQ_EN_SET 0xd4c - #define SE_DMA_RX_IRQ_EN_CLR 0xd50 --#define SE_DMA_RX_LEN_IN 0xd54 - #define SE_DMA_RX_MAX_BURST 0xd5c - #define SE_DMA_RX_FLUSH 0xd60 - #define SE_GSI_EVENT_EN 0xe18 -@@ -179,7 +177,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", - /* SE_DMA_GENERAL_CFG */ - #define DMA_RX_CLK_CGC_ON BIT(0) - #define DMA_TX_CLK_CGC_ON BIT(1) --#define DMA_AHB_SLV_CFG_ON BIT(2) -+#define DMA_AHB_SLV_CLK_CGC_ON BIT(2) - #define AHB_SEC_SLV_CLK_CGC_ON BIT(3) - #define DUMMY_RX_NON_BUFFERABLE BIT(4) - #define RX_DMA_ZERO_PADDING_EN BIT(5) -@@ -220,12 +218,12 @@ static void geni_se_io_init(void __iomem *base) - { - u32 val; - -- val = readl_relaxed(base + GENI_CGC_CTRL); -+ val = readl_relaxed(base + SE_GENI_CGC_CTRL); - val |= DEFAULT_CGC_EN; -- writel_relaxed(val, base + GENI_CGC_CTRL); -+ writel_relaxed(val, base + SE_GENI_CGC_CTRL); - - val = readl_relaxed(base + SE_DMA_GENERAL_CFG); -- val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON; -+ val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON; - val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; - writel_relaxed(val, base + SE_DMA_GENERAL_CFG); - -@@ -891,6 +889,379 @@ int geni_icc_disable(struct geni_se *se) - } - EXPORT_SYMBOL_GPL(geni_icc_disable); - -+/** -+ * geni_read_elf() - Read an ELF file. -+ * @se: Pointer to the SE resources structure. -+ * @fw: Pointer to the firmware buffer. -+ * @pelfseg: Pointer to the SE-specific ELF header. -+ * -+ * Read the ELF file and output a pointer to the header data, which -+ * contains the firmware data and any other details. -+ * -+ * Return: 0 if successful, otherwise return an error value. -+ */ -+static int geni_read_elf(struct geni_se *se, const struct firmware *fw, struct se_fw_hdr **pelfseg) -+{ -+ const struct elf32_hdr *ehdr; -+ struct elf32_phdr *phdrs, *phdr; -+ const struct se_fw_hdr *elfseg; -+ const u8 *addr; -+ int i; -+ -+ if (!fw || fw->size < sizeof(struct elf32_hdr)) -+ return -EINVAL; -+ -+ ehdr = (struct elf32_hdr *)fw->data; -+ phdrs = (struct elf32_phdr *)(ehdr + 1); -+ -+ if (ehdr->e_phnum < 2) -+ return -EINVAL; -+ -+ for (i = 0; i < ehdr->e_phnum; i++) { -+ phdr = &phdrs[i]; -+ -+ if (fw->size < phdr->p_offset + phdr->p_filesz) -+ return -EINVAL; -+ -+ if (phdr->p_type != PT_LOAD || !phdr->p_memsz) -+ continue; -+ -+ if (MI_PBT_PAGE_MODE_VALUE(phdr->p_flags) != MI_PBT_NON_PAGED_SEGMENT || -+ MI_PBT_SEGMENT_TYPE_VALUE(phdr->p_flags) == MI_PBT_HASH_SEGMENT || -+ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_NOTUSED_SEGMENT || -+ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_SHARED_SEGMENT) -+ continue; -+ -+ if (phdr->p_filesz < sizeof(struct se_fw_hdr)) -+ continue; -+ -+ addr = fw->data + phdr->p_offset; -+ elfseg = (const struct se_fw_hdr *)addr; -+ -+ if (cpu_to_le32(elfseg->magic) != MAGIC_NUM_SE || elfseg->version != 1) -+ continue; -+ -+ if (phdr->p_filesz < elfseg->fw_offset + -+ elfseg->fw_size_in_items * sizeof(u32) || -+ phdr->p_filesz < elfseg->cfg_idx_offset + -+ elfseg->cfg_size_in_items * sizeof(u8) || -+ phdr->p_filesz < elfseg->cfg_val_offset + -+ elfseg->cfg_size_in_items * sizeof(u32)) -+ continue; -+ -+ if (elfseg->serial_protocol != se->protocol) -+ continue; -+ -+ *pelfseg = (struct se_fw_hdr *)addr; -+ return 0; -+ } -+ return -EINVAL; -+} -+ -+/** -+ * geni_configure_xfer_mode() - Set the transfer mode. -+ * @se: Pointer to a structure representing SE-related resources. -+ * -+ * Set the transfer mode to either FIFO or DMA according to the mode specified by the protocol -+ * driver. -+ * -+ * Return: 0 if successful, otherwise return an error value. -+ */ -+static int geni_configure_xfer_mode(struct geni_se *se) -+{ -+ /* Configure SE FIFO, DMA or GSI mode. */ -+ switch (se->mode) { -+ case GENI_GPI_DMA: -+ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); -+ writel_relaxed(0x0, se->base + SE_IRQ_EN); -+ writel_relaxed(DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | -+ GENI_M_EVENT_EN | GENI_S_EVENT_EN, -+ se->base + SE_GSI_EVENT_EN); -+ break; -+ -+ case GENI_SE_FIFO: -+ geni_clrbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); -+ writel_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, -+ se->base + SE_IRQ_EN); -+ writel_relaxed(0x0, se->base + SE_GSI_EVENT_EN); -+ break; -+ -+ case GENI_SE_DMA: -+ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); -+ writel_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, -+ se->base + SE_IRQ_EN); -+ writel_relaxed(0x0, se->base + SE_GSI_EVENT_EN); -+ break; -+ -+ default: -+ dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", se->mode); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+/** -+ * geni_enable_interrupts() - Enable interrupts. -+ * @se: Pointer to a structure representing SE-related resources. -+ * -+ * Enable the required interrupts during the firmware load process. -+ * -+ */ -+static void geni_enable_interrupts(struct geni_se *se) -+{ -+ u32 reg_value; -+ -+ /* Enable required interrupts. */ -+ writel_relaxed(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN); -+ -+ reg_value = S_CMD_OVERRUN_EN | S_ILLEGAL_CMD_EN | -+ S_CMD_CANCEL_EN | S_CMD_ABORT_EN | -+ S_GP_IRQ_0_EN | S_GP_IRQ_1_EN | -+ S_GP_IRQ_2_EN | S_GP_IRQ_3_EN | -+ S_RX_FIFO_WR_ERR_EN | S_RX_FIFO_RD_ERR_EN; -+ writel_relaxed(reg_value, se->base + SE_GENI_S_IRQ_ENABLE); -+ -+ /* DMA mode configuration. */ -+ reg_value = RESET_DONE_EN | SBE_EN | DMA_DONE_EN; -+ writel_relaxed(reg_value, se->base + SE_DMA_TX_IRQ_EN_SET); -+ reg_value = FLUSH_DONE_EN | RESET_DONE_EN | SBE_EN | DMA_DONE_EN; -+ writel_relaxed(reg_value, se->base + SE_DMA_RX_IRQ_EN_SET); -+} -+ -+/** -+ * geni_write_fw_revision() - Write the firmware revision. -+ * @se: Pointer to a structure representing SE-related resources. -+ * @serial_protocol: serial protocol type. -+ * @fw_version: QUP firmware version. -+ * -+ * Write the firmware revision and protocol into the respective register. -+ * -+ * Return: None. -+ */ -+static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version) -+{ -+ u32 reg_value; -+ -+ reg_value = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol); -+ reg_value |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version); -+ -+ writel_relaxed(reg_value, se->base + SE_GENI_FW_REVISION); -+ writel_relaxed(reg_value, se->base + SE_S_FW_REVISION); -+} -+ -+/** -+ * geni_load_se_fw() - Load Serial Engine specific firmware. -+ * @se: Pointer to a structure representing SE-related resources. -+ * @fw: Pointer to the firmware structure. -+ * -+ * Load the protocol firmware into the IRAM of the Serial Engine. -+ * -+ * Return: 0 if successful, otherwise return an error value. -+ */ -+static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw) -+{ -+ const u32 *fw_data, *cfg_val_arr; -+ const u8 *cfg_idx_arr; -+ u32 i, reg_value, ramn_cnt; -+ int ret; -+ struct se_fw_hdr *hdr; -+ -+ ret = geni_read_elf(se, fw, &hdr); -+ if (ret) { -+ dev_err(se->dev, "ELF parsing failed ret: %d\n", ret); -+ return ret; -+ } -+ -+ ramn_cnt = hdr->fw_size_in_items; -+ if (hdr->fw_size_in_items % 2 != 0) -+ ramn_cnt++; -+ -+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) -+ return -EINVAL; -+ -+ ret = geni_icc_set_bw(se); -+ if (ret) -+ return ret; -+ -+ ret = geni_icc_enable(se); -+ if (ret) -+ return ret; -+ -+ ret = geni_se_resources_on(se); -+ if (ret) -+ goto err; -+ -+ ramn_cnt = hdr->fw_size_in_items; -+ if (hdr->fw_size_in_items % 2 != 0) -+ ramn_cnt++; -+ -+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) -+ goto err_resource; -+ -+ fw_data = (const u32 *)((u8 *)hdr + hdr->fw_offset); -+ cfg_idx_arr = (const u8 *)hdr + hdr->cfg_idx_offset; -+ cfg_val_arr = (const u32 *)((u8 *)hdr + hdr->cfg_val_offset); -+ -+ /* Disable high priority interrupt until current low priority interrupts are handled. */ -+ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE); -+ -+ /* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */ -+ geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON); -+ -+ /* Let hardware to control common cgc. */ -+ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON); -+ -+ /* Allows to drive corresponding data according to hardware value. */ -+ writel_relaxed(0x0, se->base + GENI_OUTPUT_CTRL); -+ -+ /* Set SCLK and HCLK to program RAM */ -+ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); -+ writel_relaxed(0x0, se->base + SE_GENI_CLK_CTRL); -+ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); -+ -+ /* Enable required clocks for DMA CSR, TX and RX. */ -+ reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON | -+ DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; -+ geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value); -+ -+ /* Let hardware control CGC by default. */ -+ writel_relaxed(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL); -+ -+ /* Set version of the configuration register part of firmware. */ -+ writel_relaxed(hdr->cfg_version, se->base + SE_GENI_INIT_CFG_REVISION); -+ writel_relaxed(hdr->cfg_version, se->base + SE_GENI_S_INIT_CFG_REVISION); -+ -+ /* Configure GENI primitive table. */ -+ for (i = 0; i < hdr->cfg_size_in_items; i++) -+ writel_relaxed(cfg_val_arr[i], -+ se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32))); -+ -+ /* Configure condition for assertion of RX_RFR_WATERMARK condition. */ -+ reg_value = geni_se_get_rx_fifo_depth(se); -+ writel_relaxed(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG); -+ -+ /* Let hardware control CGC */ -+ geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK); -+ -+ ret = geni_configure_xfer_mode(se); -+ if (ret) -+ goto err_resource; -+ -+ geni_enable_interrupts(se); -+ -+ geni_write_fw_revision(se, hdr->serial_protocol, hdr->fw_version); -+ -+ ramn_cnt = hdr->fw_size_in_items; -+ if (hdr->fw_size_in_items % 2 != 0) -+ ramn_cnt++; -+ -+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) -+ goto err_resource; -+ -+ /* Program RAM address space. */ -+ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, ramn_cnt * sizeof(u32)); -+ -+ /* Put default values on GENI's output pads. */ -+ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG); -+ -+ /* High to low SCLK and HCLK to finish RAM. */ -+ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); -+ geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL); -+ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); -+ -+ /* Serial engine DMA interface is enabled. */ -+ geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN); -+ -+ /* Enable or disable FIFO interface of the serial engine. */ -+ if (se->mode == GENI_SE_FIFO) -+ geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); -+ else -+ geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); -+ -+err_resource: -+ geni_se_resources_off(se); -+err: -+ geni_icc_disable(se); -+ return ret; -+} -+ -+/** -+ * qup_fw_load() - Initiate firmware load. -+ * @se: Pointer to a structure representing SE-related resources. -+ * @fw_name: Name of the firmware. -+ * -+ * Load the firmware into a specific SE. Read the associated ELF file, -+ * copy the data into a buffer in kernel space using the request_firmware API, write the -+ * data into the SE's IRAM register, and then free the buffers. Handle firmware loading -+ * and parsing for a specific protocol. -+ * -+ * Return: 0 if successful, otherwise return an error value. -+ */ -+static int qup_fw_load(struct geni_se *se, const char *fw_name) -+{ -+ int ret; -+ const struct firmware *fw; -+ struct device *dev = se->dev; -+ -+ ret = request_firmware(&fw, fw_name, dev); -+ if (ret) { -+ dev_err(dev, "request_firmware failed for %d: %d\n", se->protocol, ret); -+ return ret; -+ } -+ -+ ret = geni_load_se_fw(se, fw); -+ -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+/** -+ * geni_load_se_firmware() - Initiate firmware loading. -+ * @se: Serial engine details. -+ * @protocol: Protocol (SPI, I2C, or UART) for which the firmware is to be loaded. -+ * -+ * If the device tree properties are configured to load QUP firmware and the firmware -+ * is not already loaded, start the firmware loading process. If the device tree properties -+ * are not defined, skip loading the firmware, assuming it is already loaded by TZ. -+ * -+ * Return: 0 if successful, otherwise return an error value. -+ */ -+int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol) -+{ -+ const char *fw_name; -+ int ret; -+ -+ if (protocol >= MAX_PROTOCOL) { -+ dev_err(se->dev, "Invalid geni-se protocol: %d", protocol); -+ return -EINVAL; -+ } -+ -+ ret = device_property_read_string(se->wrapper->dev, "firmware-name", &fw_name); -+ if (ret) -+ return -EINVAL; -+ -+ se->protocol = protocol; -+ -+ if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma")) -+ se->mode = GENI_GPI_DMA; -+ else -+ se->mode = GENI_SE_FIFO; -+ -+ /* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */ -+ if (protocol == GENI_SE_UART) -+ se->mode = GENI_SE_FIFO; -+ -+ ret = qup_fw_load(se, fw_name); -+ if (ret) -+ return ret; -+ -+ dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode %d\n", -+ protocol_name[se->protocol], se->mode); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(geni_load_se_firmware); -+ - static int geni_se_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h -index 111111111111..222222222222 100644 ---- a/include/linux/soc/qcom/geni-se.h -+++ b/include/linux/soc/qcom/geni-se.h -@@ -1,11 +1,13 @@ - /* SPDX-License-Identifier: GPL-2.0 */ - /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. - */ - - #ifndef _LINUX_QCOM_GENI_SE - #define _LINUX_QCOM_GENI_SE - -+#include - #include - - /** -@@ -36,6 +38,7 @@ enum geni_se_protocol_type { - GENI_SE_I2C, - GENI_SE_I3C, - GENI_SE_SPI_SLAVE, -+ GENI_SE_INVALID_PROTO = 255, - }; - - struct geni_wrapper; -@@ -61,6 +64,8 @@ struct geni_icc_path { - * @num_clk_levels: Number of valid clock levels in clk_perf_tbl - * @clk_perf_tbl: Table of clock frequency input to serial engine clock - * @icc_paths: Array of ICC paths for SE -+ * @mode: Transfer mode se fifo, dma or gsi. -+ * @protocol: Protocol spi or i2c or serial. - */ - struct geni_se { - void __iomem *base; -@@ -70,24 +75,32 @@ struct geni_se { - unsigned int num_clk_levels; - unsigned long *clk_perf_tbl; - struct geni_icc_path icc_paths[3]; -+ enum geni_se_xfer_mode mode; -+ enum geni_se_protocol_type protocol; - }; - - /* Common SE registers */ -+#define SE_GENI_INIT_CFG_REVISION 0x0 -+#define SE_GENI_S_INIT_CFG_REVISION 0x4 - #define GENI_FORCE_DEFAULT_REG 0x20 - #define GENI_OUTPUT_CTRL 0x24 -+#define SE_GENI_CGC_CTRL 0x28 - #define SE_GENI_STATUS 0x40 - #define GENI_SER_M_CLK_CFG 0x48 - #define GENI_SER_S_CLK_CFG 0x4c - #define GENI_IF_DISABLE_RO 0x64 --#define GENI_FW_REVISION_RO 0x68 -+#define SE_GENI_FW_REVISION_RO 0x68 -+#define SE_GENI_S_FW_REVISION_RO 0x6c - #define SE_GENI_CLK_SEL 0x7c - #define SE_GENI_CFG_SEQ_START 0x84 -+#define SE_GENI_CFG_REG0 0x100 - #define SE_GENI_DMA_MODE_EN 0x258 - #define SE_GENI_M_CMD0 0x600 - #define SE_GENI_M_CMD_CTRL_REG 0x604 - #define SE_GENI_M_IRQ_STATUS 0x610 - #define SE_GENI_M_IRQ_EN 0x614 - #define SE_GENI_M_IRQ_CLEAR 0x618 -+#define SE_GENI_S_IRQ_ENABLE 0x644 - #define SE_GENI_M_IRQ_EN_SET 0x61c - #define SE_GENI_M_IRQ_EN_CLEAR 0x620 - #define SE_GENI_S_CMD0 0x630 -@@ -109,13 +122,22 @@ struct geni_se { - #define SE_GENI_S_GP_LENGTH 0x914 - #define SE_DMA_TX_IRQ_STAT 0xc40 - #define SE_DMA_TX_IRQ_CLR 0xc44 -+#define SE_DMA_TX_IRQ_EN_SET 0xc4c - #define SE_DMA_TX_FSM_RST 0xc58 - #define SE_DMA_RX_IRQ_STAT 0xd40 - #define SE_DMA_RX_IRQ_CLR 0xd44 -+#define SE_DMA_RX_IRQ_EN_SET 0xd4c - #define SE_DMA_RX_LEN_IN 0xd54 - #define SE_DMA_RX_FSM_RST 0xd58 - #define SE_HW_PARAM_0 0xe24 - #define SE_HW_PARAM_1 0xe28 -+#define SE_DMA_GENERAL_CFG 0xe30 -+#define SE_GENI_FW_REVISION 0x1000 -+#define SE_S_FW_REVISION 0x1004 -+#define SE_GENI_CFG_RAMN 0x1010 -+#define SE_GENI_CLK_CTRL 0x2000 -+#define SE_DMA_IF_EN 0x2004 -+#define SE_FIFO_IF_DISABLE 0x2008 - - /* GENI_FORCE_DEFAULT_REG fields */ - #define FORCE_DEFAULT BIT(0) -@@ -137,7 +159,7 @@ struct geni_se { - - /* GENI_FW_REVISION_RO fields */ - #define FW_REV_PROTOCOL_MSK GENMASK(15, 8) --#define FW_REV_PROTOCOL_SHFT 8 -+#define FW_REV_VERSION_MSK GENMASK(7, 0) - - /* GENI_CLK_SEL fields */ - #define CLK_SEL_MSK GENMASK(2, 0) -@@ -325,9 +347,9 @@ static inline u32 geni_se_read_proto(struct geni_se *se) - { - u32 val; - -- val = readl_relaxed(se->base + GENI_FW_REVISION_RO); -+ val = readl_relaxed(se->base + SE_GENI_FW_REVISION_RO); - -- return (val & FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT; -+ return FIELD_GET(FW_REV_PROTOCOL_MSK, val); - } - - /** -@@ -531,5 +553,7 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag); - int geni_icc_enable(struct geni_se *se); - - int geni_icc_disable(struct geni_se *se); -+ -+int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol); - #endif - #endif -diff --git a/include/linux/soc/qcom/qup-fw-load.h b/include/linux/soc/qcom/qup-fw-load.h -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/include/linux/soc/qcom/qup-fw-load.h -@@ -0,0 +1,93 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+#ifndef _LINUX_QCOM_QUP_FW_LOAD -+#define _LINUX_QCOM_QUP_FW_LOAD -+ -+#include -+ -+/*Magic numbers*/ -+#define MAGIC_NUM_SE 0x57464553 -+ -+#define MAX_GENI_CFG_RAMn_CNT 455 -+ -+#define MI_PBT_NON_PAGED_SEGMENT 0x0 -+#define MI_PBT_HASH_SEGMENT 0x2 -+#define MI_PBT_NOTUSED_SEGMENT 0x3 -+#define MI_PBT_SHARED_SEGMENT 0x4 -+ -+#define MI_PBT_FLAG_PAGE_MODE BIT(20) -+#define MI_PBT_FLAG_SEGMENT_TYPE GENMASK(26, 24) -+#define MI_PBT_FLAG_ACCESS_TYPE GENMASK(23, 21) -+ -+#define MI_PBT_PAGE_MODE_VALUE(x) FIELD_GET(MI_PBT_FLAG_PAGE_MODE, x) -+ -+#define MI_PBT_SEGMENT_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_SEGMENT_TYPE, x) -+ -+#define MI_PBT_ACCESS_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_ACCESS_TYPE, x) -+ -+#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \ -+ M_IO_DATA_DEASSERT_EN | \ -+ M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \ -+ M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \ -+ M_TX_FIFO_WR_ERR_EN) -+ -+/* DMA_TX/RX_IRQ_EN fields */ -+#define DMA_DONE_EN BIT(0) -+#define SBE_EN BIT(2) -+#define RESET_DONE_EN BIT(3) -+#define FLUSH_DONE_EN BIT(4) -+ -+/* GENI_CLK_CTRL fields */ -+#define SER_CLK_SEL BIT(0) -+ -+/* GENI_DMA_IF_EN fields */ -+#define DMA_IF_EN BIT(0) -+ -+#define QUPV3_COMMON_CFG 0x120 -+#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0) -+ -+#define QUPV3_SE_AHB_M_CFG 0x118 -+#define AHB_M_CLK_CGC_ON BIT(0) -+ -+#define QUPV3_COMMON_CGC_CTRL 0x21C -+#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0) -+ -+/* access ports */ -+#define geni_setbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) | (_v), _addr) -+#define geni_clrbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) & ~(_v), _addr) -+ -+/** -+ * struct se_fw_hdr - Serial Engine firmware configuration header -+ * -+ * This structure defines metadata for the Serial Engine (SE) firmware -+ * configuration. Although it is embedded within an ELF segment, it is -+ * not part of the ELF format itself. -+ * -+ * @magic: Set to 'SEFW' -+ * @version: Structure version number -+ * @core_version: QUPV3 hardware version -+ * @serial_protocol: Encoded in GENI_FW_REVISION -+ * @fw_version: Firmware version, from GENI_FW_REVISION -+ * @cfg_version: Configuration version, from GENI_INIT_CFG_REVISION -+ * @fw_size_in_items: Number of 32-bit words in GENI_FW_RAM -+ * @fw_offset: Byte offset to GENI_FW_RAM array -+ * @cfg_size_in_items: Number of GENI_FW_CFG index/value pairs -+ * @cfg_idx_offset: Byte offset to GENI_FW_CFG index array -+ * @cfg_val_offset: Byte offset to GENI_FW_CFG values array -+ */ -+struct se_fw_hdr { -+ __le32 magic; -+ u32 version; -+ u32 core_version; -+ u16 serial_protocol; -+ u16 fw_version; -+ u16 cfg_version; -+ u16 fw_size_in_items; -+ u16 fw_offset; -+ u16 cfg_size_in_items; -+ u16 cfg_idx_offset; -+ u16 cfg_val_offset; -+}; -+#endif /* _LINUX_QCOM_QUP_FW_LOAD */ --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0017-dt-bindings-display-simple-bridge-Add-ra620-compatib.patch b/patch/kernel/archive/qcs6490-6.16/0017-dt-bindings-display-simple-bridge-Add-ra620-compatib.patch deleted file mode 100644 index b250b9782..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0017-dt-bindings-display-simple-bridge-Add-ra620-compatib.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andy Yan -Date: Thu, 3 Apr 2025 11:37:32 +0800 -Subject: dt-bindings: display: simple-bridge: Add ra620 compatible - -RA620 is a DP to HDMI bridge converter from RADXA, which first -found be used on ROCK 5 ITX. - -This chip can be used without involving software. - -Signed-off-by: Andy Yan - -Acked-by: Krzysztof Kozlowski ---- - Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml -index 111111111111..222222222222 100644 ---- a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml -+++ b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml -@@ -28,6 +28,7 @@ properties: - - enum: - - adi,adv7123 - - dumb-vga-dac -+ - radxa,ra620 - - ti,opa362 - - ti,ths8134 - - ti,ths8135 --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0025-soc-qcom-qcom_stats-Add-support-to-read-DDR-statisti.patch b/patch/kernel/archive/qcs6490-6.16/0025-soc-qcom-qcom_stats-Add-support-to-read-DDR-statisti.patch deleted file mode 100644 index ad8017dd2..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0025-soc-qcom-qcom_stats-Add-support-to-read-DDR-statisti.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Maulik Shah -Date: Wed, 11 Jun 2025 11:33:45 +0530 -Subject: soc: qcom: qcom_stats: Add support to read DDR statistic - -DDR statistic provide different DDR LPM and DDR frequency statistic. -Add support to read from MSGRAM and display via debugfs. - -Reviewed-by: Konrad Dybcio -Reviewed-by: Dmitry Baryshkov -Signed-off-by: Maulik Shah ---- - drivers/soc/qcom/qcom_stats.c | 99 ++++++++++ - 1 file changed, 99 insertions(+) - -diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c -index 111111111111..222222222222 100644 ---- a/drivers/soc/qcom/qcom_stats.c -+++ b/drivers/soc/qcom/qcom_stats.c -@@ -1,8 +1,10 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* - * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include - #include - #include -@@ -24,6 +26,17 @@ - #define ACCUMULATED_OFFSET 0x18 - #define CLIENT_VOTES_OFFSET 0x20 - -+#define DDR_STATS_MAGIC_KEY 0xA1157A75 -+#define DDR_STATS_MAX_NUM_MODES 20 -+#define DDR_STATS_MAGIC_KEY_ADDR 0x0 -+#define DDR_STATS_NUM_MODES_ADDR 0x4 -+#define DDR_STATS_ENTRY_START_ADDR 0x8 -+ -+#define DDR_STATS_CP_IDX(data) FIELD_GET(GENMASK(4, 0), data) -+#define DDR_STATS_LPM_NAME(data) FIELD_GET(GENMASK(7, 0), data) -+#define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data) -+#define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data) -+ - struct subsystem_data { - const char *name; - u32 smem_item; -@@ -48,12 +61,19 @@ static const struct subsystem_data subsystems[] = { - - struct stats_config { - size_t stats_offset; -+ size_t ddr_stats_offset; - size_t num_records; - bool appended_stats_avail; - bool dynamic_offset; - bool subsystem_stats_in_smem; - }; - -+struct ddr_stats_entry { -+ u32 name; -+ u32 count; -+ u64 duration; -+}; -+ - struct stats_data { - bool appended_stats_avail; - void __iomem *base; -@@ -122,8 +142,85 @@ static int qcom_soc_sleep_stats_show(struct seq_file *s, void *unused) - return 0; - } - -+static void qcom_ddr_stats_print(struct seq_file *s, struct ddr_stats_entry *data) -+{ -+ u32 cp_idx; -+ -+ /* -+ * DDR statistic have two different types of details encoded. -+ * (1) DDR LPM Stats -+ * (2) DDR Frequency Stats -+ * -+ * The name field have details like which type of DDR stat (bits 8:15) -+ * along with other details as explained below -+ * -+ * In case of DDR LPM stat, name field will be encoded as, -+ * Bits - Meaning -+ * 0:7 - DDR LPM name, can be of 0xd4, 0xd3, 0x11 and 0xd0. -+ * 8:15 - 0x0 (indicates its a LPM stat) -+ * 16:31 - Unused -+ * -+ * In case of DDR FREQ stats, name field will be encoded as, -+ * Bits - Meaning -+ * 0:4 - DDR Clock plan index (CP IDX) -+ * 5:7 - Unused -+ * 8:15 - 0x1 (indicates its Freq stat) -+ * 16:31 - Frequency value in Mhz -+ */ -+ switch (DDR_STATS_TYPE(data->name)) { -+ case 0: -+ seq_printf(s, "DDR LPM Stat Name:0x%lx\tcount:%u\tDuration (ticks):%llu\n", -+ DDR_STATS_LPM_NAME(data->name), data->count, data->duration); -+ break; -+ case 1: -+ if (!data->count || !DDR_STATS_FREQ(data->name)) -+ return; -+ -+ cp_idx = DDR_STATS_CP_IDX(data->name); -+ seq_printf(s, "DDR Freq %luMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n", -+ DDR_STATS_FREQ(data->name), cp_idx, data->count, data->duration); -+ break; -+ } -+} -+ -+static int qcom_ddr_stats_show(struct seq_file *s, void *d) -+{ -+ struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES]; -+ void __iomem *reg = (void __iomem *)s->private; -+ u32 entry_count; -+ int i; -+ -+ entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR); -+ if (entry_count > DDR_STATS_MAX_NUM_MODES) -+ return -EINVAL; -+ -+ reg += DDR_STATS_ENTRY_START_ADDR; -+ memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count); -+ -+ for (i = 0; i < entry_count; i++) -+ qcom_ddr_stats_print(s, &data[i]); -+ -+ return 0; -+} -+ - DEFINE_SHOW_ATTRIBUTE(qcom_soc_sleep_stats); - DEFINE_SHOW_ATTRIBUTE(qcom_subsystem_sleep_stats); -+DEFINE_SHOW_ATTRIBUTE(qcom_ddr_stats); -+ -+static void qcom_create_ddr_stat_files(struct dentry *root, void __iomem *reg, -+ const struct stats_config *config) -+{ -+ u32 key; -+ -+ if (!config->ddr_stats_offset) -+ return; -+ -+ key = readl_relaxed(reg + config->ddr_stats_offset + DDR_STATS_MAGIC_KEY_ADDR); -+ if (key == DDR_STATS_MAGIC_KEY) -+ debugfs_create_file("ddr_stats", 0400, root, -+ (__force void *)reg + config->ddr_stats_offset, -+ &qcom_ddr_stats_fops); -+} - - static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *reg, - struct stats_data *d, -@@ -212,6 +309,7 @@ static int qcom_stats_probe(struct platform_device *pdev) - - qcom_create_subsystem_stat_files(root, config); - qcom_create_soc_sleep_stat_files(root, reg, d, config); -+ qcom_create_ddr_stat_files(root, reg, config); - - platform_set_drvdata(pdev, root); - -@@ -254,6 +352,7 @@ static const struct stats_config rpmh_data_sdm845 = { - - static const struct stats_config rpmh_data = { - .stats_offset = 0x48, -+ .ddr_stats_offset = 0xb8, - .num_records = 3, - .appended_stats_avail = false, - .dynamic_offset = false, --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0026-soc-qcom-qcom_stats-Add-QMP-support-for-syncing-ddr-.patch b/patch/kernel/archive/qcs6490-6.16/0026-soc-qcom-qcom_stats-Add-QMP-support-for-syncing-ddr-.patch deleted file mode 100644 index 289b0450d..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0026-soc-qcom-qcom_stats-Add-QMP-support-for-syncing-ddr-.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Maulik Shah -Date: Wed, 11 Jun 2025 11:33:46 +0530 -Subject: soc: qcom: qcom_stats: Add QMP support for syncing ddr stats - -Recent SoCs (SM8450 onwards) require QMP command to be sent before reading -ddr stats. The duration field of ddr stats will get populated only if QMP -command is sent. - -Add support to send ddr stats freqsync QMP command. - -Signed-off-by: Maulik Shah -Reviewed-by: Dmitry Baryshkov ---- - drivers/soc/qcom/qcom_stats.c | 36 +++++++++- - 1 file changed, 35 insertions(+), 1 deletion(-) - -diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c -index 111111111111..222222222222 100644 ---- a/drivers/soc/qcom/qcom_stats.c -+++ b/drivers/soc/qcom/qcom_stats.c -@@ -13,6 +13,7 @@ - #include - #include - -+#include - #include - #include - -@@ -37,6 +38,8 @@ - #define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data) - #define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data) - -+static struct qmp *qcom_stats_qmp; -+ - struct subsystem_data { - const char *name; - u32 smem_item; -@@ -188,12 +191,28 @@ static int qcom_ddr_stats_show(struct seq_file *s, void *d) - struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES]; - void __iomem *reg = (void __iomem *)s->private; - u32 entry_count; -- int i; -+ int i, ret; - - entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR); - if (entry_count > DDR_STATS_MAX_NUM_MODES) - return -EINVAL; - -+ if (qcom_stats_qmp) { -+ /* -+ * Recent SoCs (SM8450 onwards) do not have duration field -+ * populated from boot up onwards for both DDR LPM Stats -+ * and DDR Frequency Stats. -+ * -+ * Send QMP message to Always on processor which will -+ * populate duration field into MSG RAM area. -+ * -+ * Sent every time to read latest data. -+ */ -+ ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}"); -+ if (ret) -+ return ret; -+ } -+ - reg += DDR_STATS_ENTRY_START_ADDR; - memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count); - -@@ -304,6 +323,21 @@ static int qcom_stats_probe(struct platform_device *pdev) - - for (i = 0; i < config->num_records; i++) - d[i].appended_stats_avail = config->appended_stats_avail; -+ /* -+ * QMP is used for DDR stats syncing to MSG RAM for recent SoCs (SM8450 onwards). -+ * The prior SoCs do not need QMP handle as the required stats are already present -+ * in MSG RAM, provided the DDR_STATS_MAGIC_KEY matches. -+ */ -+ qcom_stats_qmp = qmp_get(&pdev->dev); -+ if (IS_ERR(qcom_stats_qmp)) { -+ /* We ignore error if QMP is not defined/needed */ -+ if (!of_property_present(pdev->dev.of_node, "qcom,qmp")) -+ qcom_stats_qmp = NULL; -+ else if (PTR_ERR(qcom_stats_qmp) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ else -+ return PTR_ERR(qcom_stats_qmp); -+ } - - root = debugfs_create_dir("qcom_stats", NULL); - --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0027-arm64-dts-qcom-sc7280-Add-support-for-two-additional.patch b/patch/kernel/archive/qcs6490-6.16/0027-arm64-dts-qcom-sc7280-Add-support-for-two-additional.patch deleted file mode 100644 index fde57c658..000000000 --- a/patch/kernel/archive/qcs6490-6.16/0027-arm64-dts-qcom-sc7280-Add-support-for-two-additional.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Pushpendra Singh -Date: Wed, 2 Jul 2025 05:31:20 +0530 -Subject: arm64: dts: qcom: sc7280: Add support for two additional DDR - frequencies - -The SC7280 SoC now supports two additional frequencies. This patch -add those frequencies to the BWMON OPP table and updates the frequency -mapping table accordingly. - -These changes do not impact existing platforms, as the updated mapping -only affects the highest OPP. On any given platform, this will continue -to vote for the maximum available OPP. - -Signed-off-by: Pushpendra Singh -Reviewed-by: Dmitry Baryshkov ---- - arch/arm64/boot/dts/qcom/sc7280.dtsi | 18 ++++++---- - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -621,12 +621,12 @@ cpu4_opp_2208mhz: opp-2208000000 { - - cpu4_opp_2400mhz: opp-2400000000 { - opp-hz = /bits/ 64 <2400000000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - - cpu4_opp_2611mhz: opp-2611200000 { - opp-hz = /bits/ 64 <2611200000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - }; - -@@ -686,22 +686,22 @@ cpu7_opp_2381mhz: opp-2380800000 { - - cpu7_opp_2400mhz: opp-2400000000 { - opp-hz = /bits/ 64 <2400000000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - - cpu7_opp_2515mhz: opp-2515200000 { - opp-hz = /bits/ 64 <2515200000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - - cpu7_opp_2707mhz: opp-2707200000 { - opp-hz = /bits/ 64 <2707200000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - - cpu7_opp_3014mhz: opp-3014400000 { - opp-hz = /bits/ 64 <3014400000>; -- opp-peak-kBps = <8532000 48537600>; -+ opp-peak-kBps = <12787200 48537600>; - }; - }; - -@@ -4268,6 +4268,12 @@ opp-6 { - opp-7 { - opp-peak-kBps = <8532000>; - }; -+ opp-8 { -+ opp-peak-kBps = <10944000>; -+ }; -+ opp-9 { -+ opp-peak-kBps = <12787200>; -+ }; - }; - }; - --- -Armbian - diff --git a/patch/kernel/archive/qcs6490-6.16/0000.patching_config.yaml b/patch/kernel/archive/qcs6490-6.18/0000.patching_config.yaml similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0000.patching_config.yaml rename to patch/kernel/archive/qcs6490-6.18/0000.patching_config.yaml diff --git a/patch/kernel/archive/qcs6490-6.16/0004-arm64-dts-qcom-qcs6490-audioreach-Modify-LPASS-macro.patch b/patch/kernel/archive/qcs6490-6.18/0004-arm64-dts-qcom-qcs6490-audioreach-Modify-LPASS-macro.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0004-arm64-dts-qcom-qcs6490-audioreach-Modify-LPASS-macro.patch rename to patch/kernel/archive/qcs6490-6.18/0004-arm64-dts-qcom-qcs6490-audioreach-Modify-LPASS-macro.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0010-phy-qcom-qmp-combo-temporarily-fix-the-orientation-t.patch b/patch/kernel/archive/qcs6490-6.18/0010-phy-qcom-qmp-combo-temporarily-fix-the-orientation-t.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0010-phy-qcom-qmp-combo-temporarily-fix-the-orientation-t.patch rename to patch/kernel/archive/qcs6490-6.18/0010-phy-qcom-qmp-combo-temporarily-fix-the-orientation-t.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0016-firmware-psci-Read-and-use-vendor-reset-types.patch b/patch/kernel/archive/qcs6490-6.18/0016-firmware-psci-Read-and-use-vendor-reset-types.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0016-firmware-psci-Read-and-use-vendor-reset-types.patch rename to patch/kernel/archive/qcs6490-6.18/0016-firmware-psci-Read-and-use-vendor-reset-types.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0018-drm-birdge-simple-bridge-Add-support-for-radxa-ra620.patch b/patch/kernel/archive/qcs6490-6.18/0018-drm-birdge-simple-bridge-Add-support-for-radxa-ra620.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0018-drm-birdge-simple-bridge-Add-support-for-radxa-ra620.patch rename to patch/kernel/archive/qcs6490-6.18/0018-drm-birdge-simple-bridge-Add-support-for-radxa-ra620.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0019-scsi-ufs-qcom-temporarily-force-to-rate-A.patch b/patch/kernel/archive/qcs6490-6.18/0019-scsi-ufs-qcom-temporarily-force-to-rate-A.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0019-scsi-ufs-qcom-temporarily-force-to-rate-A.patch rename to patch/kernel/archive/qcs6490-6.18/0019-scsi-ufs-qcom-temporarily-force-to-rate-A.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0020-phy-qcom-qmp-ufs-Fix-HS-G4-PHY-init-table-for-sc7280.patch b/patch/kernel/archive/qcs6490-6.18/0020-phy-qcom-qmp-ufs-Fix-HS-G4-PHY-init-table-for-sc7280.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0020-phy-qcom-qmp-ufs-Fix-HS-G4-PHY-init-table-for-sc7280.patch rename to patch/kernel/archive/qcs6490-6.18/0020-phy-qcom-qmp-ufs-Fix-HS-G4-PHY-init-table-for-sc7280.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0021-arm64-dts-qcom-sc7280-add-OPP-table-support-to-PCIe-.patch b/patch/kernel/archive/qcs6490-6.18/0021-arm64-dts-qcom-sc7280-add-OPP-table-support-to-PCIe-.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0021-arm64-dts-qcom-sc7280-add-OPP-table-support-to-PCIe-.patch rename to patch/kernel/archive/qcs6490-6.18/0021-arm64-dts-qcom-sc7280-add-OPP-table-support-to-PCIe-.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch b/patch/kernel/archive/qcs6490-6.18/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch similarity index 92% rename from patch/kernel/archive/qcs6490-6.16/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch rename to patch/kernel/archive/qcs6490-6.18/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch index 927f05e50..6954b22b9 100644 --- a/patch/kernel/archive/qcs6490-6.16/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch +++ b/patch/kernel/archive/qcs6490-6.18/0022-drm-msm-dpu-Add-missing-caps-and-blocks-to-sc7280-ca.patch @@ -33,9 +33,9 @@ index 111111111111..222222222222 100644 }, }; -@@ -128,32 +131,45 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { +@@ -128,29 +131,42 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { + .name = "pingpong_0", .id = PINGPONG_0, .base = 0x69000, .len = 0, - .features = BIT(DPU_PINGPONG_DITHER), .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_0, @@ -43,7 +43,6 @@ index 111111111111..222222222222 100644 }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x6a000, .len = 0, - .features = BIT(DPU_PINGPONG_DITHER), .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_0, @@ -51,7 +50,6 @@ index 111111111111..222222222222 100644 }, { .name = "pingpong_2", .id = PINGPONG_2, .base = 0x6b000, .len = 0, - .features = BIT(DPU_PINGPONG_DITHER), .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_1, @@ -59,7 +57,6 @@ index 111111111111..222222222222 100644 }, { .name = "pingpong_3", .id = PINGPONG_3, .base = 0x6c000, .len = 0, - .features = BIT(DPU_PINGPONG_DITHER), .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_1, diff --git a/patch/kernel/archive/qcs6490-6.16/0023-remoteproc-core-Allow-auto-retry-of-rproc_start.patch b/patch/kernel/archive/qcs6490-6.18/0023-remoteproc-core-Allow-auto-retry-of-rproc_start.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0023-remoteproc-core-Allow-auto-retry-of-rproc_start.patch rename to patch/kernel/archive/qcs6490-6.18/0023-remoteproc-core-Allow-auto-retry-of-rproc_start.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0024-scripts-Add-PKGBUILD-for-testing-on-Arch-Linux-ARM.patch b/patch/kernel/archive/qcs6490-6.18/0024-scripts-Add-PKGBUILD-for-testing-on-Arch-Linux-ARM.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0024-scripts-Add-PKGBUILD-for-testing-on-Arch-Linux-ARM.patch rename to patch/kernel/archive/qcs6490-6.18/0024-scripts-Add-PKGBUILD-for-testing-on-Arch-Linux-ARM.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0028-configs-Add-qcom_module_defconfig.patch b/patch/kernel/archive/qcs6490-6.18/0028-configs-Add-qcom_module_defconfig.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0028-configs-Add-qcom_module_defconfig.patch rename to patch/kernel/archive/qcs6490-6.18/0028-configs-Add-qcom_module_defconfig.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0029-spi-spi-qcom-qspi-Add-support-for-polling.patch b/patch/kernel/archive/qcs6490-6.18/0029-spi-spi-qcom-qspi-Add-support-for-polling.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0029-spi-spi-qcom-qspi-Add-support-for-polling.patch rename to patch/kernel/archive/qcs6490-6.18/0029-spi-spi-qcom-qspi-Add-support-for-polling.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0030-drm-panel-Add-support-for-Orise-Tech-OTA7290B-DSI-Pa.patch b/patch/kernel/archive/qcs6490-6.18/0030-drm-panel-Add-support-for-Orise-Tech-OTA7290B-DSI-Pa.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0030-drm-panel-Add-support-for-Orise-Tech-OTA7290B-DSI-Pa.patch rename to patch/kernel/archive/qcs6490-6.18/0030-drm-panel-Add-support-for-Orise-Tech-OTA7290B-DSI-Pa.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0031-arm64-dts-qcom-sc7280-Add-cci-aliases.patch b/patch/kernel/archive/qcs6490-6.18/0031-arm64-dts-qcom-sc7280-Add-cci-aliases.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0031-arm64-dts-qcom-sc7280-Add-cci-aliases.patch rename to patch/kernel/archive/qcs6490-6.18/0031-arm64-dts-qcom-sc7280-Add-cci-aliases.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch b/patch/kernel/archive/qcs6490-6.18/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch similarity index 99% rename from patch/kernel/archive/qcs6490-6.16/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch rename to patch/kernel/archive/qcs6490-6.18/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch index 77958b958..b94dd4977 100644 --- a/patch/kernel/archive/qcs6490-6.16/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch +++ b/patch/kernel/archive/qcs6490-6.18/0032-arm64-dts-qcom-Add-initial-support-for-Radxa-Dragon-.patch @@ -101,7 +101,7 @@ new file mode 100644 index 000000000000..111111111111 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts -@@ -0,0 +1,1410 @@ +@@ -0,0 +1,1404 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd. @@ -1372,9 +1372,6 @@ index 000000000000..111111111111 + +&usb_1 { + status = "okay"; -+}; -+ -+&usb_1_dwc3 { + dr_mode = "host"; +}; + @@ -1399,9 +1396,6 @@ index 000000000000..111111111111 + +&usb_2 { + status = "okay"; -+}; -+ -+&usb_2_dwc3 { + dr_mode = "host"; +}; + diff --git a/patch/kernel/archive/qcs6490-6.16/0033-arm64-dts-qcom-radxa-dragon-q6a-Add-user-led.patch b/patch/kernel/archive/qcs6490-6.18/0033-arm64-dts-qcom-radxa-dragon-q6a-Add-user-led.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0033-arm64-dts-qcom-radxa-dragon-q6a-Add-user-led.patch rename to patch/kernel/archive/qcs6490-6.18/0033-arm64-dts-qcom-radxa-dragon-q6a-Add-user-led.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0034-arm64-dts-qcom-Add-qcs6490-dragon-q6a-radxa-display-.patch b/patch/kernel/archive/qcs6490-6.18/0034-arm64-dts-qcom-Add-qcs6490-dragon-q6a-radxa-display-.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0034-arm64-dts-qcom-Add-qcs6490-dragon-q6a-radxa-display-.patch rename to patch/kernel/archive/qcs6490-6.18/0034-arm64-dts-qcom-Add-qcs6490-dragon-q6a-radxa-display-.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0035-soc-qcom-geni-se-Add-MODULE_FIRMWARE-macro.patch b/patch/kernel/archive/qcs6490-6.18/0035-soc-qcom-geni-se-Add-MODULE_FIRMWARE-macro.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0035-soc-qcom-geni-se-Add-MODULE_FIRMWARE-macro.patch rename to patch/kernel/archive/qcs6490-6.18/0035-soc-qcom-geni-se-Add-MODULE_FIRMWARE-macro.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0036-arm64-configs-Update-qcom_module_defconfig.patch b/patch/kernel/archive/qcs6490-6.18/0036-arm64-configs-Update-qcom_module_defconfig.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0036-arm64-configs-Update-qcom_module_defconfig.patch rename to patch/kernel/archive/qcs6490-6.18/0036-arm64-configs-Update-qcom_module_defconfig.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch b/patch/kernel/archive/qcs6490-6.18/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch similarity index 98% rename from patch/kernel/archive/qcs6490-6.16/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch rename to patch/kernel/archive/qcs6490-6.18/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch index 37cbaaaf2..201b04acf 100644 --- a/patch/kernel/archive/qcs6490-6.16/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch +++ b/patch/kernel/archive/qcs6490-6.18/0037-soc-qcom-rpmh-Add-support-to-read-back-resource-sett.patch @@ -41,9 +41,9 @@ index 111111111111..222222222222 100644 + req->cmds[0].data = read_tcs_reg(drv, reg, i); + } + - /* - * If wake tcs was re-purposed for sending active - * votes, clear AMC trigger & enable modes and + /* Clear AMC trigger & enable modes and + * disable interrupt for this TCS + */ @@ -496,13 +502,14 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, const struct tcs_request *msg) { diff --git a/patch/kernel/archive/qcs6490-6.16/0038-regulator-qcom-rpmh-Add-support-to-read-regulator-se.patch b/patch/kernel/archive/qcs6490-6.18/0038-regulator-qcom-rpmh-Add-support-to-read-regulator-se.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0038-regulator-qcom-rpmh-Add-support-to-read-regulator-se.patch rename to patch/kernel/archive/qcs6490-6.18/0038-regulator-qcom-rpmh-Add-support-to-read-regulator-se.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0039-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Optimize-reg.patch b/patch/kernel/archive/qcs6490-6.18/0039-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Optimize-reg.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0039-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Optimize-reg.patch rename to patch/kernel/archive/qcs6490-6.18/0039-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Optimize-reg.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0040-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Move-LED-nod.patch b/patch/kernel/archive/qcs6490-6.18/0040-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Move-LED-nod.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0040-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Move-LED-nod.patch rename to patch/kernel/archive/qcs6490-6.18/0040-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Move-LED-nod.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0041-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-pcie0_cl.patch b/patch/kernel/archive/qcs6490-6.18/0041-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-pcie0_cl.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0041-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-pcie0_cl.patch rename to patch/kernel/archive/qcs6490-6.18/0041-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-pcie0_cl.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0042-scsi-ufs-qcom-Add-support-for-UFS-module-detection.patch b/patch/kernel/archive/qcs6490-6.18/0042-scsi-ufs-qcom-Add-support-for-UFS-module-detection.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0042-scsi-ufs-qcom-Add-support-for-UFS-module-detection.patch rename to patch/kernel/archive/qcs6490-6.18/0042-scsi-ufs-qcom-Add-support-for-UFS-module-detection.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0043-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-UFS-modu.patch b/patch/kernel/archive/qcs6490-6.18/0043-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-UFS-modu.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0043-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-UFS-modu.patch rename to patch/kernel/archive/qcs6490-6.18/0043-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-UFS-modu.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0044-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-overlays.patch b/patch/kernel/archive/qcs6490-6.18/0044-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-overlays.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0044-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-overlays.patch rename to patch/kernel/archive/qcs6490-6.18/0044-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Fix-overlays.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0045-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-an-overl.patch b/patch/kernel/archive/qcs6490-6.18/0045-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-an-overl.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0045-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-an-overl.patch rename to patch/kernel/archive/qcs6490-6.18/0045-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Add-an-overl.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0046-arm64-dts-qcom-qcs6490-dragon-q6a-add-gpio-label.patch b/patch/kernel/archive/qcs6490-6.18/0046-arm64-dts-qcom-qcs6490-dragon-q6a-add-gpio-label.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0046-arm64-dts-qcom-qcs6490-dragon-q6a-add-gpio-label.patch rename to patch/kernel/archive/qcs6490-6.18/0046-arm64-dts-qcom-qcs6490-dragon-q6a-add-gpio-label.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0047-drivers-gpu-drm-fix-4K-30-fps.patch b/patch/kernel/archive/qcs6490-6.18/0047-drivers-gpu-drm-fix-4K-30-fps.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0047-drivers-gpu-drm-fix-4K-30-fps.patch rename to patch/kernel/archive/qcs6490-6.18/0047-drivers-gpu-drm-fix-4K-30-fps.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0048-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Enable-eMMC.patch b/patch/kernel/archive/qcs6490-6.18/0048-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Enable-eMMC.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0048-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Enable-eMMC.patch rename to patch/kernel/archive/qcs6490-6.18/0048-arm64-dts-qcom-qcs6490-radxa-dragon-q6a-Enable-eMMC.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0049-drm-display-add-hw_params-callback-function-to-drm_c.patch b/patch/kernel/archive/qcs6490-6.18/0049-drm-display-add-hw_params-callback-function-to-drm_c.patch similarity index 100% rename from patch/kernel/archive/qcs6490-6.16/0049-drm-display-add-hw_params-callback-function-to-drm_c.patch rename to patch/kernel/archive/qcs6490-6.18/0049-drm-display-add-hw_params-callback-function-to-drm_c.patch diff --git a/patch/kernel/archive/rockchip-6.12/kernel-6.8-tools-cgroup-makefile.patch b/patch/kernel/archive/rockchip-6.12/kernel-6.8-tools-cgroup-makefile.patch index 068fe8368..dbe14a47e 100644 --- a/patch/kernel/archive/rockchip-6.12/kernel-6.8-tools-cgroup-makefile.patch +++ b/patch/kernel/archive/rockchip-6.12/kernel-6.8-tools-cgroup-makefile.patch @@ -1,6 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 25 Mar 2024 19:38:38 +0100 +Subject: [ARCHEOLOGY] rockchip: bump edge kernel to 6.8 + +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + tools/cgroup/Makefile | 11 ++++++++++ + 1 file changed, 11 insertions(+) + diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile new file mode 100644 -index 000000000000..ffca068e4a76 +index 000000000000..111111111111 --- /dev/null +++ b/tools/cgroup/Makefile @@ -0,0 +1,11 @@ @@ -15,3 +49,6 @@ index 000000000000..ffca068e4a76 + +clean: + $(RM) cgroup_event_listener +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-ds1307.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-ds1307.dtbo deleted file mode 100644 index 937c261ae..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-ds1307.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c1.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c1.dtbo deleted file mode 100644 index fd1b3d988..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c1.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c4.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c4.dtbo deleted file mode 100644 index aa2836e20..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-i2c4.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi0.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi0.dtbo deleted file mode 100644 index 060d23bce..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi0.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi2.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi2.dtbo deleted file mode 100644 index 7bedbcbee..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spi2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev0.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev0.dtbo deleted file mode 100644 index 2423a6ca4..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev0.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev2.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev2.dtbo deleted file mode 100644 index 65f6860c6..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-spidev2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart1.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart1.dtbo deleted file mode 100644 index 0b820aa44..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart1.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart2.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart2.dtbo deleted file mode 100644 index 3e57168c2..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart3.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart3.dtbo deleted file mode 100644 index d171ece89..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart3.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart4.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart4.dtbo deleted file mode 100644 index 795fdebae..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-uart4.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-w1-gpio.dtbo b/patch/kernel/archive/rockchip-6.12/overlay/rockchip-w1-gpio.dtbo deleted file mode 100644 index 6bbc11452..000000000 Binary files a/patch/kernel/archive/rockchip-6.12/overlay/rockchip-w1-gpio.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/bt-broadcom-serdev-workaround.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/bt-broadcom-serdev-workaround.patch index 8f641846c..882460fa6 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/bt-broadcom-serdev-workaround.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/bt-broadcom-serdev-workaround.patch @@ -1,18 +1,18 @@ -From e5c9702bd2ffd09e48c118ab40c2764590af7929 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 1 May 2021 12:41:14 +0000 -Subject: [PATCH] Workaround to make several broadcom bluetooth serdev devices - work even without proper MAC address +Subject: Workaround to make several broadcom bluetooth serdev devices work + even without proper MAC address --- drivers/bluetooth/btbcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c -index 1b9743b7f..b274f1cdd 100644 +index 111111111111..222222222222 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c -@@ -129,7 +129,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) +@@ -135,7 +135,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) if (btbcm_set_bdaddr_from_efi(hdev) != 0) { bt_dev_info(hdev, "BCM: Using default device address (%pMR)", &bda->bdaddr); @@ -21,7 +21,6 @@ index 1b9743b7f..b274f1cdd 100644 } } - -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/clk-rk322x-composite-mmc-clk.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/clk-rk322x-composite-mmc-clk.patch index 1c889e358..4d8ca1bdf 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/clk-rk322x-composite-mmc-clk.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/clk-rk322x-composite-mmc-clk.patch @@ -1,17 +1,17 @@ -From 9e105544fcb63f8f79b199d1b194a36a354519b3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 2 Apr 2023 10:53:07 +0000 -Subject: [PATCH 2/2] rk322x: better handle mmc/sdio clocks +Subject: rk322x: better handle mmc/sdio clocks --- drivers/clk/rockchip/clk-rk3228.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 996f8bfee..0f690dd84 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -371,17 +371,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -383,17 +383,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, RK2928_CLKGATE_CON(2), 11, GFLAGS), @@ -34,5 +34,5 @@ index 996f8bfee..0f690dd84 100644 /* * Clock-Architecture Diagram 2 -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk322x-audio-codec.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk322x-audio-codec.patch index a3c56bcf1..103638abe 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk322x-audio-codec.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk322x-audio-codec.patch @@ -1,25 +1,22 @@ -From 50a8db983c682918cd2efe02ede48db93892d52a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 20 Jul 2024 13:51:55 +0200 -Subject: [PATCH] rk3228: add analog audio codec +Subject: rk3228: add analog audio codec --- - .../bindings/sound/rockchip,rk3228-codec.txt | 22 + - arch/arm/boot/dts/rockchip/rk322x.dtsi | 9 + - drivers/clk/rockchip/clk-rk3228.c | 2 +- - include/dt-bindings/clock/rk3228-cru.h | 1 + - sound/soc/codecs/Kconfig | 6 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/rk3228_codec.c | 545 ++++++++++++++++++ - sound/soc/codecs/rk3228_codec.h | 218 +++++++ + Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt | 22 + + arch/arm/boot/dts/rockchip/rk322x.dtsi | 9 + + drivers/clk/rockchip/clk-rk3228.c | 2 +- + include/dt-bindings/clock/rk3228-cru.h | 1 + + sound/soc/codecs/Kconfig | 6 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/rk3228_codec.c | 545 ++++++++++ + sound/soc/codecs/rk3228_codec.h | 218 ++++ 8 files changed, 804 insertions(+), 1 deletion(-) - create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt - create mode 100644 sound/soc/codecs/rk3228_codec.c - create mode 100644 sound/soc/codecs/rk3228_codec.h diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt new file mode 100644 -index 000000000000..9191a8593380 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt @@ -0,0 +1,22 @@ @@ -46,10 +43,10 @@ index 000000000000..9191a8593380 + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index cc5a5e609f04..d13dc979a67e 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -249,6 +249,15 @@ i2s1: i2s1@100b0000 { +@@ -149,6 +149,15 @@ i2s1: i2s1@100b0000 { status = "disabled"; }; @@ -66,10 +63,10 @@ index cc5a5e609f04..d13dc979a67e 100644 compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100c0000 0x4000>; diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 0db8a97007f2..0f690dd84650 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -603,7 +603,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -618,7 +618,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), @@ -79,10 +76,10 @@ index 0db8a97007f2..0f690dd84650 100644 GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h -index 911824731866..9162f9132657 100644 +index 111111111111..222222222222 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h -@@ -116,6 +116,7 @@ +@@ -115,6 +115,7 @@ #define PCLK_HDMI_CTRL 364 #define PCLK_HDMI_PHY 365 #define PCLK_GMAC 367 @@ -91,10 +88,10 @@ index 911824731866..9162f9132657 100644 /* hclk gates */ #define HCLK_I2S0_8CH 442 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 4afc43d3f71f..183a69249160 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -182,6 +182,7 @@ config SND_SOC_ALL_CODECS +@@ -186,6 +186,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_PCM6240 imply SND_SOC_PEB2466 imply SND_SOC_RK3308 @@ -102,7 +99,7 @@ index 4afc43d3f71f..183a69249160 100644 imply SND_SOC_RK3328 imply SND_SOC_RK817 imply SND_SOC_RT274 -@@ -1457,6 +1458,11 @@ config SND_SOC_RK3308 +@@ -1494,6 +1495,11 @@ config SND_SOC_RK3308 It has 8 24-bit ADCs and 2 24-bit DACs. The maximum supported sampling rate is 192 kHz. @@ -115,10 +112,10 @@ index 4afc43d3f71f..183a69249160 100644 tristate "Rockchip RK3328 audio CODEC" depends on ARCH_ROCKCHIP || COMPILE_TEST diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index b4df22186e25..454179eb7b73 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -207,6 +207,7 @@ snd-soc-pcm512x-spi-y := pcm512x-spi.o +@@ -213,6 +213,7 @@ snd-soc-pcm512x-spi-y := pcm512x-spi.o snd-soc-pcm6240-y := pcm6240.o snd-soc-peb2466-y := peb2466.o snd-soc-rk3308-y := rk3308_codec.o @@ -126,7 +123,7 @@ index b4df22186e25..454179eb7b73 100644 snd-soc-rk3328-y := rk3328_codec.o snd-soc-rk817-y := rk817_codec.o snd-soc-rl6231-y := rl6231.o -@@ -599,6 +600,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +@@ -615,6 +616,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o obj-$(CONFIG_SND_SOC_PCM6240) += snd-soc-pcm6240.o obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o @@ -136,7 +133,7 @@ index b4df22186e25..454179eb7b73 100644 obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o diff --git a/sound/soc/codecs/rk3228_codec.c b/sound/soc/codecs/rk3228_codec.c new file mode 100644 -index 000000000000..197e7e2e0d8b +index 000000000000..111111111111 --- /dev/null +++ b/sound/soc/codecs/rk3228_codec.c @@ -0,0 +1,545 @@ @@ -687,7 +684,7 @@ index 000000000000..197e7e2e0d8b +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rk3228_codec.h b/sound/soc/codecs/rk3228_codec.h new file mode 100644 -index 000000000000..7283d0ba86e8 +index 000000000000..111111111111 --- /dev/null +++ b/sound/soc/codecs/rk3228_codec.h @@ -0,0 +1,218 @@ @@ -910,5 +907,5 @@ index 000000000000..7283d0ba86e8 + +#endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk3288-gpiomem.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk3288-gpiomem.patch index e2f887bdd..7d1ac4d16 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk3288-gpiomem.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-rk3288-gpiomem.patch @@ -1,8 +1,128 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Igor Pecovnik +Date: Thu, 24 May 2018 15:44:15 +0200 +Subject: [ARCHEOLOGY] Merging Rockchip family + +> X-Git-Archeology: - Revision 7d2f3af08f23049c91c88eec5062613bbfbc85d4: https://github.com/armbian/build/commit/7d2f3af08f23049c91c88eec5062613bbfbc85d4 +> X-Git-Archeology: Date: Thu, 24 May 2018 15:44:15 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Merging Rockchip family +> X-Git-Archeology: +> X-Git-Archeology: - Revision fafd26db7e055a87e775fdc18de8e64f95e53d41: https://github.com/armbian/build/commit/fafd26db7e055a87e775fdc18de8e64f95e53d41 +> X-Git-Archeology: Date: Thu, 28 Jun 2018 22:11:59 -0400 +> X-Git-Archeology: From: Tony +> X-Git-Archeology: Subject: Rockchip default merge (#1026) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96e78c102f8c9a3719b9cb4a9eb6becb063891ce: https://github.com/armbian/build/commit/96e78c102f8c9a3719b9cb4a9eb6becb063891ce +> X-Git-Archeology: Date: Sun, 08 Jul 2018 13:19:07 -0700 +> X-Git-Archeology: From: Rabit +> X-Git-Archeology: Subject: ASUS Tinkerboard: Restore justice - author of the gpiomem port +> X-Git-Archeology: +> X-Git-Archeology: - Revision 106685906579e4c5528fcd22abf79c6719d633fb: https://github.com/armbian/build/commit/106685906579e4c5528fcd22abf79c6719d633fb +> X-Git-Archeology: Date: Sun, 08 Jul 2018 14:12:15 -0700 +> X-Git-Archeology: From: Rabit +> X-Git-Archeology: Subject: ASUS Tinkerboard: Added gpio & i2c groups with udev rules to devices +> X-Git-Archeology: +> X-Git-Archeology: - Revision de41d3dbce3ed5e467019c0f74ac93dbeb866ded: https://github.com/armbian/build/commit/de41d3dbce3ed5e467019c0f74ac93dbeb866ded +> X-Git-Archeology: Date: Fri, 10 Aug 2018 10:33:42 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Rockchip default cleanup. (Temporally) moving back to Rockchip upstream. This source builds but doesn't boot ... +> X-Git-Archeology: +> X-Git-Archeology: - Revision fc1715450015ae62374a13d77f19b0ab53bb1d4c: https://github.com/armbian/build/commit/fc1715450015ae62374a13d77f19b0ab53bb1d4c +> X-Git-Archeology: Date: Sat, 13 Jul 2019 15:14:54 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: rockchip-dev: bump to 5.2, adjust pathes, add gpio_mem driver +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 744ea89a589d62cb6f409baab60fc6664520bc39: https://github.com/armbian/build/commit/744ea89a589d62cb6f409baab60fc6664520bc39 +> X-Git-Archeology: Date: Wed, 08 Sep 2021 17:51:34 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bumping EDGE kernel to 5.14.y (#3125) +> X-Git-Archeology: +> X-Git-Archeology: - Revision a1d044de8e0bb6ca504386bc31f5615a9d169067: https://github.com/armbian/build/commit/a1d044de8e0bb6ca504386bc31f5615a9d169067 +> X-Git-Archeology: Date: Tue, 12 Oct 2021 15:59:01 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: update support for edge kernel 5.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9: https://github.com/armbian/build/commit/4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9 +> X-Git-Archeology: Date: Tue, 09 Nov 2021 21:58:35 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Rockchip 5.15 (#3242) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 3f704692a7933a67b5e8cc6ff690d92ef3a5e735: https://github.com/armbian/build/commit/3f704692a7933a67b5e8cc6ff690d92ef3a5e735 +> X-Git-Archeology: Date: Fri, 24 Mar 2023 23:12:56 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.2 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4605bcab83d3d0c0360da7dd0f9ee90e884b58e4: https://github.com/armbian/build/commit/4605bcab83d3d0c0360da7dd0f9ee90e884b58e4 +> X-Git-Archeology: Date: Sun, 09 Jul 2023 11:24:10 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge kernel to 6.4 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 3 + + arch/arm/boot/dts/rockchip/rk3288.dtsi | 6 + + drivers/char/Kconfig | 1 + + drivers/char/Makefile | 2 + + drivers/char/rockchip/Kconfig | 16 + + drivers/char/rockchip/Makefile | 1 + + drivers/char/rockchip/rk3288-gpiomem.c | 303 ++++++++++ + 7 files changed, 332 insertions(+) + diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index e5b7ef1a5..f88c913ff 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -544,3 +544,6 @@ +@@ -544,3 +544,6 @@ &vopl_mmu { &wdt { status = "okay"; }; @@ -10,13 +130,13 @@ index e5b7ef1a5..f88c913ff 100644 + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index f3ca55496..14bbcb192 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1418,6 +1418,12 @@ +@@ -1479,6 +1479,12 @@ gic: interrupt-controller@ffc01000 { interrupts = ; }; - + + gpiomem: rk3288-gpiomem@ff750000 { + compatible = "rockchip,rk3288-gpiomem"; + reg = <0x0 0xff750000 0x0 0x1000>; @@ -26,27 +146,26 @@ index f3ca55496..14bbcb192 100644 pinctrl: pinctrl { compatible = "rockchip,rk3288-pinctrl"; rockchip,grf = <&grf>; - diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index 3143db5..9c18b74 100644 +index 111111111111..222222222222 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig -@@ -5,6 +5,7 @@ +@@ -6,6 +6,7 @@ menu "Character devices" - + source "drivers/tty/Kconfig" +source "drivers/char/rockchip/Kconfig" - - config DEVMEM - bool "/dev/mem virtual device support" + + config TTY_PRINTK + tristate "TTY driver to output user messages via printk" diff --git a/drivers/char/Makefile b/drivers/char/Makefile -index 264eb398f..9fd5f240b 100644 +index 111111111111..222222222222 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile -@@ -43,6 +43,8 @@ obj-$(CONFIG_TCG_TPM) += tpm/ - +@@ -40,6 +40,8 @@ obj-$(CONFIG_TCG_TPM) += tpm/ + obj-$(CONFIG_PS3_FLASH) += ps3flash.o - + +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ + obj-$(CONFIG_XILLYBUS_CLASS) += xillybus/ @@ -54,7 +173,7 @@ index 264eb398f..9fd5f240b 100644 obj-$(CONFIG_ADI) += adi.o diff --git a/drivers/char/rockchip/Kconfig b/drivers/char/rockchip/Kconfig new file mode 100644 -index 0000000..6e97486 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/Kconfig @@ -0,0 +1,16 @@ @@ -77,7 +196,7 @@ index 0000000..6e97486 \ No newline at end of file diff --git a/drivers/char/rockchip/Makefile b/drivers/char/rockchip/Makefile new file mode 100644 -index 0000000..2287ec2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/Makefile @@ -0,0 +1 @@ @@ -85,7 +204,7 @@ index 0000000..2287ec2 \ No newline at end of file diff --git a/drivers/char/rockchip/rk3288-gpiomem.c b/drivers/char/rockchip/rk3288-gpiomem.c new file mode 100644 -index 0000000..984471c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/rk3288-gpiomem.c @@ -0,0 +1,303 @@ @@ -393,3 +512,6 @@ index 0000000..984471c +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); \ No newline at end of file +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-tinkerboard-alc4040-codec.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-tinkerboard-alc4040-codec.patch index f85f24fb7..cf68b3e6a 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-tinkerboard-alc4040-codec.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/driver-tinkerboard-alc4040-codec.patch @@ -1,8 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony +Date: Sun, 15 Apr 2018 14:40:58 -0400 +Subject: [ARCHEOLOGY] Rockchip next sync master and development + +> X-Git-Archeology: > recovered message: > includes kernel panic fix on veth interfaces and audio device patch to enable Tinkerboard audio +> X-Git-Archeology: - Revision b1a21a44cde3d976b9b8ebce4f265e5aa79b2d8a: https://github.com/armbian/build/commit/b1a21a44cde3d976b9b8ebce4f265e5aa79b2d8a +> X-Git-Archeology: Date: Sun, 15 Apr 2018 14:40:58 -0400 +> X-Git-Archeology: From: Tony +> X-Git-Archeology: Subject: Rockchip next sync master and development +> X-Git-Archeology: +> X-Git-Archeology: - Revision b6f1503dfdb215429cc6dee6c2b94ca9ddc96fbc: https://github.com/armbian/build/commit/b6f1503dfdb215429cc6dee6c2b94ca9ddc96fbc +> X-Git-Archeology: Date: Mon, 26 Nov 2018 01:38:25 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ tinkerboard ] dev kernel add audio support +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + sound/usb/card.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + diff --git a/sound/usb/card.c b/sound/usb/card.c -index 2bfe4e80a..cea93aaf5 100644 +index 111111111111..222222222222 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c -@@ -382,6 +382,14 @@ static void usb_audio_make_shortname(struct usb_device *dev, +@@ -533,6 +533,14 @@ static void usb_audio_make_shortname(struct usb_device *dev, } strim(card->shortname); @@ -17,3 +82,6 @@ index 2bfe4e80a..cea93aaf5 100644 } static void usb_audio_make_longname(struct usb_device *dev, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-plane-overlay.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-plane-overlay.patch index 15319a894..6c48ba981 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-plane-overlay.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-plane-overlay.patch @@ -1,8 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: paolo +Date: Sat, 19 Sep 2020 15:20:16 +0000 +Subject: [ARCHEOLOGY] Many changes for rk322x target: + +> X-Git-Archeology: > recovered message: > - Chanaged default x.org configuration to disable glamor +> X-Git-Archeology: > recovered message: > - Reintroduce patch to use DRM cursor plane as overlay in rk322x-current and -dev +> X-Git-Archeology: > recovered message: > - Updated wifi patches for kernel 5.8.10 +> X-Git-Archeology: > recovered message: > - Bumped rk322x to u-boot v2020.07, removed reserved zones from device trees +> X-Git-Archeology: > recovered message: > - Updated OPTEE to v3.10, using ddrbin v1.10 +> X-Git-Archeology: > recovered message: > - Bumped rk322x-current to kernel 5.8.y +> X-Git-Archeology: > recovered message: > - Imported new patches from knaerzche's LibreELEC fork for rk322x-dev (kernel 5.8.y) +> X-Git-Archeology: > recovered message: > - Adjusted existing patches to match changes, updated rk322x-dev kernel config file +> X-Git-Archeology: > recovered message: > - Add default modprobe conf file for esp8089 to force the crystal frequency to 40Mhz for rk322x targets +> X-Git-Archeology: > recovered message: > - Removed ssv6051 firmware packages to move to armbian-firmware repository +> X-Git-Archeology: > recovered message: > - Switching ssv6051-wifi.cfg to /lib/firmware for rk322x-legacy +> X-Git-Archeology: > recovered message: > - Removed P2P interface for esp8089 driver for rk322x-legacy +> X-Git-Archeology: > recovered message: > - Optimized ssv6051 performance: kernel module gains -Os flag, disabled p2p interface, enabled HW crypto for CCMP cipher +> X-Git-Archeology: > recovered message: > - Enabled remote control interface, IR GPIO kernel module and HDMI CEC modules +> X-Git-Archeology: - Revision bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076: https://github.com/armbian/build/commit/bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076 +> X-Git-Archeology: Date: Sat, 19 Sep 2020 15:20:16 +0000 +> X-Git-Archeology: From: paolo +> X-Git-Archeology: Subject: Many changes for rk322x target: +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 44 +++++++++- + 1 file changed, 41 insertions(+), 3 deletions(-) + diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 73d24c6bbf05..d4ac6e161ef2 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -614,6 +614,44 @@ static const struct vop_common rk3288_common = { +@@ -735,6 +735,44 @@ static const struct vop_common rk3288_common = { .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), }; @@ -47,7 +110,7 @@ index 73d24c6bbf05..d4ac6e161ef2 100644 /* * Note: rk3288 has a dedicated 'cursor' window, however, that window requires * special support to get alpha blending working. For now, just use overlay -@@ -864,10 +902,10 @@ static const struct vop_data rk3399_vop_lit = { +@@ -1112,10 +1150,10 @@ static const struct vop_data rk3399_vop_lit = { }; static const struct vop_win_data rk3228_vop_win_data[] = { @@ -62,5 +125,5 @@ index 73d24c6bbf05..d4ac6e161ef2 100644 static const struct vop_data rk3228_vop = { -- -2.17.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-yuv-10bit-modes.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-yuv-10bit-modes.patch index acd738f00..420c85737 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-yuv-10bit-modes.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rk322x-yuv-10bit-modes.patch @@ -1,17 +1,17 @@ -From 2d42546642fa4299d88fa4ae414fa1ab205dad70 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 11 Sep 2021 17:38:48 +0000 -Subject: [PATCH] rk322x: enable YUV modes for win1, 10-bit for win0/win1 +Subject: rk322x: enable YUV modes for win1, 10-bit for win0/win1 --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 70930b410..3fd00b323 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -719,10 +719,11 @@ static const struct vop_common rk3288_common = { +@@ -737,10 +737,11 @@ static const struct vop_common rk3288_common = { static const struct vop_win_phy rk3228_win0_data = { .scl = &rk3288_win_full_scl, @@ -25,7 +25,7 @@ index 70930b410..3fd00b323 100644 .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), -@@ -738,10 +739,11 @@ static const struct vop_win_phy rk3228_win0_data = { +@@ -756,10 +757,11 @@ static const struct vop_win_phy rk3228_win0_data = { static const struct vop_win_phy rk3228_win1_data = { .scl = &rk3288_win_full_scl, @@ -40,5 +40,5 @@ index 70930b410..3fd00b323 100644 .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rockchip-hardware-cursor.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rockchip-hardware-cursor.patch index 0c4abae7c..b176a6ceb 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rockchip-hardware-cursor.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/drm-rockchip-hardware-cursor.patch @@ -1,19 +1,19 @@ -From ff9a0ab9d920d4a855b4be9912a57ac65e8906e2 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Fri, 10 Sep 2021 14:10:18 +0000 -Subject: [PATCH] drm rockchip hardware cursor +Subject: drm rockchip hardware cursor --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 218 +++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 208 +++++++++- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 3 + - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 19 +- - 3 files changed, 238 insertions(+), 2 deletions(-) + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 23 +- + 3 files changed, 230 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 83a926c0a..b0832320e 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -1160,6 +1160,197 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane, +@@ -1177,6 +1177,197 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane, } } @@ -211,8 +211,8 @@ index 83a926c0a..b0832320e 100644 static const struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_check = vop_plane_atomic_check, .atomic_update = vop_plane_atomic_update, -@@ -1169,6 +1370,15 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = { - .prepare_fb = drm_gem_plane_helper_prepare_fb, +@@ -1185,6 +1376,15 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = { + .atomic_async_update = vop_plane_atomic_async_update, }; +static const struct drm_plane_helper_funcs cursor_plane_helper_funcs = { @@ -227,7 +227,7 @@ index 83a926c0a..b0832320e 100644 static const struct drm_plane_funcs vop_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, -@@ -1956,6 +2166,7 @@ static int vop_create_crtc(struct vop *vop) +@@ -2020,6 +2220,7 @@ static int vop_create_crtc(struct vop *vop) struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp; struct drm_crtc *crtc = &vop->crtc; struct device_node *port; @@ -235,7 +235,7 @@ index 83a926c0a..b0832320e 100644 int ret; int i; -@@ -1976,7 +2187,12 @@ static int vop_create_crtc(struct vop *vop) +@@ -2040,7 +2241,12 @@ static int vop_create_crtc(struct vop *vop) } plane = &vop_win->base; @@ -250,10 +250,10 @@ index 83a926c0a..b0832320e 100644 if (plane->type == DRM_PLANE_TYPE_PRIMARY) primary = plane; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -index a997578e1..42dc299d9 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -@@ -190,6 +190,8 @@ struct vop_win_phy { +@@ -213,6 +213,8 @@ struct vop_win_phy { struct vop_reg alpha_mode; struct vop_reg alpha_en; struct vop_reg channel; @@ -262,7 +262,7 @@ index a997578e1..42dc299d9 100644 }; struct vop_win_yuv2yuv_data { -@@ -225,6 +227,7 @@ struct vop_data { +@@ -243,6 +245,7 @@ struct vop_data { #define VOP_FEATURE_OUTPUT_RGB10 BIT(0) #define VOP_FEATURE_INTERNAL_RGB BIT(1) @@ -271,10 +271,10 @@ index a997578e1..42dc299d9 100644 }; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index ab0a78097..70930b410 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -665,6 +665,19 @@ static const struct vop_win_phy rk3288_win23_data = { +@@ -696,6 +696,19 @@ static const struct vop_win_phy rk3288_win23_data = { .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0), }; @@ -294,7 +294,7 @@ index ab0a78097..70930b410 100644 static const struct vop_modeset rk3288_modeset = { .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), -@@ -756,6 +769,8 @@ static const struct vop_win_data rk3288_vop_win_data[] = { +@@ -789,6 +802,8 @@ static const struct vop_win_data rk3288_vop_win_data[] = { { .base = 0x00, .phy = &rk3288_win23_data, .type = DRM_PLANE_TYPE_OVERLAY }, { .base = 0x50, .phy = &rk3288_win23_data, @@ -303,7 +303,25 @@ index ab0a78097..70930b410 100644 .type = DRM_PLANE_TYPE_CURSOR }, }; -@@ -1132,11 +1132,13 @@ static const struct vop_win_data rk3228_vop_win_data[] = { +@@ -810,7 +825,7 @@ static const struct vop_intr rk3288_vop_intr = { + + static const struct vop_data rk3288_vop_big = { + .version = VOP_VERSION(3, 1), +- .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE, + .intr = &rk3288_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -828,7 +843,7 @@ static const struct vop_data rk3288_vop_big = { + + static const struct vop_data rk3288_vop_lit = { + .version = VOP_VERSION(3, 1), +- .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE, + .max_output = { 2560, 1600 }, + .intr = &rk3288_vop_intr, + .common = &rk3288_common, +@@ -1156,11 +1171,13 @@ static const struct vop_win_data rk3228_vop_win_data[] = { .type = DRM_PLANE_TYPE_PRIMARY }, { .base = 0x40, .phy = &rk3228_win1_data, .type = DRM_PLANE_TYPE_OVERLAY }, @@ -318,31 +336,6 @@ index ab0a78097..70930b410 100644 .intr = &rk3366_vop_intr, .common = &rk3288_common, .modeset = &rk3288_modeset, - -diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 04e30bdc8a0e..26a246a0fe1d 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -809,7 +809,7 @@ static const struct vop_intr rk3288_vop_intr = { - - static const struct vop_data rk3288_vop_big = { - .version = VOP_VERSION(3, 1), -- .feature = VOP_FEATURE_OUTPUT_RGB10, -+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE, - .intr = &rk3288_vop_intr, - .common = &rk3288_common, - .modeset = &rk3288_modeset, -@@ -827,7 +827,7 @@ static const struct vop_data rk3288_vop_big = { - - static const struct vop_data rk3288_vop_lit = { - .version = VOP_VERSION(3, 1), -- .feature = VOP_FEATURE_OUTPUT_RGB10, -+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE, - .max_output = { 2560, 1600 }, - .intr = &rk3288_vop_intr, - .common = &rk3288_common, - -- -2.25.1 - +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-fan.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-fan.patch index b4b05a4ab..3c12f55f8 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-fan.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-fan.patch @@ -1,7 +1,7 @@ -From c27e445527e949f3ef46d5326066196969c17d23 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Date: Sun, 12 Mar 2017 19:43:15 +0000 -Subject: [PATCH 06/28] ARM: dts: rockchip: add the MiQi board's fan definition +Subject: ARM: dts: rockchip: add the MiQi board's fan definition The MiQi board is sold with an enclosure in which a fan is connected to the second LED output, and configured by default in "heartbeat" @@ -24,10 +24,10 @@ Signed-off-by: Myy 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index a1c3cdaa..0e383595 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -67,6 +67,13 @@ +@@ -30,6 +30,13 @@ ext_gmac: external-gmac-clock { leds { compatible = "gpio-leds"; @@ -42,4 +42,5 @@ index a1c3cdaa..0e383595 100644 gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>; label = "miqi:green:user"; -- -2.11.0 +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-hevc-rga.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-hevc-rga.patch index f1d54b97c..b4f17f38a 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-hevc-rga.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-hevc-rga.patch @@ -1,17 +1,17 @@ -From 2fdd826a704ef70df42d92b38ad88ef869c3729b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 18 Sep 2021 12:32:05 +0000 -Subject: [PATCH 2/2] rockchip: enable hevc, hevc_mmu and rga nodes for miqi +Subject: rockchip: enable hevc, hevc_mmu and rga nodes for miqi --- - arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 12 ++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 12 ++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 94bc76099..68eb766f0 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -162,6 +162,14 @@ &hdmi { +@@ -157,6 +157,14 @@ &hdmi { status = "okay"; }; @@ -26,7 +26,7 @@ index 94bc76099..68eb766f0 100644 &i2c0 { clock-frequency = <400000>; status = "okay"; -@@ -405,6 +413,10 @@ host_vbus_drv: host-vbus-drv { +@@ -399,6 +407,10 @@ host_vbus_drv: host-vbus-drv { }; }; @@ -38,5 +38,5 @@ index 94bc76099..68eb766f0 100644 vref-supply = <&vcc_18>; status = "okay"; -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-mali-gpu.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-mali-gpu.patch index 6a07886e7..a4a8d73be 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-mali-gpu.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-mali-gpu.patch @@ -1,7 +1,7 @@ -From 604ea7fc311af2b3a41e7fe3b4fbde0ee03dfb9c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Thu, 19 Oct 2017 21:09:50 +0200 -Subject: [PATCH 04/28] dts: rk3288: miqi: Enabling the Mali GPU node +Subject: dts: rk3288: miqi: Enabling the Mali GPU node Why is the MiQi the only one left without a working mali GPU node ? @@ -15,11 +15,11 @@ Signed-off-by: Myy Miouyouyou 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 4d923aa6..3cd60674 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -149,6 +149,11 @@ - status = "ok"; +@@ -150,6 +150,11 @@ &gpu { + status = "okay"; }; +&gpu { @@ -29,7 +29,7 @@ index 4d923aa6..3cd60674 100644 + &hdmi { ddc-i2c-bus = <&i2c5>; - status = "okay"; + pinctrl-names = "default"; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-regulator-fix.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-regulator-fix.patch index 01c66a95f..0d715fb96 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-regulator-fix.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-miqi-regulator-fix.patch @@ -1,8 +1,7 @@ -From 89e5763110ca77d68a4be00cd97a638adc2401d5 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 2 Aug 2016 08:31:00 +0200 -Subject: [PATCH 05/28] ARM: dts: rockchip: fix the regulator's voltage range - on MiQi board +Subject: ARM: dts: rockchip: fix the regulator's voltage range on MiQi board The board declared too narrow a voltage range for the CPU and GPU regulators, preventing it from using the full CPU frequency range. @@ -15,10 +14,10 @@ Signed-off-by: Willy Tarreau 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 3cd60674..a1c3cdaa 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -168,8 +168,8 @@ +@@ -179,8 +179,8 @@ vdd_cpu: syr827@40 { fcs,suspend-voltage-selector = <1>; reg = <0x40>; regulator-name = "vdd_cpu"; @@ -29,7 +28,7 @@ index 3cd60674..a1c3cdaa 100644 regulator-always-on; regulator-boot-on; regulator-enable-ramp-delay = <300>; -@@ -182,8 +182,8 @@ +@@ -193,8 +193,8 @@ vdd_gpu: syr828@41 { fcs,suspend-voltage-selector = <1>; reg = <0x41>; regulator-name = "vdd_gpu"; @@ -41,5 +40,5 @@ index 3cd60674..a1c3cdaa 100644 vin-supply = <&vcc_sys>; }; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-iep-node.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-iep-node.patch index 994f01e8e..32606494f 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-iep-node.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-iep-node.patch @@ -1,17 +1,17 @@ -From adecdd57a0155e0d96af2c84cc4fa52309fbb535 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 19:14:08 +0000 -Subject: [PATCH] add iep node for rk322x +Subject: add iep node for rk322x --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 11 +++++++++++ + arch/arm/boot/dts/rockchip/rk322x.dtsi | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 0ae753c1d..271e7835f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -834,6 +834,17 @@ rga: rga@20060000 { +@@ -715,6 +715,17 @@ rga: rga@20060000 { reset-names = "core", "axi", "ahb"; }; @@ -30,5 +30,5 @@ index 0ae753c1d..271e7835f 100644 compatible = "rockchip,iommu"; reg = <0x20070800 0x100>; -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-pinctrl-nand.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-pinctrl-nand.patch index 6c6ab33ff..531a6b60d 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-pinctrl-nand.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk322x-pinctrl-nand.patch @@ -1,8 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Fri, 19 Jun 2020 17:27:27 +0200 +Subject: [ARCHEOLOGY] Introducing Rockchip RK322X SoC support (#2032) + +> X-Git-Archeology: > recovered message: > * Introducing Rockchip rk322x SoC support +> X-Git-Archeology: > recovered message: > Main features: +> X-Git-Archeology: > recovered message: > - Legacy kernel flavour based upon stable v2.x rk3288 Rockchip branch (https://github.com/rockchip-linux/kernel/tree/stable-4.4-rk3288-linux-v2.x) +> X-Git-Archeology: > recovered message: > - Current kernel flavour based on mainline 5.6.y kernel +> X-Git-Archeology: > recovered message: > - Mainline u-boot (v2020.04) +> X-Git-Archeology: > recovered message: > - Single generic tv box target (rk322x-box) which boots on all the known tv boxes +> X-Git-Archeology: > recovered message: > - Hardware devices (eMMC/NAND, led wiring configuration, SoC variant selection) modulation done by user at runtime via device tree overlays - a script (rk322x-config) is provided for autodetection and simple configuration by inexperienced users; +> X-Git-Archeology: > recovered message: > - Bits added to armbian-hardware-optimization to set affinity for irq handlers +> X-Git-Archeology: > recovered message: > - rk322x-box targets already added to targets.conf for automatic image creation +> X-Git-Archeology: > recovered message: > * Removed disabled patches +> X-Git-Archeology: > recovered message: > * Restored mysteriously removed comment character +> X-Git-Archeology: - Revision 23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7: https://github.com/armbian/build/commit/23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7 +> X-Git-Archeology: Date: Fri, 19 Jun 2020 17:27:27 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Introducing Rockchip RK322X SoC support (#2032) +> X-Git-Archeology: +> X-Git-Archeology: - Revision bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076: https://github.com/armbian/build/commit/bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076 +> X-Git-Archeology: Date: Sat, 19 Sep 2020 15:20:16 +0000 +> X-Git-Archeology: From: paolo +> X-Git-Archeology: Subject: Many changes for rk322x target: +> X-Git-Archeology: +> X-Git-Archeology: - Revision 95425c27b9d3bbb96e7936cc531638c9150538f9: https://github.com/armbian/build/commit/95425c27b9d3bbb96e7936cc531638c9150538f9 +> X-Git-Archeology: Date: Fri, 12 Mar 2021 20:20:12 +0000 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: Changes and fixes to rk322x uboot and kernel config +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9: https://github.com/armbian/build/commit/4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9 +> X-Git-Archeology: Date: Tue, 09 Nov 2021 21:58:35 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Rockchip 5.15 (#3242) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0a2892aeba4dec4633a86f8ad573bf62f09cdb38: https://github.com/armbian/build/commit/0a2892aeba4dec4633a86f8ad573bf62f09cdb38 +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:47:01 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rk322x: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk322x.dtsi | 75 ++++++++++ + 1 file changed, 75 insertions(+) + diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 48e6e8d44..1dfd27f9f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -712,6 +712,22 @@ emmc: mmc@30020000 { +@@ -818,6 +818,22 @@ emmc: mmc@30020000 { status = "disabled"; }; @@ -25,7 +105,7 @@ index 48e6e8d44..1dfd27f9f 100644 usb_otg: usb@30040000 { compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb", "snps,dwc2"; -@@ -950,6 +966,65 @@ emmc_bus8: emmc-bus8 { +@@ -1101,6 +1117,65 @@ emmc_bus8: emmc-bus8 { }; }; @@ -91,3 +171,6 @@ index 48e6e8d44..1dfd27f9f 100644 gmac { rgmii_pins: rgmii-pins { rockchip,pins = <2 RK_PB6 1 &pcfg_pull_none>, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-disable-serial-dma.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-disable-serial-dma.patch index b54cf9d59..9a3739da3 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-disable-serial-dma.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-disable-serial-dma.patch @@ -1,8 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Sun, 14 Jun 2020 22:59:24 +0200 +Subject: [ARCHEOLOGY] [RK3288] Bump rockchip-dev to kernel 5.7 (#2018) + +> X-Git-Archeology: > recovered message: > * Moved rockchip-dev to kernel 5.7, removed already upstreamed patch (1016), adjusted conflicting patch (1015) +> X-Git-Archeology: > recovered message: > Most kernel configuration answer left at default, notables: +> X-Git-Archeology: > recovered message: > - Wireguard (as module) +> X-Git-Archeology: > recovered message: > - Zswap default compression set to LZO +> X-Git-Archeology: > recovered message: > - RK3288 GPIOMEM (as module) +> X-Git-Archeology: > recovered message: > - Enabled some new DMABUF bits (heaps, cmas) +> X-Git-Archeology: > recovered message: > - Hantro driver +> X-Git-Archeology: > recovered message: > - F2FS compression +> X-Git-Archeology: > recovered message: > * Disabled rx/tx dma for uarts, on my board causes system freeze during bluetooth initialization. Don't know if they ever worked, tried to enable them ages ago and they were already not working +> X-Git-Archeology: - Revision 8f9f12065eab021a57bc782916da77348998074f: https://github.com/armbian/build/commit/8f9f12065eab021a57bc782916da77348998074f +> X-Git-Archeology: Date: Sun, 14 Jun 2020 22:59:24 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: [RK3288] Bump rockchip-dev to kernel 5.7 (#2018) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 812245def37a695bce9e7ece148b2920d82c8b37: https://github.com/armbian/build/commit/812245def37a695bce9e7ece148b2920d82c8b37 +> X-Git-Archeology: Date: Sat, 18 Jul 2020 23:07:01 +0200 +> X-Git-Archeology: From: Werner +> X-Git-Archeology: Subject: Move rockchip/64 current to 5.7.y (#2099) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54bc65b3bbd244820d950366523149f1c437223f: https://github.com/armbian/build/commit/54bc65b3bbd244820d950366523149f1c437223f +> X-Git-Archeology: Date: Wed, 17 Feb 2021 01:36:25 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump DEV kernels to 5.11.y (#2636) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 8 -------- + 1 file changed, 8 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 0cd88774d..07681f1f0 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -420,8 +420,6 @@ +@@ -387,8 +387,6 @@ uart0: serial@ff180000 { reg-io-width = <4>; clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; @@ -11,7 +89,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>; status = "disabled"; -@@ -435,8 +433,6 @@ +@@ -402,8 +400,6 @@ uart1: serial@ff190000 { reg-io-width = <4>; clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; clock-names = "baudclk", "apb_pclk"; @@ -20,7 +98,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "disabled"; -@@ -463,8 +459,6 @@ +@@ -430,8 +426,6 @@ uart3: serial@ff1b0000 { reg-io-width = <4>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; @@ -29,7 +107,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart3_xfer>; status = "disabled"; -@@ -478,8 +472,6 @@ +@@ -445,8 +439,6 @@ uart4: serial@ff1c0000 { reg-io-width = <4>; clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; clock-names = "baudclk", "apb_pclk"; @@ -38,3 +116,6 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer>; status = "disabled"; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-fix-mmc-aliases.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-fix-mmc-aliases.patch index dede52866..2e47c0569 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-fix-mmc-aliases.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-fix-mmc-aliases.patch @@ -1,8 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 26 Dec 2023 16:45:30 +0100 +Subject: [ARCHEOLOGY] consolidate rk322x and rockchip 32 bit families + +> X-Git-Archeology: > recovered message: > * merge patches from rockchip and rk322x families for current and edge +> X-Git-Archeology: > recovered message: > kernels +> X-Git-Archeology: > recovered message: > * adjust patches for tinkerboard to remove some cruft and overclocking +> X-Git-Archeology: > recovered message: > * rework kernel configs +> X-Git-Archeology: > recovered message: > * fix rk322x dmc to avoid lockup on rk3288 +> X-Git-Archeology: > recovered message: > * migrate rockchip-6.6 into patch series, rename all patches with +> X-Git-Archeology: > recovered message: > more understandable names +> X-Git-Archeology: > recovered message: > * add gen-series.sh script in tools directory (it is a naive tool to +> X-Git-Archeology: > recovered message: > create patch series when you don't want to rebase everything) +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 511ca864c1b2..d7ecb6b4de40 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -25,10 +25,10 @@ aliases { +@@ -34,10 +34,10 @@ aliases { i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; @@ -17,4 +65,6 @@ index 511ca864c1b2..d7ecb6b4de40 100644 serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; +-- +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch index 6a91d9226..9f15140b8 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch @@ -1,7 +1,7 @@ -From 73258d32daf3a661281bb5c77c5e2e06c7ff714e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Fri, 3 Jul 2020 02:02:18 +0200 -Subject: [PATCH] arm: dtsi: rk3288: add GPU 500 Mhz OPP again +Subject: arm: dtsi: rk3288: add GPU 500 Mhz OPP again Undoing the very bizarre mainline kernel patch, 75481833c6dbab4c29d15452f6b4337c16f5407b @@ -23,10 +23,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index a66412547..ef7457f79 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1312,6 +1312,10 @@ opp-400000000 { +@@ -1354,6 +1354,10 @@ opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1100000>; }; @@ -38,5 +38,5 @@ index a66412547..ef7457f79 100644 opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1250000>; -- -2.27.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-pinctrl-spi2.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-pinctrl-spi2.patch index f34e8fa8e..5ee3b2373 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-pinctrl-spi2.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-pinctrl-spi2.patch @@ -1,7 +1,7 @@ -From 062488e4b8fd552c01e1104b3bc91a6f7ffe6c41 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Thu, 19 Oct 2017 21:24:47 +0200 -Subject: [PATCH 10/28] RK3288: DTSI: rk3288.dtsi: Add missing SPI2 pinctrl +Subject: RK3288: DTSI: rk3288.dtsi: Add missing SPI2 pinctrl The spi2_cs1 pin reference is missing in the spi2 first pin control definition. @@ -14,10 +14,10 @@ Signed-off-by: Myy Miouyouyou 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 5b789528..9ed532cc 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -334,7 +334,7 @@ +@@ -320,7 +320,7 @@ spi2: spi@ff130000 { dma-names = "tx", "rx"; interrupts = ; pinctrl-names = "default"; @@ -27,5 +27,5 @@ index 5b789528..9ed532cc 100644 #address-cells = <1>; #size-cells = <0>; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch index c9ae49db3..f87270bdb 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch @@ -1,8 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tonymac32 +Date: Mon, 18 Sep 2017 15:04:14 +0000 +Subject: [ARCHEOLOGY] Add files via upload + +> X-Git-Archeology: - Revision 3d96c26b0f4d6f94f1be3b42c1599f74a0f93465: https://github.com/armbian/build/commit/3d96c26b0f4d6f94f1be3b42c1599f74a0f93465 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 15:04:14 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: Add files via upload +> X-Git-Archeology: +> X-Git-Archeology: - Revision 97d06e86c19d3d7d73c0a978fbad7d022b915922: https://github.com/armbian/build/commit/97d06e86c19d3d7d73c0a978fbad7d022b915922 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 15:05:37 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: RK3288 get cpu to thermal_zone0 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7ee8ff8e3bd040e4cc02596327b01c5f89dc1027: https://github.com/armbian/build/commit/7ee8ff8e3bd040e4cc02596327b01c5f89dc1027 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 18:09:24 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: rk3288 dtsi thermal zone adjustment +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0d2da12129218170ac244cc8d6fc1b94e6f49089: https://github.com/armbian/build/commit/0d2da12129218170ac244cc8d6fc1b94e6f49089 +> X-Git-Archeology: Date: Sun, 17 Dec 2017 20:33:45 -0500 +> X-Git-Archeology: From: tonymac32 +> X-Git-Archeology: Subject: Re-fix RK3288 Next Thermal Zones +> X-Git-Archeology: +> X-Git-Archeology: - Revision f831a2a014d9305e272fc7541fa7d85f32c7dbab: https://github.com/armbian/build/commit/f831a2a014d9305e272fc7541fa7d85f32c7dbab +> X-Git-Archeology: Date: Mon, 19 Feb 2018 00:30:58 -0500 +> X-Git-Archeology: From: tonymac32 +> X-Git-Archeology: Subject: Rockchip Dev fixup. Boots. +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 3b3d85e25c2ecde30df7b5274fc6f1b9c0299ea2: https://github.com/armbian/build/commit/3b3d85e25c2ecde30df7b5274fc6f1b9c0299ea2 +> X-Git-Archeology: Date: Sat, 22 May 2021 17:08:44 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Upgrade EDGE to 5.12.y (#2825) +> X-Git-Archeology: +> X-Git-Archeology: - Revision e7377248b3cae186e24e2be781cd3365b43246f0: https://github.com/armbian/build/commit/e7377248b3cae186e24e2be781cd3365b43246f0 +> X-Git-Archeology: Date: Thu, 22 Jul 2021 00:15:54 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Second part of EDGE bumping to 5.13.y (#3045) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 14 +++++----- + 1 file changed, 7 insertions(+), 7 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index bc3601a..37ae378 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -467,13 +467,6 @@ +@@ -457,13 +457,6 @@ dmac_peri: dma-controller@ff250000 { }; thermal-zones { @@ -16,7 +110,7 @@ index bc3601a..37ae378 100644 cpu_thermal: cpu-thermal { polling-delay-passive = <100>; /* milliseconds */ polling-delay = <5000>; /* milliseconds */ -@@ -539,6 +532,13 @@ +@@ -535,6 +528,13 @@ map0 { }; }; }; @@ -30,3 +124,6 @@ index bc3601a..37ae378 100644 }; tsadc: tsadc@ff280000 { +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch index e56921406..8dc221cff 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch @@ -1,17 +1,17 @@ -From 87313f95f809fc34f499c1ceff1b95cd4efa0f3f Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 22 Mar 2022 22:02:46 +0000 -Subject: [PATCH] rockchip: add tinkerboard bluetooth +Subject: rockchip: add tinkerboard bluetooth --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 11 +++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index ff2c6de3216..23acfdecee7 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -510,6 +510,17 @@ &tsadc { +@@ -491,6 +491,17 @@ &tsadc { &uart0 { status = "okay"; @@ -30,5 +30,5 @@ index ff2c6de3216..23acfdecee7 100644 &uart1 { -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-uart-pins.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-uart-pins.patch index 50da0ecae..99e9fe274 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-uart-pins.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-bt-uart-pins.patch @@ -1,7 +1,7 @@ -From 2c2e60256f2cbb2fce50a6317f85b1500efd1a6c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 22:03:26 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Setup the Bluetooth UART pins +Subject: ARM: DTS: rk3288-tinker: Setup the Bluetooth UART pins The most essential being the RTS pin, which is clearly needed to upload the initial configuration into the Realtek Bluetooth @@ -44,12 +44,12 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index d4df13bed..b92e59c1e 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -73,3 +73,9 @@ - status = "okay"; - supports-sdio; +@@ -11,3 +11,9 @@ / { + model = "Rockchip RK3288 Asus Tinker Board"; + compatible = "asus,rk3288-tinker", "rockchip,rk3288"; }; + +&uart0 { @@ -58,5 +58,5 @@ index d4df13bed..b92e59c1e 100644 +}; + -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-hevc-rga.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-hevc-rga.patch index a5175c9e5..1c18b53b6 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-hevc-rga.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-hevc-rga.patch @@ -1,18 +1,17 @@ -From 0bcc81848ec1fb34fee9d3c7eb1550495cc8efc9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 18 Sep 2021 12:31:19 +0000 -Subject: [PATCH 1/2] rockchip: enable hevc, hevc_mmu and rga nodes for - tinkerboard (both) +Subject: rockchip: enable hevc, hevc_mmu and rga nodes for tinkerboard (both) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 12 ++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 12 ++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index aa36aedf9..ff2c6de32 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -150,6 +150,14 @@ &hdmi { +@@ -148,6 +148,14 @@ &hdmi { status = "okay"; }; @@ -27,7 +26,7 @@ index aa36aedf9..ff2c6de32 100644 &i2c0 { clock-frequency = <400000>; status = "okay"; -@@ -449,6 +457,10 @@ &pwm0 { +@@ -447,6 +455,10 @@ &pwm0 { status = "okay"; }; @@ -39,5 +38,5 @@ index aa36aedf9..ff2c6de32 100644 vref-supply = <&vcc18_ldo1>; status = "okay"; -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdio-wifi.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdio-wifi.patch index 85974972b..c8e2314fa 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdio-wifi.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdio-wifi.patch @@ -1,7 +1,7 @@ -From d5d5c53173c484a13cda62a537cbf75a5df4b0e4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 21:58:56 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Enabling SDIO and Wifi +Subject: ARM: DTS: rk3288-tinker: Enabling SDIO and Wifi Adding the appropriate nodes in order to exploit the WiFi capabilities of the board. @@ -15,14 +15,14 @@ Split if necessary. Signed-off-by: Miouyouyou (Myy) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 62 +++++++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 62 ++++++++++ 1 file changed, 62 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index 1e43527aa..d4df13bed 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -6,8 +6,70 @@ +@@ -6,10 +6,72 @@ /dts-v1/; #include "rk3288-tinker.dtsi" @@ -93,6 +93,8 @@ index 1e43527aa..d4df13bed 100644 + status = "okay"; + supports-sdio; }; + + &uart0 { -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdmmc-properties.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdmmc-properties.patch index 5486d6018..c55153298 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdmmc-properties.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-sdmmc-properties.patch @@ -1,7 +1,7 @@ -From 487db7cefc9861fdaf30579c378a98f0360690ae Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 20:27:14 +0100 -Subject: [PATCH] ARM: DTSI: rk3288-tinker: Defining SDMMC properties +Subject: ARM: DTSI: rk3288-tinker: Defining SDMMC properties I never knew if these properties were required to fix the dreaded reboot issue... @@ -12,10 +12,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index dd1090728..8edd6f681 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -436,7 +436,12 @@ +@@ -472,7 +472,12 @@ &sdmmc { disable-wp; /* wp not hooked up */ pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; @@ -29,5 +29,5 @@ index dd1090728..8edd6f681 100644 vqmmc-supply = <&vccio_sd>; }; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-spi-interface.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-spi-interface.patch index db2b09b15..4592a28db 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-spi-interface.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-tinkerboard-spi-interface.patch @@ -1,7 +1,7 @@ -From b24b8f83e150811ad54ee2a4843e44cd1421fafa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 22:15:14 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Defining the SPI interface +Subject: ARM: DTS: rk3288-tinker: Defining the SPI interface Taken from, and tested by @TonyMac32 . @@ -12,14 +12,14 @@ Therefore that *might* break, along with a few other patches. Signed-off-by: Miouyouyou (Myy) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 19 +++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 19 ++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index 96d05fc6b..17bfea298 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -99,6 +99,25 @@ +@@ -74,6 +74,25 @@ &sdio0 { supports-sdio; }; @@ -46,5 +46,5 @@ index 96d05fc6b..17bfea298 100644 pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-veyron-flag-cache-flush.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-veyron-flag-cache-flush.patch index 89cb36c0a..ae50fbc2a 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-veyron-flag-cache-flush.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/dts-veyron-flag-cache-flush.patch @@ -1,8 +1,7 @@ -From 9177b30ab083dbda2bede3b3d61ef71ad4b1ffe0 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Thu, 1 Nov 2018 21:31:26 +0100 -Subject: [PATCH 2/2] arm: dts: veyron: Added a flag to disable cache flush - during reset +Subject: arm: dts: veyron: Added a flag to disable cache flush during reset Flushing the MMC cache of ASUS Chromebooks during initialization or "recovery" generates 10 minutes hangup, according to @SolidHal. @@ -16,10 +15,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi -index 2075120cf..fa4951fd7 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi -@@ -123,6 +123,7 @@ +@@ -157,6 +157,7 @@ &emmc { mmc-hs200-1_8v; mmc-pwrseq = <&emmc_pwrseq>; non-removable; @@ -28,5 +27,5 @@ index 2075120cf..fa4951fd7 100644 pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-overlay-configfs.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-overlay-configfs.patch index 0aa88542f..533faaa5a 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-overlay-configfs.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-overlay-configfs.patch @@ -1,3 +1,143 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Ayotte +Date: Wed, 20 Jul 2016 10:56:30 -0400 +Subject: [ARCHEOLOGY] Add ConfigFS for overlays support in v4.6.x + +> X-Git-Archeology: - Revision 7eb8428bb65aedbd9ef506d942a0a7420c8becd6: https://github.com/armbian/build/commit/7eb8428bb65aedbd9ef506d942a0a7420c8becd6 +> X-Git-Archeology: Date: Wed, 20 Jul 2016 10:56:30 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: Add ConfigFS for overlays support in v4.6.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision 12c0a8a81224224d3fd9b487bf2e178fcb0cb9bd: https://github.com/armbian/build/commit/12c0a8a81224224d3fd9b487bf2e178fcb0cb9bd +> X-Git-Archeology: Date: Wed, 20 Jul 2016 11:19:44 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: move the add_configfs_overlay_for_v4.6.x.patch into sun8i-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 536c9d795d9d5fe491795b4fff6bd1676b229688: https://github.com/armbian/build/commit/536c9d795d9d5fe491795b4fff6bd1676b229688 +> X-Git-Archeology: Date: Fri, 22 Jul 2016 17:24:12 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: fix Makefile in add_configfs_overlay_for_v4.6.x.patch +> X-Git-Archeology: +> X-Git-Archeology: - Revision 023b2e10a58d5090d6c1a6e1e34fdf2348900e0a: https://github.com/armbian/build/commit/023b2e10a58d5090d6c1a6e1e34fdf2348900e0a +> X-Git-Archeology: Date: Sun, 24 Jul 2016 16:50:16 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: remove debugging message +> X-Git-Archeology: +> X-Git-Archeology: - Revision a659f1769e5a08e780db9cb7a8aa35a49e90c917: https://github.com/armbian/build/commit/a659f1769e5a08e780db9cb7a8aa35a49e90c917 +> X-Git-Archeology: Date: Fri, 12 Aug 2016 15:13:23 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: add modified ConfigFS patches for kernel 4.8.x in sunxi-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2def4ca6d90a8bba0df71a395ea08d9811169c24: https://github.com/armbian/build/commit/2def4ca6d90a8bba0df71a395ea08d9811169c24 +> X-Git-Archeology: Date: Mon, 09 Jan 2017 10:54:22 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: remove useless part of the patch for 4.10.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision 43f9fe3debf8061be55dc51d0069973a61c707d4: https://github.com/armbian/build/commit/43f9fe3debf8061be55dc51d0069973a61c707d4 +> X-Git-Archeology: Date: Mon, 09 Jan 2017 10:55:14 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: rename patch for 4.10.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision b0fcb64aaca589359338a500e7bc07eb7ca1cb71: https://github.com/armbian/build/commit/b0fcb64aaca589359338a500e7bc07eb7ca1cb71 +> X-Git-Archeology: Date: Thu, 07 Dec 2017 07:09:10 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Temporally disabling broken patches on sunxi DEV branch +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2c08ec8f5a210de35f9482f482ac01ea15381792: https://github.com/armbian/build/commit/2c08ec8f5a210de35f9482f482ac01ea15381792 +> X-Git-Archeology: Date: Thu, 24 May 2018 13:32:29 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Merge sunxi family into stable +> X-Git-Archeology: +> X-Git-Archeology: - Revision 8bc9d032a372ebd1b8f8126e439658a9879789d4: https://github.com/armbian/build/commit/8bc9d032a372ebd1b8f8126e439658a9879789d4 +> X-Git-Archeology: Date: Wed, 27 Jun 2018 11:24:34 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: fix pantoniou configfs using pelwell patch for new OF API +> X-Git-Archeology: +> X-Git-Archeology: - Revision 1a12994e79b6ef173dc58efe4df8919cb6cc7781: https://github.com/armbian/build/commit/1a12994e79b6ef173dc58efe4df8919cb6cc7781 +> X-Git-Archeology: Date: Tue, 17 Jul 2018 15:53:30 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Moving sunxi-next to 4.17.y (#1049) +> X-Git-Archeology: +> X-Git-Archeology: - Revision a57ce78b37f8dd2eb94a3836f4a7f6969f2ffd72: https://github.com/armbian/build/commit/a57ce78b37f8dd2eb94a3836f4a7f6969f2ffd72 +> X-Git-Archeology: Date: Tue, 21 Aug 2018 10:41:10 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Reverting sunxi/sunxi64 NEXT to 4.14. (#1087) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0aec4b058834e16d12ddff68c90ecbed946b19a3: https://github.com/armbian/build/commit/0aec4b058834e16d12ddff68c90ecbed946b19a3 +> X-Git-Archeology: Date: Tue, 04 Dec 2018 15:10:36 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: add configfs for overlay on meson64-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2c439b921988b4f5210866ed484304d804cca60f: https://github.com/armbian/build/commit/2c439b921988b4f5210866ed484304d804cca60f +> X-Git-Archeology: Date: Mon, 30 Dec 2019 21:25:03 +0100 +> X-Git-Archeology: From: Piotr Szczepanik +> X-Git-Archeology: Subject: Overlay configfs support for rockchip64-current (#1699) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 20d17a7c9556b6eb39c2557b4a17fa0181f763fc: https://github.com/armbian/build/commit/20d17a7c9556b6eb39c2557b4a17fa0181f763fc +> X-Git-Archeology: Date: Fri, 19 Jun 2020 09:47:44 +0200 +> X-Git-Archeology: From: m][sko +> X-Git-Archeology: Subject: Switch meson to linux 5.7 (#2024) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7: https://github.com/armbian/build/commit/23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7 +> X-Git-Archeology: Date: Fri, 19 Jun 2020 17:27:27 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Introducing Rockchip RK322X SoC support (#2032) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 1e37959e5381a0a1d1eaf0629cdc19658f30df9a: https://github.com/armbian/build/commit/1e37959e5381a0a1d1eaf0629cdc19658f30df9a +> X-Git-Archeology: Date: Thu, 10 Feb 2022 20:32:58 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bumping sunxi/64, xu4, rockchip and mvebu64 to 5.16.y (#3453) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + Documentation/devicetree/configfs-overlays.txt | 31 + + drivers/of/Kconfig | 7 + + drivers/of/Makefile | 1 + + drivers/of/configfs.c | 290 ++++++++++ + 4 files changed, 329 insertions(+) + +diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt +new file mode 100644 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/configfs-overlays.txt @@ -0,0 +1,31 @@ @@ -33,10 +173,10 @@ +intended to be used by hardware managers in the kernel, while the copy interface +make sense for developers (since it avoids problems with namespaces). diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index 37c2ccbefecdc..d3fc81a40c0e7 100644 +index 111111111111..222222222222 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig -@@ -103,4 +103,11 @@ config OF_OVERLAY +@@ -120,4 +120,11 @@ config OF_OVERLAY_KUNIT_TEST config OF_NUMA bool @@ -49,20 +189,20 @@ index 37c2ccbefecdc..d3fc81a40c0e7 100644 + endif # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index 663a4af0cccd5..b00a95adf5199 100644 +index 111111111111..222222222222 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 - obj-y = base.o device.o platform.o property.o + obj-y = base.o cpu.o device.o module.o platform.o property.o obj-$(CONFIG_OF_KOBJ) += kobj.o +obj-$(CONFIG_OF_CONFIGFS) += configfs.o obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c new file mode 100644 -index 000000000..5dd509e8f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/of/configfs.c @@ -0,0 +1,290 @@ @@ -356,3 +496,6 @@ index 000000000..5dd509e8f + return ret; +} +late_initcall(of_cfs_init); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-restart-handler-for-act8846.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-restart-handler-for-act8846.patch index 055ba8eee..9bf8875eb 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-restart-handler-for-act8846.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-add-restart-handler-for-act8846.patch @@ -1,14 +1,14 @@ -From 7f2d6a02498ce3fa7771893072e81b31f9bd64b2 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Fri, 24 Mar 2023 17:15:16 +0000 -Subject: [PATCH] register act8846 restart handler for SIPC function +Subject: register act8846 restart handler for SIPC function --- - drivers/regulator/act8865-regulator.c | 27 +++++++++++++++++++++++++++ + drivers/regulator/act8865-regulator.c | 27 ++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c -index 53f2c75cd..e45ad8430 100644 +index 111111111111..222222222222 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -20,6 +20,7 @@ @@ -51,7 +51,7 @@ index 53f2c75cd..e45ad8430 100644 static int act8600_charger_get_status(struct regmap *map) { unsigned int val; -@@ -733,6 +752,14 @@ static int act8865_pmic_probe(struct i2c_client *client) +@@ -731,6 +750,14 @@ static int act8865_pmic_probe(struct i2c_client *client) } else { dev_err(dev, "Failed to set poweroff capability, already defined\n"); } @@ -67,5 +67,5 @@ index 53f2c75cd..e45ad8430 100644 /* Finally register devices */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch index bc3a6f296..e906cfb77 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch @@ -1,14 +1,14 @@ -From c046bcccf1ca331cff3b89f09eed080a5407aa5a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 4 Dec 2024 14:32:40 +0100 -Subject: [PATCH] rockchip: fix rk3288 reset-on-wake quirk +Subject: rockchip: fix rk3288 reset-on-wake quirk --- drivers/usb/dwc2/params.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c -index 4d73fae80b12..0109055a9a8e 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -130,7 +130,6 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) @@ -20,5 +20,5 @@ index 4d73fae80b12..0109055a9a8e 100644 static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg) -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-peripheral.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-peripheral.patch index 9a5c933fd..a66a3ee97 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-peripheral.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-peripheral.patch @@ -1,17 +1,17 @@ -From e477f1546f2739e9ea053d677f421e01a9babff4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 2 Mar 2024 21:56:44 +0100 -Subject: [PATCH] dwc2: add fixes for rk322x peripheral mode +Subject: dwc2: add fixes for rk322x peripheral mode --- - drivers/usb/dwc2/core.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) + drivers/usb/dwc2/core.c | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 5635e4d7ec88..0a3d387a497a 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -532,6 +532,9 @@ void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) +@@ -537,6 +537,9 @@ void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) gusbcfg |= set; dwc2_writel(hsotg, gusbcfg, GUSBCFG); @@ -22,5 +22,5 @@ index 5635e4d7ec88..0a3d387a497a 100644 return; } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-time.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-time.patch index f8517ac54..053ef0832 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-time.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-fix-wait-time.patch @@ -1,7 +1,7 @@ -From ee7c3ab6b5a4d284a04f110792508a7f8decd7f7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Wu Date: Tue, 6 Dec 2022 14:45:54 +0800 -Subject: [PATCH] usb: dwc2: fix waiting time for host only mode +Subject: usb: dwc2: fix waiting time for host only mode The current code uses 50ms sleep to wait for host only mode, the delay time is not enough for some Rockchip @@ -20,14 +20,14 @@ mode and increases the maximum waiting time to 200ms. Signed-off-by: William Wu Change-Id: Ie28299934aba09907ea08f5fd3b34bf2fb35822e --- - drivers/usb/dwc2/core.c | 14 ++++++++++++-- + drivers/usb/dwc2/core.c | 14 ++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 15911ac7582b4..cbd5f1142f35e 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -656,14 +656,24 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) +@@ -578,14 +578,24 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) */ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg) { @@ -54,3 +54,6 @@ index 15911ac7582b4..cbd5f1142f35e 100644 break; case USB_DR_MODE_PERIPHERAL: +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-nak-gadget.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-nak-gadget.patch index 1162a96d9..fa57b5c67 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-nak-gadget.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-dwc2-nak-gadget.patch @@ -1,8 +1,7 @@ -From 15b317ff84dc09faa47995b1d973d96a6172fa4c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Wu Date: Thu, 15 Dec 2022 14:19:28 +0800 -Subject: [PATCH] usb: dwc2: gadget: Disable nak interrupt when get first isoc - in token +Subject: usb: dwc2: gadget: Disable nak interrupt when get first isoc in token The dwc2 driver use the nak interrupt for the starting point of isoc-in transfer. The first nak interrupt for isoc-in means @@ -21,14 +20,14 @@ the nak interrupt when get first isoc in token if the feature Signed-off-by: William Wu Change-Id: I99c71a5e0d7903346fd8f71619b6736c3181c0ec --- - drivers/usb/dwc2/gadget.c | 37 +++++++++++++++++++++++++++++++++++-- + drivers/usb/dwc2/gadget.c | 37 +++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c -index e1dc4735a99c..0e185ef474ac 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c -@@ -1402,6 +1402,8 @@ static int dwc2_gadget_set_ep0_desc_chain(struct dwc2_hsotg *hsotg, +@@ -1399,6 +1399,8 @@ static int dwc2_gadget_set_ep0_desc_chain(struct dwc2_hsotg *hsotg, return 0; } @@ -37,7 +36,7 @@ index e1dc4735a99c..0e185ef474ac 100644 static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { -@@ -1518,6 +1520,20 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, +@@ -1519,6 +1521,20 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, if (hs_ep->target_frame != TARGET_FRAME_INITIAL) dwc2_hsotg_start_req(hs, hs_ep, hs_req, false); @@ -58,7 +57,7 @@ index e1dc4735a99c..0e185ef474ac 100644 } return 0; } -@@ -2989,8 +3005,25 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) +@@ -2991,8 +3007,25 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) hs_ep->target_frame = hsotg->frame_number; if (hs_ep->interval > 1) { @@ -86,3 +85,6 @@ index e1dc4735a99c..0e185ef474ac 100644 if (hs_ep->target_frame & 0x1) ctrl |= DXEPCTL_SETODDFR; else +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-fix-reboot-from-kwiboo.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-fix-reboot-from-kwiboo.patch index 088b7ebe8..e867dd3f2 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-fix-reboot-from-kwiboo.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-fix-reboot-from-kwiboo.patch @@ -1,10 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas McKahan +Date: Sun, 17 Feb 2019 23:28:02 -0500 +Subject: [ARCHEOLOGY] [ rockchip-dev ] Add simpler reboot code + +> X-Git-Archeology: > recovered message: > As seen here: https://patchwork.kernel.org/patch/10817217/ +> X-Git-Archeology: > recovered message: > for testing in Dev. @paolosabatino please check TV box. +> X-Git-Archeology: - Revision 2c8ee5a69d023d22c9e3ac99e9fc45ab30751f22: https://github.com/armbian/build/commit/2c8ee5a69d023d22c9e3ac99e9fc45ab30751f22 +> X-Git-Archeology: Date: Sun, 17 Feb 2019 23:28:02 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ rockchip-dev ] Add simpler reboot code +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/mmc/core/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index 5bd58b95d..48ebe081f 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c -@@ -1684,6 +1684,14 @@ void mmc_power_off(struct mmc_host *host) - if (host->ios.power_mode == MMC_POWER_OFF) - return; +@@ -1376,6 +1376,14 @@ void mmc_power_off(struct mmc_host *host) + */ + mmc_delay(host->ios.power_delay_ms); + mmc_set_initial_signal_voltage(host); + @@ -17,3 +68,6 @@ index 5bd58b95d..48ebe081f 100644 mmc_pwrseq_power_off(host); host->ios.clock = 0; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-increase-spdif-dma-burst.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-increase-spdif-dma-burst.patch index 9d3a91b4d..eb32f431f 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-increase-spdif-dma-burst.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-increase-spdif-dma-burst.patch @@ -1,14 +1,14 @@ -From 379651eb82cf5966a40a5b931afc2fa91c6a311d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 12 Jan 2025 12:39:03 +0100 -Subject: [PATCH 2/2] rockchip: increase SPDIF max burst value to maximum +Subject: rockchip: increase SPDIF max burst value to maximum --- sound/soc/rockchip/rockchip_spdif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c -index d87c0e4f6f91..7a2cfecf6a94 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -329,7 +329,7 @@ static int rk_spdif_probe(struct platform_device *pdev) @@ -21,5 +21,5 @@ index d87c0e4f6f91..7a2cfecf6a94 100644 spdif->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, spdif); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-linux-export-mm-trace-rss-stats.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-linux-export-mm-trace-rss-stats.patch index 45c975a46..8cb53a2c5 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-linux-export-mm-trace-rss-stats.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-linux-export-mm-trace-rss-stats.patch @@ -1,24 +1,24 @@ -From 6408e6688b18e5c712c711110d196a4e95f3f870 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 16:37:28 +0000 -Subject: [PATCH 2/4] 01-linux-1000-export-mm_trace_rss_stat +Subject: 01-linux-1000-export-mm_trace_rss_stat --- mm/memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/memory.c b/mm/memory.c -index 25fc46e87..7ef0adaa5 100644 +index 111111111111..222222222222 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -171,6 +171,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member, long count) +@@ -181,6 +181,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member) { - trace_rss_stat(mm, member, count); + trace_rss_stat(mm, member); } +EXPORT_SYMBOL(mm_trace_rss_stat); - #if defined(SPLIT_RSS_COUNTING) - + /* + * Note: this doesn't free the actual pages themselves. That -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-01-fix-periodic-transfers.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-01-fix-periodic-transfers.patch index 844286d43..3d6828ac6 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-01-fix-periodic-transfers.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-01-fix-periodic-transfers.patch @@ -1,14 +1,14 @@ -From fc0d09bf651fcab0998da4d187a91f64df419188 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 12 Jan 2025 12:36:50 +0100 -Subject: [PATCH 1/2] pl330: fix dma engine periodic transfers +Subject: pl330: fix dma engine periodic transfers --- - drivers/dma/pl330.c | 277 +++++++++++++++++++++++++++++--------------- + drivers/dma/pl330.c | 277 +++++++--- 1 file changed, 186 insertions(+), 91 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 82a9fe88ad54..ef197c4cfed4 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -239,6 +239,7 @@ enum pl330_byteswap { @@ -417,5 +417,5 @@ index 82a9fe88ad54..ef197c4cfed4 100644 return &desc->txd; } -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch index 54f0dd913..4b9f8f78b 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch @@ -1,16 +1,16 @@ -From e691c5c3feede95b4e159344aaea070fc428c847 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 23 Jan 2025 20:23:50 +0100 -Subject: [PATCH 1/2] rockchip/64: pl330 - add support for interleaved - transfers +Subject: rockchip/64: pl330 - add support for interleaved transfers original source: https://patchwork.kernel.org/project/linux-rockchip/cover/1712150304-60832-1-git-send-email-sugar.zhang@rock-chips.com/ --- - drivers/dma/pl330.c | 168 ++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 162 insertions(+), 6 deletions(-) + drivers/dma/pl330.c | 168 +++++++++- + include/linux/dmaengine.h | 1 + + 2 files changed, 163 insertions(+), 6 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index ef197c4cfed4..b49a3a6c4686 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -543,6 +543,8 @@ struct dma_pl330_desc { @@ -245,7 +245,7 @@ index ef197c4cfed4..b49a3a6c4686 100644 pd->device_prep_slave_sg = pl330_prep_slave_sg; pd->device_config = pl330_config; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index b137fdb56093..63624c5836cf 100644 +index 111111111111..222222222222 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -156,6 +156,7 @@ struct dma_interleaved_template { @@ -257,5 +257,5 @@ index b137fdb56093..63624c5836cf 100644 struct data_chunk sgl[]; }; -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch index 15b348888..070fc2fb9 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch @@ -1,7 +1,7 @@ -From f695d6bfdd099ec6f59a73aa792b97df80c72d54 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 26 Jan 2025 14:49:18 +0100 -Subject: [PATCH] increase pl330 microcode buffer size +Subject: increase pl330 microcode buffer size suggestion comes from the scatter/gather functionality as proposed here: https://github.com/radxa/kernel/commit/ec0b65dbc59793426b6dc7af06ab6675f4a24940 @@ -10,10 +10,10 @@ proposed here: https://github.com/radxa/kernel/commit/ec0b65dbc59793426b6dc7af06 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 82a9fe88ad54..eb322c7ae5de 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c -@@ -246,7 +246,7 @@ enum pl330_byteswap { +@@ -247,7 +247,7 @@ enum pl330_byteswap { * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req * should be enough for P<->M and M<->M respectively. */ @@ -23,5 +23,5 @@ index 82a9fe88ad54..eb322c7ae5de 100644 /* Use this _only_ to wait on transient states */ #define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch index c9a44f75f..2b79e7bca 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch @@ -1,7 +1,7 @@ -From 05cc2b4fba887e3da543952311b009bacc87cee8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Sat, 26 Mar 2022 18:01:21 +0800 -Subject: [PATCH] dmaengine: pl330: Fix unbalanced runtime PM +Subject: dmaengine: pl330: Fix unbalanced runtime PM This driver use runtime PM autosuspend mechanism to manager clk. @@ -64,10 +64,10 @@ Signed-off-by: Sugar Zhang 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 6dca548f4dab1..f87729ace4f5b 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c -@@ -2086,7 +2086,7 @@ static void pl330_tasklet(struct tasklet_struct *t) +@@ -2274,7 +2274,7 @@ static void pl330_tasklet(struct tasklet_struct *t) spin_lock(&pch->thread->dmac->lock); _stop(pch->thread); spin_unlock(&pch->thread->dmac->lock); @@ -76,3 +76,6 @@ index 6dca548f4dab1..f87729ace4f5b 100644 pch->active = false; } else { /* Make sure the PL330 Channel thread is active */ +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-06-fix-buffer-underruns.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-06-fix-buffer-underruns.patch index 1215a00c9..3755bf0a7 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-06-fix-buffer-underruns.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-pl330-06-fix-buffer-underruns.patch @@ -1,7 +1,7 @@ -From 4acf270a6310f5e2dbadac1d5f21d8e7477fade6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 16 Feb 2025 11:15:55 +0100 -Subject: [PATCH] pl330: fix buffer underrun with cyclic dma +Subject: pl330: fix buffer underrun with cyclic dma userspace applications (notably, pulseaudio) were suffering frequent buffer underruns when cyclic DMA @@ -10,11 +10,11 @@ the buffer underruns avoiding to juggle with the descriptor state, keeping it in BUSY state as long as it is actual transfer is progressing. --- - drivers/dma/pl330.c | 24 ++++++++++++------------ + drivers/dma/pl330.c | 24 +++++----- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 208e2a089a4d..6dac00995765 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1737,11 +1737,11 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err) @@ -34,7 +34,7 @@ index 208e2a089a4d..6dac00995765 100644 tasklet_schedule(&pch->task); } -@@ -2256,23 +2256,23 @@ static void pl330_tasklet(struct tasklet_struct *t) +@@ -2248,23 +2248,23 @@ static void pl330_tasklet(struct tasklet_struct *t) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) { @@ -66,5 +66,5 @@ index 208e2a089a4d..6dac00995765 100644 /* Try to submit a req imm. next to the last completed cookie */ -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rk322x-gpio-ir-driver.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rk322x-gpio-ir-driver.patch index 46fafb06c..3ca97ba71 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rk322x-gpio-ir-driver.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rk322x-gpio-ir-driver.patch @@ -1,20 +1,19 @@ -From 13498feb91614d59ebece61d0c278e31529bb8c8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 10 Oct 2023 21:54:51 +0200 -Subject: [PATCH] rockchip gpio IR driver +Subject: rockchip gpio IR driver --- - drivers/media/rc/Kconfig | 11 + + drivers/media/rc/Kconfig | 10 + drivers/media/rc/Makefile | 1 + - drivers/media/rc/rockchip-ir.c | 723 +++++++++++++++++++++++++++++++++ - 3 files changed, 735 insertions(+) - create mode 100644 drivers/media/rc/rockchip-ir.c + drivers/media/rc/rockchip-ir.c | 733 ++++++++++ + 3 files changed, 744 insertions(+) diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 2afe67ffa285..0fd671f5873c 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig -@@ -338,6 +338,16 @@ config IR_REDRAT3 +@@ -339,6 +339,16 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. @@ -32,7 +31,7 @@ index 2afe67ffa285..0fd671f5873c 100644 tristate "Homebrew Serial Port Receiver" depends on HAS_IOPORT diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index 2bca6f7f07bc..2ec037f8b939 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_IR_MTK) += mtk-cir.o @@ -45,7 +44,7 @@ index 2bca6f7f07bc..2ec037f8b939 100644 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o diff --git a/drivers/media/rc/rockchip-ir.c b/drivers/media/rc/rockchip-ir.c new file mode 100644 -index 000000000000..43ade8c4adce +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/rockchip-ir.c @@ -0,0 +1,733 @@ @@ -782,5 +781,6 @@ index 000000000000..43ade8c4adce + +MODULE_DESCRIPTION("Rockchip IR Receiver driver"); +MODULE_LICENSE("GPL v2"); - +-- +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rockchip-various-fixes.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rockchip-various-fixes.patch index 00d644bde..736f8b632 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rockchip-various-fixes.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/general-rockchip-various-fixes.patch @@ -1,21 +1,20 @@ -From 92a42b2df843c0f6c2937dc6bdbfe72332c9e557 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 16:46:33 +0000 -Subject: [PATCH 3/4] 01-linux-1000-rockchip-wip +Subject: 01-linux-1000-rockchip-wip --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 101 +++++++++++++++++- - arch/arm/boot/dts/rockchip/rk3xxx.dtsi | 2 + - drivers/clk/rockchip/clk-rk3228.c | 61 ++++------- - drivers/net/ethernet/arc/emac.h | 14 +++ - drivers/net/ethernet/arc/emac_main.c | 81 ++++++++++++-- - drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++++- - drivers/pmdomain/rockchip/pm-domains.c | 23 ++++ - drivers/usb/dwc2/core.c | 2 +- - 8 files changed, 266 insertions(+), 56 deletions(-) + arch/arm/boot/dts/rockchip/rk322x.dtsi | 85 +++++++++- + arch/arm/boot/dts/rockchip/rk3xxx.dtsi | 2 + + drivers/clk/rockchip/clk-rk3228.c | 61 +++---- + drivers/net/ethernet/arc/emac.h | 14 ++ + drivers/net/ethernet/arc/emac_main.c | 61 +++++++ + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++- + drivers/pmdomain/rockchip/pm-domains.c | 23 +++ + 7 files changed, 239 insertions(+), 45 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 831561fc1814..24e963b01d87 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -19,6 +19,7 @@ aliases { @@ -26,7 +25,7 @@ index 831561fc1814..24e963b01d87 100644 serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; -@@ -132,6 +149,17 @@ display_subsystem: display-subsystem { +@@ -136,6 +137,17 @@ display_subsystem: display-subsystem { ports = <&vop_out>; }; @@ -44,7 +43,7 @@ index 831561fc1814..24e963b01d87 100644 i2s1: i2s1@100b0000 { compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100b0000 0x4000>; -@@ -142,6 +170,7 @@ i2s1: i2s1@100b0000 { +@@ -146,6 +158,7 @@ i2s1: i2s1@100b0000 { dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&i2s1_bus>; @@ -52,7 +51,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -153,6 +182,7 @@ i2s0: i2s0@100c0000 { +@@ -166,6 +179,7 @@ i2s0: i2s0@100c0000 { clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; dmas = <&pdma 11>, <&pdma 12>; dma-names = "tx", "rx"; @@ -60,7 +59,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -166,6 +196,7 @@ spdif: spdif@100d0000 { +@@ -179,6 +193,7 @@ spdif: spdif@100d0000 { dma-names = "tx"; pinctrl-names = "default"; pinctrl-0 = <&spdif_tx>; @@ -68,7 +67,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -337,7 +368,7 @@ uart2: serial@11030000 { +@@ -350,7 +365,7 @@ uart2: serial@11030000 { clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; @@ -77,7 +76,7 @@ index 831561fc1814..24e963b01d87 100644 reg-shift = <2>; reg-io-width = <4>; status = "disabled"; -@@ -358,6 +389,10 @@ efuse_id: id@7 { +@@ -371,6 +386,10 @@ efuse_id: id@7 { cpu_leakage: cpu_leakage@17 { reg = <0x17 0x1>; }; @@ -88,7 +87,7 @@ index 831561fc1814..24e963b01d87 100644 }; i2c0: i2c@11050000 { -@@ -554,6 +589,11 @@ map1 { +@@ -569,6 +588,11 @@ map1 { <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; @@ -100,7 +99,7 @@ index 831561fc1814..24e963b01d87 100644 }; }; }; -@@ -584,6 +624,8 @@ hdmi_phy: hdmi-phy@12030000 { +@@ -599,6 +623,8 @@ hdmi_phy: hdmi-phy@12030000 { clock-names = "sysclk", "refoclk", "refpclk"; #clock-cells = <0>; clock-output-names = "hdmiphy_phy"; @@ -109,7 +108,7 @@ index 831561fc1814..24e963b01d87 100644 #phy-cells = <0>; status = "disabled"; }; -@@ -607,7 +649,27 @@ gpu: gpu@20000000 { +@@ -622,7 +648,27 @@ gpu: gpu@20000000 { clock-names = "bus", "core"; power-domains = <&power RK3228_PD_GPU>; resets = <&cru SRST_GPU_A>; @@ -138,7 +137,7 @@ index 831561fc1814..24e963b01d87 100644 }; vpu: video-codec@20020000 { -@@ -727,6 +789,7 @@ hdmi: hdmi@200a0000 { +@@ -753,6 +799,7 @@ hdmi: hdmi@200a0000 { phys = <&hdmi_phy>; phy-names = "hdmi"; rockchip,grf = <&grf>; @@ -146,7 +145,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; ports { -@@ -748,9 +811,13 @@ sdmmc: mmc@30000000 { +@@ -780,9 +827,13 @@ sdmmc: mmc@30000000 { clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; @@ -161,7 +160,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -760,10 +827,14 @@ sdio: mmc@30010000 { +@@ -792,10 +843,14 @@ sdio: mmc@30010000 { interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; @@ -176,7 +175,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -771,14 +842,13 @@ emmc: mmc@30020000 { +@@ -803,14 +858,13 @@ emmc: mmc@30020000 { compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x30020000 0x4000>; interrupts = ; @@ -192,7 +191,7 @@ index 831561fc1814..24e963b01d87 100644 pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; resets = <&cru SRST_EMMC>; -@@ -1029,6 +1099,10 @@ sdmmc_bus4: sdmmc-bus4 { +@@ -1077,6 +1131,10 @@ sdmmc_bus4: sdmmc-bus4 { <1 RK_PC4 1 &pcfg_pull_none_drv_12ma>, <1 RK_PC5 1 &pcfg_pull_none_drv_12ma>; }; @@ -203,7 +202,7 @@ index 831561fc1814..24e963b01d87 100644 }; sdio { -@@ -1261,13 +1335,30 @@ uart1_xfer: uart1-xfer { +@@ -1368,13 +1426,30 @@ uart1_xfer: uart1-xfer { <1 RK_PB2 1 &pcfg_pull_none>; }; @@ -235,10 +234,10 @@ index 831561fc1814..24e963b01d87 100644 uart2 { diff --git a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi -index 616a828e0..f233b7a77 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi -@@ -64,6 +64,8 @@ L2: cache-controller@10138000 { +@@ -68,6 +68,8 @@ L2: cache-controller@10138000 { reg = <0x10138000 0x1000>; cache-unified; cache-level = <2>; @@ -248,10 +247,10 @@ index 616a828e0..f233b7a77 100644 scu@1013c000 { diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index aca1a483a..7250adc64 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -135,24 +135,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { +@@ -131,24 +131,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; @@ -278,7 +277,7 @@ index aca1a483a..7250adc64 100644 PNAME(mux_dclk_vop_p) = { "hdmiphy", "sclk_vop_pre" }; PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; -@@ -221,27 +219,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -217,27 +215,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), /* PD_DDR */ @@ -313,7 +312,7 @@ index aca1a483a..7250adc64 100644 COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 1, GFLAGS), -@@ -258,14 +252,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -254,14 +248,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_MISC_CON, 15, 1, MFLAGS), /* PD_BUS */ @@ -330,7 +329,7 @@ index aca1a483a..7250adc64 100644 GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, -@@ -338,14 +327,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -334,14 +323,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(3), 8, GFLAGS), /* PD_PERI */ @@ -347,7 +346,7 @@ index aca1a483a..7250adc64 100644 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK2928_CLKSEL_CON(10), 12, 3, DFLAGS, RK2928_CLKGATE_CON(5), 2, GFLAGS), -@@ -380,7 +364,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -376,7 +360,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(10), 12, GFLAGS), COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, @@ -356,7 +355,7 @@ index aca1a483a..7250adc64 100644 RK2928_CLKGATE_CON(2), 15, GFLAGS), COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, -@@ -403,12 +387,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -397,12 +381,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ @@ -371,7 +370,7 @@ index aca1a483a..7250adc64 100644 DIV(DCLK_HDMI_PHY, "dclk_hdmiphy", "sclk_vop_src", 0, RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, -@@ -640,13 +621,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -634,13 +615,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), @@ -388,7 +387,7 @@ index aca1a483a..7250adc64 100644 }; static const char *const rk3228_critical_clocks[] __initconst = { -@@ -661,6 +642,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -655,6 +636,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { "aclk_vop_noc", "aclk_hdcp_noc", "hclk_vio_ahb_arbi", @@ -396,7 +395,7 @@ index aca1a483a..7250adc64 100644 "hclk_vio_noc", "hclk_vop_noc", "hclk_host0_arb", -@@ -678,10 +660,13 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -672,10 +654,13 @@ static const char *const rk3228_critical_clocks[] __initconst = { "pclk_ddrphy", "pclk_acodecphy", "pclk_phy_noc", @@ -411,7 +410,7 @@ index aca1a483a..7250adc64 100644 static void __init rk3228_clk_init(struct device_node *np) diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h -index d820ae03a..0ac87288b 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/arc/emac.h +++ b/drivers/net/ethernet/arc/emac.h @@ -91,6 +91,20 @@ struct arc_emac_bd { @@ -436,10 +435,10 @@ index d820ae03a..0ac87288b 100644 * struct buffer_state - Stores Rx/Tx buffer state. * @sk_buff: Pointer to socket buffer. diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c -index 67b8113a2..40332a976 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c -@@ -850,6 +850,62 @@ static const struct net_device_ops arc_emac_netdev_ops = { +@@ -855,6 +855,62 @@ static const struct net_device_ops arc_emac_netdev_ops = { #endif }; @@ -502,7 +501,7 @@ index 67b8113a2..40332a976 100644 int arc_emac_probe(struct net_device *ndev, int interface) { struct device *dev = ndev->dev.parent; -@@ -970,6 +1026,11 @@ int arc_emac_probe(struct net_device *ndev, int interface) +@@ -975,6 +1031,11 @@ int arc_emac_probe(struct net_device *ndev, int interface) goto out_clken; } @@ -515,10 +514,10 @@ index 67b8113a2..40332a976 100644 interface); if (!phydev) { diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -index 1889e78e1..6209f51b3 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -237,6 +237,9 @@ struct inno_hdmi_phy { +@@ -236,6 +236,9 @@ struct inno_hdmi_phy { struct clk *refoclk; struct clk *refpclk; @@ -528,7 +527,7 @@ index 1889e78e1..6209f51b3 100644 /* platform data */ const struct inno_hdmi_phy_drv_data *plat_data; int chip_version; -@@ -471,6 +474,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { +@@ -470,6 +473,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { static const struct post_pll_config post_pll_cfg_table[] = { {33750000, 1, 40, 8, 1}, {33750000, 1, 80, 8, 2}, @@ -536,7 +535,7 @@ index 1889e78e1..6209f51b3 100644 {74250000, 1, 40, 8, 1}, {74250000, 18, 80, 8, 2}, {148500000, 2, 40, 4, 3}, -@@ -621,8 +625,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) +@@ -620,8 +624,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) return -EINVAL; for (; cfg->tmdsclock != 0; cfg++) @@ -550,7 +549,7 @@ index 1889e78e1..6209f51b3 100644 break; for (; phy_cfg->tmdsclock != 0; phy_cfg++) -@@ -1033,6 +1040,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) +@@ -1032,6 +1039,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) { @@ -561,7 +560,7 @@ index 1889e78e1..6209f51b3 100644 /* * Use phy internal register control * rxsense/poweron/pllpd/pdataen signal. -@@ -1047,7 +1058,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) +@@ -1046,7 +1057,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL, RK3228_POST_PLL_CTRL_MANUAL); @@ -590,7 +589,7 @@ index 1889e78e1..6209f51b3 100644 return 0; } -@@ -1147,6 +1179,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) +@@ -1146,6 +1178,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) /* try to read the chip-version */ inno->chip_version = 1; @@ -600,10 +599,10 @@ index 1889e78e1..6209f51b3 100644 if (IS_ERR(cell)) { if (PTR_ERR(cell) == -EPROBE_DEFER) diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index fddb4022c..9583c76b4 100644 +index 111111111111..222222222222 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -73,6 +73,7 @@ struct rockchip_pm_domain { +@@ -91,6 +91,7 @@ struct rockchip_pm_domain { struct regmap **qos_regmap; u32 *qos_save_regs[MAX_QOS_REGS_NUM]; int num_clks; @@ -611,7 +610,7 @@ index fddb4022c..9583c76b4 100644 struct clk_bulk_data *clks; }; -@@ -361,6 +362,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) +@@ -637,6 +638,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) { struct rockchip_pm_domain *pd = to_rockchip_pd(domain); @@ -621,7 +620,7 @@ index fddb4022c..9583c76b4 100644 return rockchip_pd_power(pd, true); } -@@ -368,6 +372,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) +@@ -644,6 +648,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) { struct rockchip_pm_domain *pd = to_rockchip_pd(domain); @@ -631,7 +630,7 @@ index fddb4022c..9583c76b4 100644 return rockchip_pd_power(pd, false); } -@@ -447,6 +454,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, +@@ -726,6 +733,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, pd->info = pd_info; pd->pmu = pmu; @@ -641,15 +640,15 @@ index fddb4022c..9583c76b4 100644 pd->num_clks = of_clk_get_parent_count(node); if (pd->num_clks > 0) { pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, -@@ -600,6 +610,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, +@@ -871,6 +881,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, + struct device_node *parent) { - struct device_node *np; struct generic_pm_domain *child_domain, *parent_domain; + struct rockchip_pm_domain *child_pd, *parent_pd; int error; - for_each_child_of_node(parent, np) { -@@ -640,6 +651,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, + for_each_child_of_node_scoped(parent, np) { +@@ -911,6 +922,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, parent_domain->name, child_domain->name); } @@ -669,6 +668,5 @@ index fddb4022c..9583c76b4 100644 } -- -2.25.1 - +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-rk322x-box.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-rk322x-box.patch index 2c10b95bc..fca18ac02 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-rk322x-box.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-rk322x-box.patch @@ -1,30 +1,29 @@ -From f14539f8d08328ae5aad165a4deea25c7d6b09bf Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Mon, 25 Apr 2022 13:25:09 +0000 -Subject: [PATCH] add generic rk322x tv box remote controller keymap +Subject: add generic rk322x tv box remote controller keymap --- drivers/media/rc/keymaps/Makefile | 1 + - drivers/media/rc/keymaps/rc-rk322x-tvbox.c | 74 ++++++++++++++++++++++ + drivers/media/rc/keymaps/rc-rk322x-tvbox.c | 74 ++++++++++ include/media/rc-map.h | 1 + - 3 files changed, 77 insertions(+) - create mode 100644 drivers/media/rc/keymaps/rc-rk322x-tvbox.c + 3 files changed, 76 insertions(+) diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index 5fe5c9e1a46..1aa49b78a65 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile -@@ -99,6 +99,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ +@@ -106,6 +106,7 @@ obj-$(CONFIG_RC_MAP) += \ rc-rc6-mce.o \ rc-real-audio-220-32-keys.o \ rc-reddo.o \ + rc-rk322x-tvbox.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ - rc-tanix-tx3mini.o \ + rc-su3000.o \ diff --git a/drivers/media/rc/keymaps/rc-rk322x-tvbox.c b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c new file mode 100644 -index 00000000000..91e24ee52ee +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c @@ -0,0 +1,74 @@ @@ -103,10 +102,10 @@ index 00000000000..91e24ee52ee +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Paolo Sabatino"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index 793b54342df..35aba84be9f 100644 +index 111111111111..222222222222 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h -@@ -310,6 +310,7 @@ struct rc_map *rc_map_get(const char *name); +@@ -313,6 +313,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_RC6_MCE "rc-rc6-mce" #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" #define RC_MAP_REDDO "rc-reddo" @@ -115,5 +114,5 @@ index 793b54342df..35aba84be9f 100644 #define RC_MAP_STREAMZAP "rc-streamzap" #define RC_MAP_SU3000 "rc-su3000" -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-xt-q8l-v10.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-xt-q8l-v10.patch index eb4faa632..a261215d5 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-xt-q8l-v10.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/ir-keymap-xt-q8l-v10.patch @@ -10,10 +10,10 @@ Subject: add xt-q8l-v10 keymap and makefile 3 files changed, 78 insertions(+) diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index f513ff5caf4e..198ef8bc2614 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile -@@ -136,4 +136,5 @@ obj-$(CONFIG_RC_MAP) += \ +@@ -140,4 +140,5 @@ obj-$(CONFIG_RC_MAP) += \ rc-x96max.o \ rc-xbox-360.o \ rc-xbox-dvd.o \ @@ -21,7 +21,7 @@ index f513ff5caf4e..198ef8bc2614 100644 rc-zx-irdec.o diff --git a/drivers/media/rc/keymaps/rc-xt-q8l-v10.c b/drivers/media/rc/keymaps/rc-xt-q8l-v10.c new file mode 100644 -index 000000000000..19c7d9ec8325 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-xt-q8l-v10.c @@ -0,0 +1,76 @@ @@ -102,10 +102,10 @@ index 000000000000..19c7d9ec8325 +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Paolo Sabatino"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index 793b54342dff..ef7f3710eafe 100644 +index 111111111111..222222222222 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h -@@ -343,6 +343,7 @@ struct rc_map *rc_map_get(const char *name); +@@ -347,6 +347,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_X96MAX "rc-x96max" #define RC_MAP_XBOX_360 "rc-xbox-360" #define RC_MAP_XBOX_DVD "rc-xbox-dvd" diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/misc-tinkerboard-spi-interface.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/misc-tinkerboard-spi-interface.patch index f3a1f6b83..9b1a9a4b4 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/misc-tinkerboard-spi-interface.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/misc-tinkerboard-spi-interface.patch @@ -1,8 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 27 Apr 2023 21:31:27 +0200 +Subject: [ARCHEOLOGY] rockchip: bump edge kernel to 6.3 + +> X-Git-Archeology: - Revision da0ab48b7939235608c8fc042c61ae997681e865: https://github.com/armbian/build/commit/da0ab48b7939235608c8fc042c61ae997681e865 +> X-Git-Archeology: Date: Thu, 27 Apr 2023 21:31:27 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.3 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/spi/spidev.c | 2 ++ + 1 file changed, 2 insertions(+) + diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 5a038c667401..5dd1acf7f12a 100644 +index 111111111111..222222222222 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c -@@ -713,6 +713,7 @@ static const struct spi_device_id spidev_spi_ids[] = { +@@ -711,6 +711,7 @@ static const struct spi_device_id spidev_spi_ids[] = { { .name = "spi-authenta" }, { .name = "em3581" }, { .name = "si3210" }, @@ -18,3 +67,6 @@ index 5a038c667401..5dd1acf7f12a 100644 {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch index 77385b14b..1283047c3 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch @@ -1,7 +1,7 @@ -From 302cd9b8a9f1f8a7735fabea3b9a7645dc40f9cc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Sun, 7 Jan 2018 01:52:44 +0100 -Subject: [PATCH] drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot +Subject: drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot On ASUS Tinkerboard systems, if the SDMMC hardware is shutdown before rebooting, the system will be dead, as the SDMMC is the only way to @@ -17,14 +17,14 @@ similar effects with eMMC hardware. Signed-off-by: Myy Miouyouyou --- - drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++++++++++++++++++++++++++++++ + drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c -index a3f1c2b30..7eac1f221 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c -@@ -16,6 +16,11 @@ +@@ -12,6 +12,11 @@ #include #include @@ -36,7 +36,7 @@ index a3f1c2b30..7eac1f221 100644 #include "dw_mmc.h" #include "dw_mmc-pltfm.h" -@@ -334,6 +339,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = { +@@ -527,6 +532,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = { }; MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); @@ -103,7 +103,7 @@ index a3f1c2b30..7eac1f221 100644 static int dw_mci_rockchip_probe(struct platform_device *pdev) { const struct dw_mci_drv_data *drv_data; -@@ -361,6 +426,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) +@@ -554,6 +619,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) } pm_runtime_put_autosuspend(&pdev->dev); @@ -112,5 +112,5 @@ index a3f1c2b30..7eac1f221 100644 return 0; } -- -2.14.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch index ed7158039..dc2f1cfa3 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch @@ -1,17 +1,17 @@ -From e039790fb29227f646e91e6d7ec7c3e89c584243 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 6 Jul 2021 14:21:52 +0000 -Subject: [PATCH 1/5] rk3228/rk3328: fix ddr clock gate, add SIP v2 calls +Subject: rk3228/rk3328: fix ddr clock gate, add SIP v2 calls --- - drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++++ - drivers/clk/rockchip/clk-rk3228.c | 14 ++-- + drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++ + drivers/clk/rockchip/clk-rk3228.c | 14 +- drivers/clk/rockchip/clk-rk3328.c | 7 +- drivers/clk/rockchip/clk.h | 3 +- 4 files changed, 143 insertions(+), 11 deletions(-) diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c -index 86718c54e..b16b3795f 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = { @@ -159,10 +159,10 @@ index 86718c54e..b16b3795f 100644 pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); kfree(ddrclk); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 1f9176a5c..96393aa16 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -218,9 +218,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -215,9 +215,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), /* PD_DDR */ @@ -175,7 +175,7 @@ index 1f9176a5c..96393aa16 100644 GATE(0, "ddrphy4x", "clk_ddrphy_src", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 1, GFLAGS), FACTOR_GATE(0, "ddrc", "clk_ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, -@@ -576,8 +576,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -571,8 +571,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), @@ -186,7 +186,7 @@ index 1f9176a5c..96393aa16 100644 GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), -@@ -652,8 +652,8 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -647,8 +647,8 @@ static const char *const rk3228_critical_clocks[] __initconst = { "sclk_initmem_mbist", "aclk_initmem", "hclk_rom", @@ -198,10 +198,10 @@ index 1f9176a5c..96393aa16 100644 "pclk_stimer", "pclk_ddrphy", diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c -index cc18dbc18..5fdd611bb 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3328.c +++ b/drivers/clk/rockchip/clk-rk3328.c -@@ -317,9 +317,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { +@@ -315,9 +315,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { RK3328_CLKGATE_CON(14), 1, GFLAGS), /* PD_DDR */ @@ -216,10 +216,10 @@ index cc18dbc18..5fdd611bb 100644 RK3328_CLKGATE_CON(18), 6, GFLAGS), GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h -index ae059b774..fdaa81ebb 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h -@@ -363,7 +363,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, +@@ -539,7 +539,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, * DDRCLK flags, including method of setting the rate * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. */ @@ -230,5 +230,5 @@ index ae059b774..fdaa81ebb 100644 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, const char *const *parent_names, -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch index efeaace36..3ef432f3c 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch @@ -1,16 +1,15 @@ -From 95358ea4a4434ad4af5545b3f762508e4f015fc3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 6 Jul 2021 14:23:36 +0000 -Subject: [PATCH 2/5] rk3228/rk3328: add ddr clock and SIP related constants - and defines +Subject: rk3228/rk3328: add ddr clock and SIP related constants and defines --- include/dt-bindings/clock/rk3228-cru.h | 1 + - include/soc/rockchip/rockchip_sip.h | 24 ++++++++++++++++++++++++ + include/soc/rockchip/rockchip_sip.h | 24 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h -index de550ea56..911824731 100644 +index 111111111111..222222222222 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -15,6 +15,7 @@ @@ -22,7 +21,7 @@ index de550ea56..911824731 100644 #define SCLK_NANDC 67 #define SCLK_SDMMC 68 diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h -index c46a9ae2a..34e653751 100644 +index 111111111111..222222222222 100644 --- a/include/soc/rockchip/rockchip_sip.h +++ b/include/soc/rockchip/rockchip_sip.h @@ -6,6 +6,7 @@ @@ -63,5 +62,5 @@ index c46a9ae2a..34e653751 100644 #endif -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch index b1b3aa8a5..f9779f337 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch @@ -1,22 +1,20 @@ -From de9678fab28f23bdc3969cdea397f4057d42ba5a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 11 Jan 2024 20:42:48 +0100 -Subject: [PATCH] add rk3228/rk3328 to rockchip dfi driver +Subject: add rk3228/rk3328 to rockchip dfi driver --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 7 +++ - drivers/devfreq/event/rockchip-dfi.c | 77 +++++++++++++++++++++++--- - include/soc/rockchip/rk3228_grf.h | 14 +++++ - include/soc/rockchip/rk3328_grf.h | 14 +++++ + arch/arm/boot/dts/rockchip/rk322x.dtsi | 7 + + drivers/devfreq/event/rockchip-dfi.c | 77 +++++++++- + include/soc/rockchip/rk3228_grf.h | 14 ++ + include/soc/rockchip/rk3328_grf.h | 14 ++ 4 files changed, 105 insertions(+), 7 deletions(-) - create mode 100644 include/soc/rockchip/rk3228_grf.h - create mode 100644 include/soc/rockchip/rk3328_grf.h diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 571626d879f8..e87096b97610 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -208,6 +208,13 @@ xin24m: oscillator { +@@ -132,6 +132,13 @@ xin24m: oscillator { #clock-cells = <0>; }; @@ -31,7 +29,7 @@ index 571626d879f8..e87096b97610 100644 compatible = "rockchip,display-subsystem"; ports = <&vop_out>; diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c -index e2a1e4463b6f..fba3a958b352 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/event/rockchip-dfi.c +++ b/drivers/devfreq/event/rockchip-dfi.c @@ -24,6 +24,8 @@ @@ -51,7 +49,7 @@ index e2a1e4463b6f..fba3a958b352 100644 struct regmap *regmap_pmu; struct clk *clk; int usecount; -@@ -669,6 +672,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) +@@ -673,6 +676,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) } #endif @@ -98,7 +96,7 @@ index e2a1e4463b6f..fba3a958b352 100644 static int rk3399_dfi_init(struct rockchip_dfi *dfi) { struct regmap *regmap_pmu = dfi->regmap_pmu; -@@ -757,6 +800,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) +@@ -762,6 +805,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) }; static const struct of_device_id rockchip_dfi_id_match[] = { @@ -107,7 +105,7 @@ index e2a1e4463b6f..fba3a958b352 100644 { .compatible = "rockchip,rk3399-dfi", .data = rk3399_dfi_init }, { .compatible = "rockchip,rk3568-dfi", .data = rk3568_dfi_init }, { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init }, -@@ -786,14 +831,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -791,14 +836,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (IS_ERR(dfi->regs)) return PTR_ERR(dfi->regs); @@ -145,7 +143,7 @@ index e2a1e4463b6f..fba3a958b352 100644 dfi->dev = dev; mutex_init(&dfi->mutex); -@@ -818,6 +879,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -823,6 +884,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (ret) return ret; @@ -156,7 +154,7 @@ index e2a1e4463b6f..fba3a958b352 100644 return 0; diff --git a/include/soc/rockchip/rk3228_grf.h b/include/soc/rockchip/rk3228_grf.h new file mode 100644 -index 000000000000..e37406814fad +index 000000000000..111111111111 --- /dev/null +++ b/include/soc/rockchip/rk3228_grf.h @@ -0,0 +1,14 @@ @@ -176,7 +174,7 @@ index 000000000000..e37406814fad +#endif diff --git a/include/soc/rockchip/rk3328_grf.h b/include/soc/rockchip/rk3328_grf.h new file mode 100644 -index 000000000000..bf6d209be7e6 +index 000000000000..111111111111 --- /dev/null +++ b/include/soc/rockchip/rk3328_grf.h @@ -0,0 +1,14 @@ @@ -195,5 +193,5 @@ index 000000000000..bf6d209be7e6 + +#endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-04-driver.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-04-driver.patch index 3039f9291..34c20921c 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-04-driver.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dmc-driver-04-driver.patch @@ -1,22 +1,19 @@ -From 8529e1141bf84ff4e0120eeb42e45a59c8e666c7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 27 Dec 2023 15:29:29 +0100 -Subject: [PATCH] rockchip: add rk3228 dmc driver +Subject: rockchip: add rk3228 dmc driver --- arch/arm/boot/dts/rockchip/rk322x.dtsi | 70 +- drivers/devfreq/Kconfig | 12 + drivers/devfreq/Makefile | 1 + - drivers/devfreq/rk3228_dmc.c | 696 +++++++++++++++++++ - include/dt-bindings/clock/rockchip-ddr.h | 63 ++ - include/dt-bindings/memory/rockchip,rk322x.h | 90 +++ - 6 files changed, 929 insertions(+), 3 deletions(-) - create mode 100644 drivers/devfreq/rk3228_dmc.c - create mode 100644 include/dt-bindings/clock/rockchip-ddr.h - create mode 100644 include/dt-bindings/memory/rockchip,rk322x.h + drivers/devfreq/rk3228_dmc.c | 827 ++++++++++ + include/dt-bindings/clock/rockchip-ddr.h | 63 + + include/dt-bindings/memory/rockchip,rk322x.h | 90 + + 6 files changed, 1060 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 41374aff62c8..c9d71a776587 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -7,6 +7,8 @@ @@ -28,8 +25,8 @@ index 41374aff62c8..c9d71a776587 100644 / { #address-cells = <1>; -@@ -104,6 +106,68 @@ dfi: dfi@11210000 { - status = "okay"; +@@ -101,6 +103,68 @@ opp-1200000000 { + }; }; + dmc: dmc@11200000 { @@ -97,7 +94,7 @@ index 41374aff62c8..c9d71a776587 100644 arm-pmu { compatible = "arm,cortex-a7-pmu"; interrupts = , -@@ -676,17 +740,17 @@ gpu_opp_table: opp-table2 { +@@ -664,17 +728,17 @@ gpu_opp_table: opp-table2 { opp-200000000 { opp-hz = /bits/ 64 <200000000>; @@ -119,7 +116,7 @@ index 41374aff62c8..c9d71a776587 100644 }; diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig -index 3c4862a752b5..066be239a16a 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -129,6 +129,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ @@ -142,7 +139,7 @@ index 3c4862a752b5..066be239a16a 100644 tristate "ARM RK3399 DMC DEVFREQ Driver" depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile -index bf40d04928d0..059712bfe5f5 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o @@ -153,174 +150,9 @@ index bf40d04928d0..059712bfe5f5 100644 obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-mbus.o obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o -diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h -new file mode 100644 -index 000000000000..b065432e7793 ---- /dev/null -+++ b/include/dt-bindings/clock/rockchip-ddr.h -@@ -0,0 +1,63 @@ -+/* -+ * -+ * Copyright (C) 2017 ROCKCHIP, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H -+#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H -+ -+#define DDR2_DEFAULT (0) -+ -+#define DDR3_800D (0) /* 5-5-5 */ -+#define DDR3_800E (1) /* 6-6-6 */ -+#define DDR3_1066E (2) /* 6-6-6 */ -+#define DDR3_1066F (3) /* 7-7-7 */ -+#define DDR3_1066G (4) /* 8-8-8 */ -+#define DDR3_1333F (5) /* 7-7-7 */ -+#define DDR3_1333G (6) /* 8-8-8 */ -+#define DDR3_1333H (7) /* 9-9-9 */ -+#define DDR3_1333J (8) /* 10-10-10 */ -+#define DDR3_1600G (9) /* 8-8-8 */ -+#define DDR3_1600H (10) /* 9-9-9 */ -+#define DDR3_1600J (11) /* 10-10-10 */ -+#define DDR3_1600K (12) /* 11-11-11 */ -+#define DDR3_1866J (13) /* 10-10-10 */ -+#define DDR3_1866K (14) /* 11-11-11 */ -+#define DDR3_1866L (15) /* 12-12-12 */ -+#define DDR3_1866M (16) /* 13-13-13 */ -+#define DDR3_2133K (17) /* 11-11-11 */ -+#define DDR3_2133L (18) /* 12-12-12 */ -+#define DDR3_2133M (19) /* 13-13-13 */ -+#define DDR3_2133N (20) /* 14-14-14 */ -+#define DDR3_DEFAULT (21) -+#define DDR_DDR2 (22) -+#define DDR_LPDDR (23) -+#define DDR_LPDDR2 (24) -+ -+#define DDR4_1600J (0) /* 10-10-10 */ -+#define DDR4_1600K (1) /* 11-11-11 */ -+#define DDR4_1600L (2) /* 12-12-12 */ -+#define DDR4_1866L (3) /* 12-12-12 */ -+#define DDR4_1866M (4) /* 13-13-13 */ -+#define DDR4_1866N (5) /* 14-14-14 */ -+#define DDR4_2133N (6) /* 14-14-14 */ -+#define DDR4_2133P (7) /* 15-15-15 */ -+#define DDR4_2133R (8) /* 16-16-16 */ -+#define DDR4_2400P (9) /* 15-15-15 */ -+#define DDR4_2400R (10) /* 16-16-16 */ -+#define DDR4_2400U (11) /* 18-18-18 */ -+#define DDR4_DEFAULT (12) -+ -+#define PAUSE_CPU_STACK_SIZE 16 -+ -+#endif -diff --git a/include/dt-bindings/memory/rockchip,rk322x.h b/include/dt-bindings/memory/rockchip,rk322x.h -new file mode 100644 -index 000000000000..1ab3317d700e ---- /dev/null -+++ b/include/dt-bindings/memory/rockchip,rk322x.h -@@ -0,0 +1,90 @@ -+/* -+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H -+#define _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H -+ -+#define DDR3_DS_34ohm (1 << 1) -+#define DDR3_DS_40ohm (0x0) -+ -+#define LP2_DS_34ohm (0x1) -+#define LP2_DS_40ohm (0x2) -+#define LP2_DS_48ohm (0x3) -+#define LP2_DS_60ohm (0x4) -+#define LP2_DS_68_6ohm (0x5)/* optional */ -+#define LP2_DS_80ohm (0x6) -+#define LP2_DS_120ohm (0x7)/* optional */ -+ -+#define LP3_DS_34ohm (0x1) -+#define LP3_DS_40ohm (0x2) -+#define LP3_DS_48ohm (0x3) -+#define LP3_DS_60ohm (0x4) -+#define LP3_DS_80ohm (0x6) -+#define LP3_DS_34D_40U (0x9) -+#define LP3_DS_40D_48U (0xa) -+#define LP3_DS_34D_48U (0xb) -+ -+#define DDR3_ODT_DIS (0) -+#define DDR3_ODT_40ohm ((1 << 2) | (1 << 6)) -+#define DDR3_ODT_60ohm (1 << 2) -+#define DDR3_ODT_120ohm (1 << 6) -+ -+#define LP3_ODT_DIS (0) -+#define LP3_ODT_60ohm (1) -+#define LP3_ODT_120ohm (2) -+#define LP3_ODT_240ohm (3) -+ -+#define PHY_DDR3_RON_RTT_DISABLE (0) -+#define PHY_DDR3_RON_RTT_451ohm (1) -+#define PHY_DDR3_RON_RTT_225ohm (2) -+#define PHY_DDR3_RON_RTT_150ohm (3) -+#define PHY_DDR3_RON_RTT_112ohm (4) -+#define PHY_DDR3_RON_RTT_90ohm (5) -+#define PHY_DDR3_RON_RTT_75ohm (6) -+#define PHY_DDR3_RON_RTT_64ohm (7) -+#define PHY_DDR3_RON_RTT_56ohm (16) -+#define PHY_DDR3_RON_RTT_50ohm (17) -+#define PHY_DDR3_RON_RTT_45ohm (18) -+#define PHY_DDR3_RON_RTT_41ohm (19) -+#define PHY_DDR3_RON_RTT_37ohm (20) -+#define PHY_DDR3_RON_RTT_34ohm (21) -+#define PHY_DDR3_RON_RTT_33ohm (22) -+#define PHY_DDR3_RON_RTT_30ohm (23) -+#define PHY_DDR3_RON_RTT_28ohm (24) -+#define PHY_DDR3_RON_RTT_26ohm (25) -+#define PHY_DDR3_RON_RTT_25ohm (26) -+#define PHY_DDR3_RON_RTT_23ohm (27) -+#define PHY_DDR3_RON_RTT_22ohm (28) -+#define PHY_DDR3_RON_RTT_21ohm (29) -+#define PHY_DDR3_RON_RTT_20ohm (30) -+#define PHY_DDR3_RON_RTT_19ohm (31) -+ -+#define PHY_LP23_RON_RTT_DISABLE (0) -+#define PHY_LP23_RON_RTT_480ohm (1) -+#define PHY_LP23_RON_RTT_240ohm (2) -+#define PHY_LP23_RON_RTT_160ohm (3) -+#define PHY_LP23_RON_RTT_120ohm (4) -+#define PHY_LP23_RON_RTT_96ohm (5) -+#define PHY_LP23_RON_RTT_80ohm (6) -+#define PHY_LP23_RON_RTT_68ohm (7) -+#define PHY_LP23_RON_RTT_60ohm (16) -+#define PHY_LP23_RON_RTT_53ohm (17) -+#define PHY_LP23_RON_RTT_48ohm (18) -+#define PHY_LP23_RON_RTT_43ohm (19) -+#define PHY_LP23_RON_RTT_40ohm (20) -+#define PHY_LP23_RON_RTT_37ohm (21) -+#define PHY_LP23_RON_RTT_34ohm (22) -+#define PHY_LP23_RON_RTT_32ohm (23) -+#define PHY_LP23_RON_RTT_30ohm (24) -+#define PHY_LP23_RON_RTT_28ohm (25) -+#define PHY_LP23_RON_RTT_26ohm (26) -+#define PHY_LP23_RON_RTT_25ohm (27) -+#define PHY_LP23_RON_RTT_24ohm (28) -+#define PHY_LP23_RON_RTT_22ohm (29) -+#define PHY_LP23_RON_RTT_21ohm (30) -+#define PHY_LP23_RON_RTT_20ohm (31) -+ -+#endif /* _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H */ diff --git a/drivers/devfreq/rk3228_dmc.c b/drivers/devfreq/rk3228_dmc.c new file mode 100644 -index 000000000000..1dbf53043f69 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/devfreq/rk3228_dmc.c @@ -0,0 +1,827 @@ @@ -1151,5 +983,171 @@ index 000000000000..1dbf53043f69 +MODULE_AUTHOR("Lin Huang "); +MODULE_AUTHOR("Paolo Sabatino "); +MODULE_DESCRIPTION("RK3228 dmcfreq driver with devfreq framework"); +diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/dt-bindings/clock/rockchip-ddr.h +@@ -0,0 +1,63 @@ ++/* ++ * ++ * Copyright (C) 2017 ROCKCHIP, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++ ++#define DDR2_DEFAULT (0) ++ ++#define DDR3_800D (0) /* 5-5-5 */ ++#define DDR3_800E (1) /* 6-6-6 */ ++#define DDR3_1066E (2) /* 6-6-6 */ ++#define DDR3_1066F (3) /* 7-7-7 */ ++#define DDR3_1066G (4) /* 8-8-8 */ ++#define DDR3_1333F (5) /* 7-7-7 */ ++#define DDR3_1333G (6) /* 8-8-8 */ ++#define DDR3_1333H (7) /* 9-9-9 */ ++#define DDR3_1333J (8) /* 10-10-10 */ ++#define DDR3_1600G (9) /* 8-8-8 */ ++#define DDR3_1600H (10) /* 9-9-9 */ ++#define DDR3_1600J (11) /* 10-10-10 */ ++#define DDR3_1600K (12) /* 11-11-11 */ ++#define DDR3_1866J (13) /* 10-10-10 */ ++#define DDR3_1866K (14) /* 11-11-11 */ ++#define DDR3_1866L (15) /* 12-12-12 */ ++#define DDR3_1866M (16) /* 13-13-13 */ ++#define DDR3_2133K (17) /* 11-11-11 */ ++#define DDR3_2133L (18) /* 12-12-12 */ ++#define DDR3_2133M (19) /* 13-13-13 */ ++#define DDR3_2133N (20) /* 14-14-14 */ ++#define DDR3_DEFAULT (21) ++#define DDR_DDR2 (22) ++#define DDR_LPDDR (23) ++#define DDR_LPDDR2 (24) ++ ++#define DDR4_1600J (0) /* 10-10-10 */ ++#define DDR4_1600K (1) /* 11-11-11 */ ++#define DDR4_1600L (2) /* 12-12-12 */ ++#define DDR4_1866L (3) /* 12-12-12 */ ++#define DDR4_1866M (4) /* 13-13-13 */ ++#define DDR4_1866N (5) /* 14-14-14 */ ++#define DDR4_2133N (6) /* 14-14-14 */ ++#define DDR4_2133P (7) /* 15-15-15 */ ++#define DDR4_2133R (8) /* 16-16-16 */ ++#define DDR4_2400P (9) /* 15-15-15 */ ++#define DDR4_2400R (10) /* 16-16-16 */ ++#define DDR4_2400U (11) /* 18-18-18 */ ++#define DDR4_DEFAULT (12) ++ ++#define PAUSE_CPU_STACK_SIZE 16 ++ ++#endif +diff --git a/include/dt-bindings/memory/rockchip,rk322x.h b/include/dt-bindings/memory/rockchip,rk322x.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/dt-bindings/memory/rockchip,rk322x.h +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H ++#define _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H ++ ++#define DDR3_DS_34ohm (1 << 1) ++#define DDR3_DS_40ohm (0x0) ++ ++#define LP2_DS_34ohm (0x1) ++#define LP2_DS_40ohm (0x2) ++#define LP2_DS_48ohm (0x3) ++#define LP2_DS_60ohm (0x4) ++#define LP2_DS_68_6ohm (0x5)/* optional */ ++#define LP2_DS_80ohm (0x6) ++#define LP2_DS_120ohm (0x7)/* optional */ ++ ++#define LP3_DS_34ohm (0x1) ++#define LP3_DS_40ohm (0x2) ++#define LP3_DS_48ohm (0x3) ++#define LP3_DS_60ohm (0x4) ++#define LP3_DS_80ohm (0x6) ++#define LP3_DS_34D_40U (0x9) ++#define LP3_DS_40D_48U (0xa) ++#define LP3_DS_34D_48U (0xb) ++ ++#define DDR3_ODT_DIS (0) ++#define DDR3_ODT_40ohm ((1 << 2) | (1 << 6)) ++#define DDR3_ODT_60ohm (1 << 2) ++#define DDR3_ODT_120ohm (1 << 6) ++ ++#define LP3_ODT_DIS (0) ++#define LP3_ODT_60ohm (1) ++#define LP3_ODT_120ohm (2) ++#define LP3_ODT_240ohm (3) ++ ++#define PHY_DDR3_RON_RTT_DISABLE (0) ++#define PHY_DDR3_RON_RTT_451ohm (1) ++#define PHY_DDR3_RON_RTT_225ohm (2) ++#define PHY_DDR3_RON_RTT_150ohm (3) ++#define PHY_DDR3_RON_RTT_112ohm (4) ++#define PHY_DDR3_RON_RTT_90ohm (5) ++#define PHY_DDR3_RON_RTT_75ohm (6) ++#define PHY_DDR3_RON_RTT_64ohm (7) ++#define PHY_DDR3_RON_RTT_56ohm (16) ++#define PHY_DDR3_RON_RTT_50ohm (17) ++#define PHY_DDR3_RON_RTT_45ohm (18) ++#define PHY_DDR3_RON_RTT_41ohm (19) ++#define PHY_DDR3_RON_RTT_37ohm (20) ++#define PHY_DDR3_RON_RTT_34ohm (21) ++#define PHY_DDR3_RON_RTT_33ohm (22) ++#define PHY_DDR3_RON_RTT_30ohm (23) ++#define PHY_DDR3_RON_RTT_28ohm (24) ++#define PHY_DDR3_RON_RTT_26ohm (25) ++#define PHY_DDR3_RON_RTT_25ohm (26) ++#define PHY_DDR3_RON_RTT_23ohm (27) ++#define PHY_DDR3_RON_RTT_22ohm (28) ++#define PHY_DDR3_RON_RTT_21ohm (29) ++#define PHY_DDR3_RON_RTT_20ohm (30) ++#define PHY_DDR3_RON_RTT_19ohm (31) ++ ++#define PHY_LP23_RON_RTT_DISABLE (0) ++#define PHY_LP23_RON_RTT_480ohm (1) ++#define PHY_LP23_RON_RTT_240ohm (2) ++#define PHY_LP23_RON_RTT_160ohm (3) ++#define PHY_LP23_RON_RTT_120ohm (4) ++#define PHY_LP23_RON_RTT_96ohm (5) ++#define PHY_LP23_RON_RTT_80ohm (6) ++#define PHY_LP23_RON_RTT_68ohm (7) ++#define PHY_LP23_RON_RTT_60ohm (16) ++#define PHY_LP23_RON_RTT_53ohm (17) ++#define PHY_LP23_RON_RTT_48ohm (18) ++#define PHY_LP23_RON_RTT_43ohm (19) ++#define PHY_LP23_RON_RTT_40ohm (20) ++#define PHY_LP23_RON_RTT_37ohm (21) ++#define PHY_LP23_RON_RTT_34ohm (22) ++#define PHY_LP23_RON_RTT_32ohm (23) ++#define PHY_LP23_RON_RTT_30ohm (24) ++#define PHY_LP23_RON_RTT_28ohm (25) ++#define PHY_LP23_RON_RTT_26ohm (26) ++#define PHY_LP23_RON_RTT_25ohm (27) ++#define PHY_LP23_RON_RTT_24ohm (28) ++#define PHY_LP23_RON_RTT_22ohm (29) ++#define PHY_LP23_RON_RTT_21ohm (30) ++#define PHY_LP23_RON_RTT_20ohm (31) ++ ++#endif /* _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H */ -- -2.34.1 +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dwc2-no-clock-gating.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dwc2-no-clock-gating.patch index c5c290d43..5d5aae0ce 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dwc2-no-clock-gating.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-dwc2-no-clock-gating.patch @@ -1,9 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 5 Mar 2024 20:08:38 +0100 +Subject: [ARCHEOLOGY] rockchip: add patches to fix peripheral mode + +> X-Git-Archeology: > recovered message: > rk322x has peripheral mode that is not working +> X-Git-Archeology: > recovered message: > really well, add various non-upstream patches +> X-Git-Archeology: > recovered message: > and timing adjustments that makes things a bit +> X-Git-Archeology: > recovered message: > more usable (mass storage and ethernet works, +> X-Git-Archeology: > recovered message: > uac isn't) +> X-Git-Archeology: - Revision 55836c60740bbf6f602216360f5ea785675153d2: https://github.com/armbian/build/commit/55836c60740bbf6f602216360f5ea785675153d2 +> X-Git-Archeology: Date: Tue, 05 Mar 2024 20:08:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: add patches to fix peripheral mode +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/usb/dwc2/params.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c -index a937eadbc9b3..f1f6f6afe7fe 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c -@@ -133,6 +133,14 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) - p->no_clock_gating = true; +@@ -132,6 +132,14 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) + p->hird_threshold_en = false; } +static void dwc2_set_rk3228_params(struct dwc2_hsotg *hsotg) @@ -17,7 +61,7 @@ index a937eadbc9b3..f1f6f6afe7fe 100644 static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg) { struct dwc2_core_params *p = &hsotg->params; -@@ -314,6 +322,7 @@ const struct of_device_id dwc2_of_match_table[] = { +@@ -313,6 +321,7 @@ const struct of_device_id dwc2_of_match_table[] = { { .compatible = "ingenic,x1830-otg", .data = dwc2_set_x1600_params }, { .compatible = "ingenic,x2000-otg", .data = dwc2_set_x2000_params }, { .compatible = "rockchip,rk3066-usb", .data = dwc2_set_rk_params }, @@ -25,3 +69,6 @@ index a937eadbc9b3..f1f6f6afe7fe 100644 { .compatible = "lantiq,danube-usb", .data = &dwc2_set_ltq_danube_params }, { .compatible = "lantiq,ase-usb", .data = &dwc2_set_ltq_ase_params }, { .compatible = "lantiq,arx100-usb", .data = &dwc2_set_ltq_ase_params }, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-usb-reset-props.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-usb-reset-props.patch index 81deaa758..60e8c32ca 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-usb-reset-props.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/rk322x-usb-reset-props.patch @@ -1,7 +1,7 @@ -From 6668d12fd4a628299ffbf89794b6f7f67416e3fa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 4 May 2024 15:12:43 +0200 -Subject: [PATCH] add reset props to usb otg/ehci ports +Subject: add reset props to usb otg/ehci ports usb resets are needed in case u-boot does its own reset of the devices, otherwise ports are left in a @@ -18,10 +18,10 @@ always detected also in case of timeout) 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 03d9baddcbab..17c5f0a8fcf3 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -807,6 +807,8 @@ usb_otg: usb@30040000 { +@@ -972,6 +972,8 @@ usb_otg: usb@30040000 { g-tx-fifo-size = <256 128 128 64 32 16>; phys = <&u2phy0_otg>; phy-names = "usb2-phy"; @@ -30,7 +30,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -817,6 +819,8 @@ usb_host0_ehci: usb@30080000 { +@@ -982,6 +984,8 @@ usb_host0_ehci: usb@30080000 { clocks = <&cru HCLK_HOST0>, <&u2phy0>; phys = <&u2phy0_host>; phy-names = "usb"; @@ -39,7 +39,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -837,6 +841,8 @@ usb_host1_ehci: usb@300c0000 { +@@ -1002,6 +1006,8 @@ usb_host1_ehci: usb@300c0000 { clocks = <&cru HCLK_HOST1>, <&u2phy1>; phys = <&u2phy1_otg>; phy-names = "usb"; @@ -48,7 +48,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -857,6 +863,8 @@ usb_host2_ehci: usb@30100000 { +@@ -1022,6 +1028,8 @@ usb_host2_ehci: usb@30100000 { clocks = <&cru HCLK_HOST2>, <&u2phy1>; phys = <&u2phy1_host>; phy-names = "usb"; @@ -58,10 +58,10 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 }; diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 5635e4d7ec88..1e20aabc2033 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -413,7 +413,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) +@@ -418,7 +418,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) if (!(gotgctl & GOTGCTL_CONID_B) || (gusbcfg & GUSBCFG_FORCEHOSTMODE)) { @@ -71,5 +71,5 @@ index 5635e4d7ec88..1e20aabc2033 100644 } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch index 17b44a5f3..2358ba05c 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch @@ -1,21 +1,93 @@ -FROM: Solidhal - -This patch reverses commit 2b721118b7821107757eb1d37af4b60e877b27e7, as can bee seen here: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b721118b7821107757eb1d37af4b60e877b27e7 - -This commit caused issues on veyron speedy with ath9k and dwc2 drivers. Any ath9k device (ar9271) -would intermittently work, most of the time ending in errors as can bee seen here: -https://github.com/SolidHal/PrawnOS/issues/38 -This commit fixes that issue. -This is only a temporary work around while a permenant fix is found, as this commit seems to only cause issues -with dwc2 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas McKahan +Date: Fri, 25 Jan 2019 00:21:49 -0500 +Subject: [ARCHEOLOGY] [ rockchip-dev ] update patchset, target 5.0 RC +> X-Git-Archeology: > recovered message: > Includes experimental video decoder driver. Thanks as always to @miouyouyou for the base patches +> X-Git-Archeology: - Revision 5a0d83a316e19a3df6a6fd1f8bb536a88ca8e924: https://github.com/armbian/build/commit/5a0d83a316e19a3df6a6fd1f8bb536a88ca8e924 +> X-Git-Archeology: Date: Fri, 25 Jan 2019 00:21:49 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ rockchip-dev ] update patchset, target 5.0 RC +> X-Git-Archeology: +> X-Git-Archeology: - Revision 9afdc70340c4492ad0c1db9ace45e094d0c56df5: https://github.com/armbian/build/commit/9afdc70340c4492ad0c1db9ace45e094d0c56df5 +> X-Git-Archeology: Date: Wed, 08 May 2019 09:42:55 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: [ rockchip dev ] move to 5.1.y and adjust patches false permissions, add new patch to remove broken boards +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 9020803f1d17314db0931c50ef25d2bd15542817: https://github.com/armbian/build/commit/9020803f1d17314db0931c50ef25d2bd15542817 +> X-Git-Archeology: Date: Sun, 28 Jun 2020 17:13:32 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Update kernel configs due to logo support, adjust patches +> X-Git-Archeology: +> X-Git-Archeology: - Revision f86c6b313828b356a41afa6f5ef92dbcace0bb5c: https://github.com/armbian/build/commit/f86c6b313828b356a41afa6f5ef92dbcace0bb5c +> X-Git-Archeology: Date: Thu, 03 Sep 2020 21:37:23 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Moving Rockchip 32bit to 5.8.y (#2183) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision c0001d566b3770dae722c47180dcb942bed7006a: https://github.com/armbian/build/commit/c0001d566b3770dae722c47180dcb942bed7006a +> X-Git-Archeology: Date: Wed, 14 Dec 2022 01:43:31 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump bcm, imx, mvebu64 and xu4 EDGE to 6.1.y (#4560) +> X-Git-Archeology: +> X-Git-Archeology: - Revision cb3226dfa320e6359a1c11c3744e67ec50a6e69f: https://github.com/armbian/build/commit/cb3226dfa320e6359a1c11c3744e67ec50a6e69f +> X-Git-Archeology: Date: Tue, 24 Jan 2023 20:56:00 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit to kernel 6.1 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 38 +++++++--- + 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c -index 3f563e02d..903851481 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c -@@ -118,10 +118,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, +@@ -116,10 +116,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, cmd->skb = skb; cmd->hif_dev = hif_dev; @@ -29,7 +101,7 @@ index 3f563e02d..903851481 100644 usb_anchor_urb(urb, &hif_dev->regout_submitted); ret = usb_submit_urb(urb, GFP_KERNEL); -@@ -735,11 +735,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) +@@ -778,11 +778,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) rx_buf->skb = skb; @@ -44,7 +116,7 @@ index 3f563e02d..903851481 100644 } resubmit: -@@ -944,11 +944,11 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) +@@ -995,11 +995,11 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) rx_buf->hif_dev = hif_dev; rx_buf->skb = skb; @@ -59,7 +131,7 @@ index 3f563e02d..903851481 100644 /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->reg_in_submitted); -@@ -1069,7 +1069,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) +@@ -1120,7 +1120,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { @@ -70,7 +142,7 @@ index 3f563e02d..903851481 100644 ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { -@@ -1079,6 +1081,20 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) +@@ -1130,6 +1132,20 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) return ret; } @@ -91,7 +163,7 @@ index 3f563e02d..903851481 100644 /* Alloc URBs */ ret = ath9k_hif_usb_alloc_urbs(hif_dev); if (ret) { -@@ -1353,7 +1369,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) +@@ -1418,7 +1434,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) if (!buf) return; @@ -100,3 +172,6 @@ index 3f563e02d..903851481 100644 buf, 4, NULL, USB_MSG_TIMEOUT); if (ret) dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-add-bcm43342.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-add-bcm43342.patch index e0307dc9c..9b91b3f14 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-add-bcm43342.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-add-bcm43342.patch @@ -9,7 +9,7 @@ Subject: add broadcom bcm43342 chip id 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -index 6b38d9de71af..6a603d045103 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -609,6 +609,7 @@ BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); @@ -29,7 +29,7 @@ index 6b38d9de71af..6a603d045103 100644 BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -index 44684bf1b9ac..bcf48de78d53 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h @@ -27,6 +27,7 @@ diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch index affb86e4e..796ef3b11 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch @@ -1,10 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Thu, 22 Nov 2018 07:04:19 +0100 +Subject: [ARCHEOLOGY] Add rk3288 xt-q8l-v10 CSC board (#1158) + +> X-Git-Archeology: > recovered message: > This merge request contains various files which add support for xt-q8l-v10 boards (TVBox) equipped with Rockchip RK3288 SoC, AP6330 WiSoC (BCM4330 WiFi + Bluetooth), 2 GB DRAM (LPDDR2 or DDR3), 8 Gb eMMC, Gigabit Ethernet, 3 USB (1 OTG), 1 microSD slot, SPDIF optical output, 1 HDMI. +> X-Git-Archeology: > recovered message: > Kernel patches: +> X-Git-Archeology: > recovered message: > This thouches all three linux-rockchip-* kernelconfigs, just adds brcmfmac and brcmutil modules and remote controller support. default flavor activates rockchip own remote controller driver, next and dev use the mainline GPIO CIR driver (dev has lirc userland support activated too). +> X-Git-Archeology: > recovered message: > About the remote controller, an additional kernel module is added to the existing keymaps which is activated via device tree. +> X-Git-Archeology: > recovered message: > About possibly clashing patches assert-phy-reset-when-waking-up-in-rk3288-platform.patch should be checked against other rk3288 boards because it addresses an errata in rk3288 which causes the USB Host ports to stop responding when exiting from autosleep. On my device if I connect the first USB device when the system is already running, the USB Host gets stuck without this patch. Probably to work correctly on other platforms the device tree should include the proper reset lines of the USB PHYs (for reference, check patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch starting from line 869). +> X-Git-Archeology: > recovered message: > Patch 1-2-regulator-act8865-add-restart-handler-for-act8846.patch adds a restart handler which allows reboot using SIPC bit on act8846 power regulator. Possibly MiQi board is affected (is reboot working there?), others (tinkerboard) should not care. +> X-Git-Archeology: > recovered message: > Patch brcmfmac-add-ap6330-firmware.patch adds firmware file names for ap6330 , should be harmless in other cases. +> X-Git-Archeology: > recovered message: > Patch 0010-GPU-Mali-Midgard-remove-rcu_read_lock-references.patch is from Miouyouyou. It should be harmless, it was suggested by him to do some tests with devfreq +> X-Git-Archeology: > recovered message: > Other patches just add the proper device trees, Kconfig and bits for supporting the board as a regular kernel supported board and should not interfere with anything else +> X-Git-Archeology: > recovered message: > U-Boot patches: +> X-Git-Archeology: > recovered message: > All the patches for u-boot are per-board, so nothing is added which may interfere with other existing boards here. They include the device tree and u-boot config and also a couple of patches to support the silergy power regulators driving current to CPU and GPU +> X-Git-Archeology: > recovered message: > * Initial commit to provide kernel and u-boot configuration and device trees for xt-q8-v10 as patches +> X-Git-Archeology: > recovered message: > Modification to rockchip config to add initialization bits for xt-q8-v10 +> X-Git-Archeology: > recovered message: > * Committing correct path for rk3288_ddr_400Mhz... rockchip blob, moved assembling into another section to produce +> X-Git-Archeology: > recovered message: > immediately an u-boot working binary +> X-Git-Archeology: > recovered message: > * Enabled broadcom fmac driver in rockchip-next config +> X-Git-Archeology: > recovered message: > * Changed name definition of rk3288-xt-q8-v10 board to "TVBox" +> X-Git-Archeology: > recovered message: > Added bits to include support AP6330 and binary firmwares into the final image +> X-Git-Archeology: > recovered message: > * Fixed device tree file name in related patch, added patching of Makefile to produce the device tree binary accordingly +> X-Git-Archeology: > recovered message: > * Fixed xt-q8-v10 device tree patch +> X-Git-Archeology: > recovered message: > Added brcmfmac driver to rockchip dev and default kernel configs +> X-Git-Archeology: > recovered message: > * Syncing with upstream +> X-Git-Archeology: > recovered message: > * Splitted add-xt-q8... kernel patches into two separate patches +> X-Git-Archeology: > recovered message: > * Fixed bad extension while adding dtb in makefile for rockchip-default configuration +> X-Git-Archeology: > recovered message: > Updated device tree patches for all rockchip confs +> X-Git-Archeology: > recovered message: > * Enable mmc0 and usb in u-boot config +> X-Git-Archeology: > recovered message: > Fixed again makefile patch for kernel next +> X-Git-Archeology: > recovered message: > * Adding patches to reset the USB phy when kernel requires a reset, fixes autosuspend issue +> X-Git-Archeology: > recovered message: > * Changed xt-q8-v10 to proper xt-q8l-v10 in every string and every filename +> X-Git-Archeology: > recovered message: > Added power hold to u-boot, so now the device will boot and stay turned on without the need for the OTG cable anymore +> X-Git-Archeology: > recovered message: > * Changed names from 'Q8' to proper 'XT-Q8L-V10' in device tree patch files +> X-Git-Archeology: > recovered message: > * Legacy kernel device tree: +> X-Git-Archeology: > recovered message: > Fixed bluetooth gpio pin clashing +> X-Git-Archeology: > recovered message: > Fixed HDMI gpio pin clashing +> X-Git-Archeology: > recovered message: > Added support for PWM-based IR-Receiver, added driver in kernel default config too +> X-Git-Archeology: > recovered message: > Various other fixes to avoid some complaints from the kernel +> X-Git-Archeology: > recovered message: > * Added booting bluetooth systemd service for AP6330 (xt-q8l-v10) that loads patchram and invokes hciattach +> X-Git-Archeology: > recovered message: > Minor fixes to -next and -dev device trees for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > * Disabled OTG USB port in u-boot due to long timeout during initialization +> X-Git-Archeology: > recovered message: > Fixed warning during u-boot dts compilation +> X-Git-Archeology: > recovered message: > Added emmc as second boot device in dts +> X-Git-Archeology: > recovered message: > * Adding myself to licensing +> X-Git-Archeology: > recovered message: > * Committing modifications to device trees +> X-Git-Archeology: > recovered message: > * Fixed dmac_bus_s explicitly set to unused dmac, restored right dmac in xt-q8l-v10 dts only +> X-Git-Archeology: > recovered message: > Change PLL_CPLL frequency in device tree to 408 Mhz to avoid fractional divisor warnings +> X-Git-Archeology: > recovered message: > * Added proper xt-q8l-v10_rk3288 configuration to u-boot, now appearing in config menu and +> X-Git-Archeology: > recovered message: > correctly selectable as a real target +> X-Git-Archeology: > recovered message: > Fixed typo in device tree from rockchip +> X-Git-Archeology: > recovered message: > * Fixed missing semicolon in device tree for default configuration +> X-Git-Archeology: > recovered message: > Fixed patch files for u-boot appending themselves to files on each compilation +> X-Git-Archeology: > recovered message: > * Added bits to enable power to USB ports in u-boot, thus enabling booting from USB devices (only USB host port for now) +> X-Git-Archeology: > recovered message: > * Changed u-boot binary creation using the rockchip SPL properly +> X-Git-Archeology: > recovered message: > * Added boot order for xt-q8l-v10: sdcard, usb0, eMMC, network +> X-Git-Archeology: > recovered message: > * Added bionic:next in beta config for xt-q8l-v10 board +> X-Git-Archeology: > recovered message: > * Changed some minor bits in xt-q8l-v10 device tree files, added missing bits to dev flavour +> X-Git-Archeology: > recovered message: > Added patches to introduce fairchild fan53555/silergy82x regulators to u-boot and enabled in xt-q8l-v10 device tree +> X-Git-Archeology: > recovered message: > * Updated u-boot to version v2018.03 for xt-q8l-v10. Other rk3288 boards will gain v2018.05 from main armbian fork +> X-Git-Archeology: > recovered message: > Removed pre-reloc labels in u-boot device tree because they are not necessary since we don't use u-boot SPL for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > Removed vmmc-supply and vqmmc-supply in u-boot device tree to avoid hang on boot +> X-Git-Archeology: > recovered message: > * Tidied up a bit device trees, in particular some modifications are made to power regulator properties comparing them against the original q8l device tree +> X-Git-Archeology: > recovered message: > Removed unnecessary dummy regulator, removed unnecessary capacities to embedded eMMC +> X-Git-Archeology: > recovered message: > Disabled unused USB host +> X-Git-Archeology: > recovered message: > Removed vmmc-supply and vqmmc-supply from emmc section because it causes hang in u-boot v2018.03 and newer +> X-Git-Archeology: > recovered message: > * Restored previous regulator in u-boot dts +> X-Git-Archeology: > recovered message: > removed assert phy reset USB patch from rockchip-dev because of some upstream incompatible changes +> X-Git-Archeology: > recovered message: > * Added patch to enable IRQ for Midgard drivers which caused massive slowdown on dev kernel +> X-Git-Archeology: > recovered message: > Changed u-boot if-code for xt-q8l-v10 in rockchip.conf +> X-Git-Archeology: > recovered message: > Removed references to rk3288-linux.dtsi in xt-q8l-v10 device tree for default kernel +> X-Git-Archeology: > recovered message: > * Committing effective removal of USB reset assert for dev kernel +> X-Git-Archeology: > recovered message: > Committing changes to u-boot device tree +> X-Git-Archeology: > recovered message: > * Added patch to disable USB power down for rockchip devices broken on latest kernel +> X-Git-Archeology: > recovered message: > * Removed usb dwc2 patch to reinject it from specific branch +> X-Git-Archeology: > recovered message: > * Reverting some voltage changes for xt-q8l-v10 device in rockchip-dev +> X-Git-Archeology: > recovered message: > * Reverting some voltage changes for xt-q8l-v10 in u-boot section +> X-Git-Archeology: > recovered message: > * Added patch to make USB ports working again on rockchip devices with mainline +> X-Git-Archeology: > recovered message: > kernel >= 4.18 +> X-Git-Archeology: > recovered message: > * Changed the 0 into false +> X-Git-Archeology: > recovered message: > * Moved xt-q8l-v10 u-boot patches into board_xt-q8l-v10 directory +> X-Git-Archeology: > recovered message: > * Changed some minor things in rockchip-dev dts for xt-q8l-v10, added mali midgard driver to dev kernel config +> X-Git-Archeology: > recovered message: > * Added devfreq support for Mali in rockchip-next flavour +> X-Git-Archeology: > recovered message: > * Remove manually applied patch (0007-drivers-drm...) because it has been +> X-Git-Archeology: > recovered message: > added to armbian main repo +> X-Git-Archeology: > recovered message: > * Removed duplicate patch which has added to main armbian repository +> X-Git-Archeology: > recovered message: > * Tidied up regulators for default/next/dev rockchip flavours for xt-q8l-v10, disabling those regulators which are not tied to anything +> X-Git-Archeology: > recovered message: > Enabled voltage regulator to make SPDIF connector work (thus not tested because I have no DAC) +> X-Git-Archeology: > recovered message: > Changed rockchip-dev and rockchip-next config files to enable gpio-ir-receiver module to enable bundled remote IR controller, including kernel patch for keymap +> X-Git-Archeology: > recovered message: > * Enabled back regulator REG7 to allow propert bluetooth functionaly +> X-Git-Archeology: > recovered message: > * Minor changes to u-boot device tree for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > Added patch to set act8846 SIPC to correctly reboot the device (thus require some power-hold at reboot to make reboot fully working) +> X-Git-Archeology: > recovered message: > * Fixed u-boot device tree +> X-Git-Archeology: > recovered message: > * Added configuration bits to support TPL in u-boot for xt-q8l-v10 (TPL is thrown away though) to allow faster reboot times and achieve a working reset feature activating power hold gpio pin as soon as possible. gpio pin is hardwired into spl_board_init() u-boot code because it is not possible to let it work via device tree +> X-Git-Archeology: > recovered message: > Fixed OTG USB port in u-boot, allowing devices detection and booting +> X-Git-Archeology: > recovered message: > Added proper vbus-supply properties for USB controllers in u-boot dts, so u-boot activates USB vbus itself +> X-Git-Archeology: > recovered message: > * Fixed dts makefile patching for next and dev rockchip kernel +> X-Git-Archeology: > recovered message: > * Fixed fdt_file renamed to fdtfile in armbianEnv.txt +> X-Git-Archeology: > recovered message: > * Changed xt-q8l-v10 board config as per recomendations +> X-Git-Archeology: > recovered message: > * Moved xt-q8l-v10 configuration to CSC +> X-Git-Archeology: > recovered message: > Restored linux-rockchip-* configurations, enabled brcmfmac driver, GPIO remote controller driver and lirc kernel compatibility interface +> X-Git-Archeology: > recovered message: > Polished a bit rockchip.conf +> X-Git-Archeology: > recovered message: > * Add patch to brcmfmac driver to search for ap6330 firmware +> X-Git-Archeology: > recovered message: > Removed copy-work from rockchip.conf about ap6330 firmware for xt-q8l-v10 and tidied up +> X-Git-Archeology: > recovered message: > Avoid using brcm_patchram_plus in ap6330-bluetooth-service putting proper firmware file in /etc/firmware for hciattach do firmware uploading itself +> X-Git-Archeology: > recovered message: > * Fixed bcm4330 bluetooth firmware linking for hciattach used by ap6330-bluetooth.service +> X-Git-Archeology: > recovered message: > * Removed foreign test patches from xt-q8l-v10 u-boot directory +> X-Git-Archeology: - Revision 60b4166a8a9efe74c76bf75246cd297ccf4cf7ca: https://github.com/armbian/build/commit/60b4166a8a9efe74c76bf75246cd297ccf4cf7ca +> X-Git-Archeology: Date: Thu, 22 Nov 2018 07:04:19 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Add rk3288 xt-q8l-v10 CSC board (#1158) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision c0001d566b3770dae722c47180dcb942bed7006a: https://github.com/armbian/build/commit/c0001d566b3770dae722c47180dcb942bed7006a +> X-Git-Archeology: Date: Wed, 14 Dec 2022 01:43:31 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump bcm, imx, mvebu64 and xu4 EDGE to 6.1.y (#4560) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -index a907d7b06..ec71996c7 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -619,13 +619,17 @@ BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); - BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); - BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); +@@ -633,13 +633,17 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt"); + /* per-board firmware binaries */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin"); +/* AMPAK */ +BRCMF_FW_DEF(AP6330, "brcmfmac-ap6330-sdio"); @@ -21,3 +184,6 @@ index a907d7b06..ec71996c7 100644 BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-esp8089.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-esp8089.patch index 727afc1b8..3cf537bb6 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-esp8089.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-esp8089.patch @@ -1,106 +1,73 @@ -From 2d6165af6e9d5ed5026cdf250536c0a00d84fd75 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 1 Oct 2022 12:43:53 +0000 -Subject: [PATCH] add esp8089 kernel driver +Subject: add esp8089 kernel driver --- - drivers/net/wireless/Kconfig | 1 + - drivers/net/wireless/Makefile | 1 + - drivers/net/wireless/esp8089/.gitignore | 7 + - drivers/net/wireless/esp8089/Kconfig | 13 + - drivers/net/wireless/esp8089/LICENSE | 340 +++ - drivers/net/wireless/esp8089/Makefile | 7 + - drivers/net/wireless/esp8089/Makefile.old | 99 + - drivers/net/wireless/esp8089/README.md | 31 + - drivers/net/wireless/esp8089/esp_ctrl.c | 801 ++++++ - drivers/net/wireless/esp8089/esp_ctrl.h | 58 + - drivers/net/wireless/esp8089/esp_debug.c | 297 ++ - drivers/net/wireless/esp8089/esp_debug.h | 101 + - drivers/net/wireless/esp8089/esp_ext.c | 542 ++++ - drivers/net/wireless/esp8089/esp_ext.h | 100 + - drivers/net/wireless/esp8089/esp_file.c | 258 ++ - drivers/net/wireless/esp8089/esp_file.h | 43 + - drivers/net/wireless/esp8089/esp_init_data.h | 7 + - drivers/net/wireless/esp8089/esp_io.c | 639 +++++ - drivers/net/wireless/esp8089/esp_mac80211.c | 1727 ++++++++++++ - drivers/net/wireless/esp8089/esp_mac80211.h | 38 + - drivers/net/wireless/esp8089/esp_main.c | 263 ++ - drivers/net/wireless/esp8089/esp_path.h | 6 + - drivers/net/wireless/esp8089/esp_pub.h | 222 ++ - drivers/net/wireless/esp8089/esp_sif.h | 207 ++ - drivers/net/wireless/esp8089/esp_sip.c | 2418 +++++++++++++++++ - drivers/net/wireless/esp8089/esp_sip.h | 171 ++ - drivers/net/wireless/esp8089/esp_utils.c | 262 ++ - drivers/net/wireless/esp8089/esp_utils.h | 41 + - drivers/net/wireless/esp8089/esp_version.h | 1 + - drivers/net/wireless/esp8089/esp_wl.h | 63 + - drivers/net/wireless/esp8089/esp_wmac.h | 92 + - .../wireless/esp8089/firmware/LICENSE-2.0.txt | 203 ++ - drivers/net/wireless/esp8089/sdio_sif_esp.c | 811 ++++++ - drivers/net/wireless/esp8089/sip2_common.h | 475 ++++ - .../net/wireless/esp8089/slc_host_register.h | 271 ++ - 35 files changed, 10616 insertions(+) - create mode 100644 drivers/net/wireless/esp8089/.gitignore - create mode 100644 drivers/net/wireless/esp8089/Kconfig - create mode 100644 drivers/net/wireless/esp8089/LICENSE - create mode 100644 drivers/net/wireless/esp8089/Makefile - create mode 100644 drivers/net/wireless/esp8089/Makefile.old - create mode 100644 drivers/net/wireless/esp8089/README.md - create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.c - create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.h - create mode 100644 drivers/net/wireless/esp8089/esp_debug.c - create mode 100644 drivers/net/wireless/esp8089/esp_debug.h - create mode 100644 drivers/net/wireless/esp8089/esp_ext.c - create mode 100644 drivers/net/wireless/esp8089/esp_ext.h - create mode 100644 drivers/net/wireless/esp8089/esp_file.c - create mode 100644 drivers/net/wireless/esp8089/esp_file.h - create mode 100644 drivers/net/wireless/esp8089/esp_init_data.h - create mode 100644 drivers/net/wireless/esp8089/esp_io.c - create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.c - create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.h - create mode 100644 drivers/net/wireless/esp8089/esp_main.c - create mode 100644 drivers/net/wireless/esp8089/esp_path.h - create mode 100644 drivers/net/wireless/esp8089/esp_pub.h - create mode 100644 drivers/net/wireless/esp8089/esp_sif.h - create mode 100644 drivers/net/wireless/esp8089/esp_sip.c - create mode 100644 drivers/net/wireless/esp8089/esp_sip.h - create mode 100644 drivers/net/wireless/esp8089/esp_utils.c - create mode 100644 drivers/net/wireless/esp8089/esp_utils.h - create mode 100644 drivers/net/wireless/esp8089/esp_version.h - create mode 100644 drivers/net/wireless/esp8089/esp_wl.h - create mode 100644 drivers/net/wireless/esp8089/esp_wmac.h - create mode 100644 drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt - create mode 100644 drivers/net/wireless/esp8089/sdio_sif_esp.c - create mode 100644 drivers/net/wireless/esp8089/sip2_common.h - create mode 100644 drivers/net/wireless/esp8089/slc_host_register.h + drivers/net/wireless/Kconfig | 1 + + drivers/net/wireless/Makefile | 1 + + drivers/net/wireless/esp8089/.gitignore | 7 + + drivers/net/wireless/esp8089/Kconfig | 13 + + drivers/net/wireless/esp8089/LICENSE | 340 ++ + drivers/net/wireless/esp8089/Makefile | 7 + + drivers/net/wireless/esp8089/Makefile.old | 99 + + drivers/net/wireless/esp8089/README.md | 31 + + drivers/net/wireless/esp8089/esp_ctrl.c | 801 +++ + drivers/net/wireless/esp8089/esp_ctrl.h | 58 + + drivers/net/wireless/esp8089/esp_debug.c | 297 ++ + drivers/net/wireless/esp8089/esp_debug.h | 101 + + drivers/net/wireless/esp8089/esp_ext.c | 542 +++ + drivers/net/wireless/esp8089/esp_ext.h | 100 + + drivers/net/wireless/esp8089/esp_file.c | 258 + + drivers/net/wireless/esp8089/esp_file.h | 43 + + drivers/net/wireless/esp8089/esp_init_data.h | 7 + + drivers/net/wireless/esp8089/esp_io.c | 639 +++ + drivers/net/wireless/esp8089/esp_mac80211.c | 1731 +++++++ + drivers/net/wireless/esp8089/esp_mac80211.h | 38 + + drivers/net/wireless/esp8089/esp_main.c | 263 + + drivers/net/wireless/esp8089/esp_path.h | 6 + + drivers/net/wireless/esp8089/esp_pub.h | 222 + + drivers/net/wireless/esp8089/esp_sif.h | 207 + + drivers/net/wireless/esp8089/esp_sip.c | 2420 ++++++++++ + drivers/net/wireless/esp8089/esp_sip.h | 171 + + drivers/net/wireless/esp8089/esp_utils.c | 262 + + drivers/net/wireless/esp8089/esp_utils.h | 41 + + drivers/net/wireless/esp8089/esp_version.h | 1 + + drivers/net/wireless/esp8089/esp_wl.h | 63 + + drivers/net/wireless/esp8089/esp_wmac.h | 92 + + drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt | 203 + + drivers/net/wireless/esp8089/sdio_sif_esp.c | 824 ++++ + drivers/net/wireless/esp8089/sip2_common.h | 475 ++ + drivers/net/wireless/esp8089/slc_host_register.h | 271 ++ + 35 files changed, 10635 insertions(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig -index cb1c15012dd0..de5e37846397 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig -@@ -37,6 +37,7 @@ source "drivers/net/wireless/st/Kconfig" - source "drivers/net/wireless/ti/Kconfig" +@@ -43,6 +43,7 @@ source "drivers/net/wireless/rtl8189fs/Kconfig" + source "drivers/net/wireless/rtl8189es/Kconfig" source "drivers/net/wireless/zydas/Kconfig" source "drivers/net/wireless/quantenna/Kconfig" +source "drivers/net/wireless/esp8089/Kconfig" - config PCMCIA_RAYCS - tristate "Aviator/Raytheon 2.4GHz wireless support" + source "drivers/net/wireless/virtual/Kconfig" + diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile -index a61cf6c90343..92ffd2cef51c 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile -@@ -22,6 +22,7 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ +@@ -21,6 +21,7 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ obj-$(CONFIG_WLAN_VENDOR_ST) += st/ obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ +obj-$(CONFIG_ESP8089) += esp8089/ - # 16-bit wireless PCMCIA client drivers - obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o + obj-$(CONFIG_WLAN) += virtual/ + obj-$(CONFIG_RTL8189ES) += rtl8189es/ diff --git a/drivers/net/wireless/esp8089/.gitignore b/drivers/net/wireless/esp8089/.gitignore new file mode 100644 -index 000000000000..eae6529085d0 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/.gitignore @@ -0,0 +1,7 @@ @@ -113,7 +80,7 @@ index 000000000000..eae6529085d0 +*.mod.c diff --git a/drivers/net/wireless/esp8089/Kconfig b/drivers/net/wireless/esp8089/Kconfig new file mode 100644 -index 000000000000..8db1fc54712d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Kconfig @@ -0,0 +1,13 @@ @@ -132,7 +99,7 @@ index 000000000000..8db1fc54712d + DebugFS support for ESP8089 diff --git a/drivers/net/wireless/esp8089/LICENSE b/drivers/net/wireless/esp8089/LICENSE new file mode 100644 -index 000000000000..d6a93266f748 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/LICENSE @@ -0,0 +1,340 @@ @@ -478,7 +445,7 @@ index 000000000000..d6a93266f748 + diff --git a/drivers/net/wireless/esp8089/Makefile b/drivers/net/wireless/esp8089/Makefile new file mode 100644 -index 000000000000..36decfd20ecd +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Makefile @@ -0,0 +1,7 @@ @@ -491,7 +458,7 @@ index 000000000000..36decfd20ecd +obj-$(CONFIG_ESP8089) := esp8089.o diff --git a/drivers/net/wireless/esp8089/Makefile.old b/drivers/net/wireless/esp8089/Makefile.old new file mode 100644 -index 000000000000..b7b1a47b159c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Makefile.old @@ -0,0 +1,99 @@ @@ -596,7 +563,7 @@ index 000000000000..b7b1a47b159c +.PHONY: all modules clean install config_check diff --git a/drivers/net/wireless/esp8089/README.md b/drivers/net/wireless/esp8089/README.md new file mode 100644 -index 000000000000..56b40db272f3 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/README.md @@ -0,0 +1,31 @@ @@ -633,7 +600,7 @@ index 000000000000..56b40db272f3 +To load the module. diff --git a/drivers/net/wireless/esp8089/esp_ctrl.c b/drivers/net/wireless/esp8089/esp_ctrl.c new file mode 100644 -index 000000000000..a19d2437dd82 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ctrl.c @@ -0,0 +1,801 @@ @@ -1440,7 +1407,7 @@ index 000000000000..a19d2437dd82 +} diff --git a/drivers/net/wireless/esp8089/esp_ctrl.h b/drivers/net/wireless/esp8089/esp_ctrl.h new file mode 100644 -index 000000000000..29c18caa9ede +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ctrl.h @@ -0,0 +1,58 @@ @@ -1504,7 +1471,7 @@ index 000000000000..29c18caa9ede +#endif /* _ESP_CTRL_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_debug.c b/drivers/net/wireless/esp8089/esp_debug.c new file mode 100644 -index 000000000000..5ce8fd2ebd6b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_debug.c @@ -0,0 +1,297 @@ @@ -1807,7 +1774,7 @@ index 000000000000..5ce8fd2ebd6b +#endif /* HOST_RC */ diff --git a/drivers/net/wireless/esp8089/esp_debug.h b/drivers/net/wireless/esp8089/esp_debug.h new file mode 100644 -index 000000000000..bab695d34bfb +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_debug.h @@ -0,0 +1,101 @@ @@ -1914,7 +1881,7 @@ index 000000000000..bab695d34bfb +#endif /* _DEBUG_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_ext.c b/drivers/net/wireless/esp8089/esp_ext.c new file mode 100644 -index 000000000000..541f27a6853f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ext.c @@ -0,0 +1,542 @@ @@ -2462,7 +2429,7 @@ index 000000000000..541f27a6853f +#endif /* USE_EXT_GPIO */ diff --git a/drivers/net/wireless/esp8089/esp_ext.h b/drivers/net/wireless/esp8089/esp_ext.h new file mode 100644 -index 000000000000..0eeba4d22111 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ext.h @@ -0,0 +1,100 @@ @@ -2568,7 +2535,7 @@ index 000000000000..0eeba4d22111 +#endif /* USE_EXT_GPIO */ diff --git a/drivers/net/wireless/esp8089/esp_file.c b/drivers/net/wireless/esp8089/esp_file.c new file mode 100644 -index 000000000000..ea702f010eec +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_file.c @@ -0,0 +1,258 @@ @@ -2832,7 +2799,7 @@ index 000000000000..ea702f010eec +} diff --git a/drivers/net/wireless/esp8089/esp_file.h b/drivers/net/wireless/esp8089/esp_file.h new file mode 100644 -index 000000000000..5ba39c626baa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_file.h @@ -0,0 +1,43 @@ @@ -2881,7 +2848,7 @@ index 000000000000..5ba39c626baa +#endif /* _ESP_FILE_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_init_data.h b/drivers/net/wireless/esp8089/esp_init_data.h new file mode 100644 -index 000000000000..16f451affd1e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_init_data.h @@ -0,0 +1,7 @@ @@ -2894,7 +2861,7 @@ index 000000000000..16f451affd1e +0 }; diff --git a/drivers/net/wireless/esp8089/esp_io.c b/drivers/net/wireless/esp8089/esp_io.c new file mode 100644 -index 000000000000..6c5c01aad4e5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_io.c @@ -0,0 +1,639 @@ @@ -3539,7 +3506,7 @@ index 000000000000..6c5c01aad4e5 +} diff --git a/drivers/net/wireless/esp8089/esp_mac80211.c b/drivers/net/wireless/esp8089/esp_mac80211.c new file mode 100644 -index 000000000000..14186365fdd4 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_mac80211.c @@ -0,0 +1,1731 @@ @@ -5276,7 +5243,7 @@ index 000000000000..14186365fdd4 +} diff --git a/drivers/net/wireless/esp8089/esp_mac80211.h b/drivers/net/wireless/esp8089/esp_mac80211.h new file mode 100644 -index 000000000000..699b27dcadd1 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_mac80211.h @@ -0,0 +1,38 @@ @@ -5320,7 +5287,7 @@ index 000000000000..699b27dcadd1 +#endif /* _ESP_MAC80211_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_main.c b/drivers/net/wireless/esp8089/esp_main.c new file mode 100644 -index 000000000000..404e0d7a6f54 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_main.c @@ -0,0 +1,263 @@ @@ -5589,7 +5556,7 @@ index 000000000000..404e0d7a6f54 +#endif /* !FPGA_DEBUG */ diff --git a/drivers/net/wireless/esp8089/esp_path.h b/drivers/net/wireless/esp8089/esp_path.h new file mode 100644 -index 000000000000..1ceb14bc3b15 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_path.h @@ -0,0 +1,6 @@ @@ -5601,7 +5568,7 @@ index 000000000000..1ceb14bc3b15 +#endif /* _ESP_PATH_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_pub.h b/drivers/net/wireless/esp8089/esp_pub.h new file mode 100644 -index 000000000000..0d3ad3655cf4 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_pub.h @@ -0,0 +1,222 @@ @@ -5829,7 +5796,7 @@ index 000000000000..0d3ad3655cf4 +#endif /* _ESP_PUB_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_sif.h b/drivers/net/wireless/esp8089/esp_sif.h new file mode 100644 -index 000000000000..2d49f2bc8035 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sif.h @@ -0,0 +1,207 @@ @@ -6042,7 +6009,7 @@ index 000000000000..2d49f2bc8035 +#endif /* _ESP_SIF_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_sip.c b/drivers/net/wireless/esp8089/esp_sip.c new file mode 100644 -index 000000000000..6602a1e22ab1 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sip.c @@ -0,0 +1,2420 @@ @@ -8468,7 +8435,7 @@ index 000000000000..6602a1e22ab1 +#endif /* FPGA_TXDATA */ diff --git a/drivers/net/wireless/esp8089/esp_sip.h b/drivers/net/wireless/esp8089/esp_sip.h new file mode 100644 -index 000000000000..95cc42989b2c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sip.h @@ -0,0 +1,171 @@ @@ -8645,7 +8612,7 @@ index 000000000000..95cc42989b2c +#endif diff --git a/drivers/net/wireless/esp8089/esp_utils.c b/drivers/net/wireless/esp8089/esp_utils.c new file mode 100644 -index 000000000000..8b188de79b2c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_utils.c @@ -0,0 +1,262 @@ @@ -8913,7 +8880,7 @@ index 000000000000..8b188de79b2c +} diff --git a/drivers/net/wireless/esp8089/esp_utils.h b/drivers/net/wireless/esp8089/esp_utils.h new file mode 100644 -index 000000000000..ed16d9ca0a65 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_utils.h @@ -0,0 +1,41 @@ @@ -8960,14 +8927,14 @@ index 000000000000..ed16d9ca0a65 +#endif diff --git a/drivers/net/wireless/esp8089/esp_version.h b/drivers/net/wireless/esp8089/esp_version.h new file mode 100644 -index 000000000000..481d98841fc2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_version.h @@ -0,0 +1 @@ +#define DRIVER_VER 0xbdf5087c3debll diff --git a/drivers/net/wireless/esp8089/esp_wl.h b/drivers/net/wireless/esp8089/esp_wl.h new file mode 100644 -index 000000000000..e3e62a83d505 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_wl.h @@ -0,0 +1,63 @@ @@ -9036,7 +9003,7 @@ index 000000000000..e3e62a83d505 +#endif /* _ESP_WL_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_wmac.h b/drivers/net/wireless/esp8089/esp_wmac.h new file mode 100644 -index 000000000000..72d13cbfc0e5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_wmac.h @@ -0,0 +1,92 @@ @@ -9134,7 +9101,7 @@ index 000000000000..72d13cbfc0e5 +#endif /* _ESP_WMAC_H_ */ diff --git a/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt new file mode 100644 -index 000000000000..0dd35c82a001 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt @@ -0,0 +1,203 @@ @@ -9343,7 +9310,7 @@ index 000000000000..0dd35c82a001 + limitations under the License. diff --git a/drivers/net/wireless/esp8089/sdio_sif_esp.c b/drivers/net/wireless/esp8089/sdio_sif_esp.c new file mode 100644 -index 000000000000..2bd2c63f5388 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/sdio_sif_esp.c @@ -0,0 +1,824 @@ @@ -10173,7 +10140,7 @@ index 000000000000..2bd2c63f5388 +module_exit(esp_sdio_exit); diff --git a/drivers/net/wireless/esp8089/sip2_common.h b/drivers/net/wireless/esp8089/sip2_common.h new file mode 100644 -index 000000000000..d46e87589b0b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/sip2_common.h @@ -0,0 +1,475 @@ @@ -10654,7 +10621,7 @@ index 000000000000..d46e87589b0b +#endif /* _SIP_COMMON_H_ */ diff --git a/drivers/net/wireless/esp8089/slc_host_register.h b/drivers/net/wireless/esp8089/slc_host_register.h new file mode 100644 -index 000000000000..2cdb2c856d15 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/slc_host_register.h @@ -0,0 +1,271 @@ @@ -10930,5 +10897,5 @@ index 000000000000..2cdb2c856d15 + +#endif // SLC_HOST_REGISTER_H_INCLUDED -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-ssv6051.patch b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-ssv6051.patch index 669c07b57..ad78d8245 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-ssv6051.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.armbian/wifi-driver-ssv6051.patch @@ -1,131 +1,73 @@ -From 3f30a652fb3e6ead83f65312d0240d5c9ea8c340 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 2 Nov 2022 15:40:06 +0000 -Subject: [PATCH] add ssv6xxx wifi driver +Subject: add ssv6xxx wifi driver --- - drivers/net/wireless/Kconfig | 1 + - drivers/net/wireless/Makefile | 1 + - drivers/net/wireless/ssv6051/Kconfig | 11 + - drivers/net/wireless/ssv6051/Makefile | 26 + - drivers/net/wireless/ssv6051/Makefile.bak | 107 + - .../ssv6051/firmware/ssv6051-wifi.cfg | 91 + - drivers/net/wireless/ssv6051/hci/hctrl.h | 178 + - drivers/net/wireless/ssv6051/hci/ssv_hci.c | 967 + - drivers/net/wireless/ssv6051/hci/ssv_hci.h | 77 + - drivers/net/wireless/ssv6051/hwif/hwif.h | 84 + - drivers/net/wireless/ssv6051/hwif/sdio/sdio.c | 1254 ++ - .../net/wireless/ssv6051/hwif/sdio/sdio_def.h | 80 + - drivers/net/wireless/ssv6051/include/cabrio.h | 28 + - .../net/wireless/ssv6051/include/ssv6200.h | 76 + - .../wireless/ssv6051/include/ssv6200_aux.h | 18221 ++++++++++++++++ - .../wireless/ssv6051/include/ssv6200_common.h | 452 + - .../ssv6051/include/ssv6200_configuration.h | 317 + - .../wireless/ssv6051/include/ssv6200_reg.h | 9694 ++++++++ - .../ssv6051/include/ssv6200_reg_sim.h | 176 + - .../net/wireless/ssv6051/include/ssv_cfg.h | 60 + - .../ssv6051/include/ssv_firmware_version.h | 25 + - .../wireless/ssv6051/include/ssv_version.h | 12 + - .../net/wireless/ssv6051/platform-config.mak | 97 + - drivers/net/wireless/ssv6051/rules.mak | 19 + - drivers/net/wireless/ssv6051/smac/ampdu.c | 2111 ++ - drivers/net/wireless/ssv6051/smac/ampdu.h | 215 + - drivers/net/wireless/ssv6051/smac/ap.c | 598 + - drivers/net/wireless/ssv6051/smac/ap.h | 41 + - drivers/net/wireless/ssv6051/smac/dev.c | 3880 ++++ - drivers/net/wireless/ssv6051/smac/dev.h | 445 + - drivers/net/wireless/ssv6051/smac/dev_tbl.h | 141 + - drivers/net/wireless/ssv6051/smac/drv_comm.h | 61 + - drivers/net/wireless/ssv6051/smac/efuse.c | 334 + - drivers/net/wireless/ssv6051/smac/efuse.h | 40 + - drivers/net/wireless/ssv6051/smac/init.c | 1347 ++ - drivers/net/wireless/ssv6051/smac/init.h | 23 + - drivers/net/wireless/ssv6051/smac/lib.c | 33 + - drivers/net/wireless/ssv6051/smac/lib.h | 23 + - .../net/wireless/ssv6051/smac/linux_80211.h | 24 + - drivers/net/wireless/ssv6051/smac/p2p.c | 305 + - drivers/net/wireless/ssv6051/smac/p2p.h | 58 + - drivers/net/wireless/ssv6051/smac/sar.c | 208 + - drivers/net/wireless/ssv6051/smac/sar.h | 63 + - drivers/net/wireless/ssv6051/smac/sec.h | 52 + - drivers/net/wireless/ssv6051/smac/smartlink.c | 340 + - .../wireless/ssv6051/smac/ssv6xxx_debugfs.c | 223 + - .../wireless/ssv6051/smac/ssv6xxx_debugfs.h | 27 + - .../net/wireless/ssv6051/smac/ssv_cfgvendor.c | 1384 ++ - .../net/wireless/ssv6051/smac/ssv_cfgvendor.h | 247 + - drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c | 546 + - drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h | 31 + - drivers/net/wireless/ssv6051/smac/ssv_pm.c | 19 + - drivers/net/wireless/ssv6051/smac/ssv_pm.h | 20 + - drivers/net/wireless/ssv6051/smac/ssv_rc.c | 1716 ++ - drivers/net/wireless/ssv6051/smac/ssv_rc.h | 50 + - .../net/wireless/ssv6051/smac/ssv_rc_common.h | 175 + - .../wireless/ssv6051/ssv6051-generic-wlan.c | 76 + - .../net/wireless/ssv6051/ssvdevice/ssv_cmd.c | 1765 ++ - .../net/wireless/ssv6051/ssvdevice/ssv_cmd.h | 50 + - .../wireless/ssv6051/ssvdevice/ssvdevice.c | 256 + - 60 files changed, 48983 insertions(+) - create mode 100644 drivers/net/wireless/ssv6051/Kconfig - create mode 100644 drivers/net/wireless/ssv6051/Makefile - create mode 100644 drivers/net/wireless/ssv6051/Makefile.bak - create mode 100644 drivers/net/wireless/ssv6051/firmware/ssv6051-wifi.cfg - create mode 100644 drivers/net/wireless/ssv6051/hci/hctrl.h - create mode 100644 drivers/net/wireless/ssv6051/hci/ssv_hci.c - create mode 100644 drivers/net/wireless/ssv6051/hci/ssv_hci.h - create mode 100644 drivers/net/wireless/ssv6051/hwif/hwif.h - create mode 100644 drivers/net/wireless/ssv6051/hwif/sdio/sdio.c - create mode 100644 drivers/net/wireless/ssv6051/hwif/sdio/sdio_def.h - create mode 100644 drivers/net/wireless/ssv6051/include/cabrio.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200_aux.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200_common.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200_configuration.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200_reg.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv6200_reg_sim.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv_cfg.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv_firmware_version.h - create mode 100644 drivers/net/wireless/ssv6051/include/ssv_version.h - create mode 100644 drivers/net/wireless/ssv6051/platform-config.mak - create mode 100644 drivers/net/wireless/ssv6051/rules.mak - create mode 100644 drivers/net/wireless/ssv6051/smac/ampdu.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ampdu.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ap.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ap.h - create mode 100644 drivers/net/wireless/ssv6051/smac/dev.c - create mode 100644 drivers/net/wireless/ssv6051/smac/dev.h - create mode 100644 drivers/net/wireless/ssv6051/smac/dev_tbl.h - create mode 100644 drivers/net/wireless/ssv6051/smac/drv_comm.h - create mode 100644 drivers/net/wireless/ssv6051/smac/efuse.c - create mode 100644 drivers/net/wireless/ssv6051/smac/efuse.h - create mode 100644 drivers/net/wireless/ssv6051/smac/init.c - create mode 100644 drivers/net/wireless/ssv6051/smac/init.h - create mode 100644 drivers/net/wireless/ssv6051/smac/lib.c - create mode 100644 drivers/net/wireless/ssv6051/smac/lib.h - create mode 100644 drivers/net/wireless/ssv6051/smac/linux_80211.h - create mode 100644 drivers/net/wireless/ssv6051/smac/p2p.c - create mode 100644 drivers/net/wireless/ssv6051/smac/p2p.h - create mode 100644 drivers/net/wireless/ssv6051/smac/sar.c - create mode 100644 drivers/net/wireless/ssv6051/smac/sar.h - create mode 100644 drivers/net/wireless/ssv6051/smac/sec.h - create mode 100644 drivers/net/wireless/ssv6051/smac/smartlink.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_pm.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_pm.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_rc.c - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_rc.h - create mode 100644 drivers/net/wireless/ssv6051/smac/ssv_rc_common.h - create mode 100644 drivers/net/wireless/ssv6051/ssv6051-generic-wlan.c - create mode 100644 drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c - create mode 100644 drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h - create mode 100644 drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c + drivers/net/wireless/Kconfig | 1 + + drivers/net/wireless/Makefile | 1 + + drivers/net/wireless/ssv6051/Kconfig | 11 + + drivers/net/wireless/ssv6051/Makefile | 26 + + drivers/net/wireless/ssv6051/Makefile.bak | 107 + + drivers/net/wireless/ssv6051/firmware/ssv6051-wifi.cfg | 91 + + drivers/net/wireless/ssv6051/hci/hctrl.h | 178 + + drivers/net/wireless/ssv6051/hci/ssv_hci.c | 967 + + drivers/net/wireless/ssv6051/hci/ssv_hci.h | 77 + + drivers/net/wireless/ssv6051/hwif/hwif.h | 84 + + drivers/net/wireless/ssv6051/hwif/sdio/sdio.c | 1254 + + drivers/net/wireless/ssv6051/hwif/sdio/sdio_def.h | 80 + + drivers/net/wireless/ssv6051/include/cabrio.h | 28 + + drivers/net/wireless/ssv6051/include/ssv6200.h | 76 + + drivers/net/wireless/ssv6051/include/ssv6200_aux.h | 18221 ++++++++++ + drivers/net/wireless/ssv6051/include/ssv6200_common.h | 452 + + drivers/net/wireless/ssv6051/include/ssv6200_configuration.h | 317 + + drivers/net/wireless/ssv6051/include/ssv6200_reg.h | 9694 +++++ + drivers/net/wireless/ssv6051/include/ssv6200_reg_sim.h | 176 + + drivers/net/wireless/ssv6051/include/ssv_cfg.h | 60 + + drivers/net/wireless/ssv6051/include/ssv_firmware_version.h | 25 + + drivers/net/wireless/ssv6051/include/ssv_version.h | 12 + + drivers/net/wireless/ssv6051/platform-config.mak | 97 + + drivers/net/wireless/ssv6051/rules.mak | 19 + + drivers/net/wireless/ssv6051/smac/ampdu.c | 2111 ++ + drivers/net/wireless/ssv6051/smac/ampdu.h | 215 + + drivers/net/wireless/ssv6051/smac/ap.c | 598 + + drivers/net/wireless/ssv6051/smac/ap.h | 41 + + drivers/net/wireless/ssv6051/smac/dev.c | 3884 ++ + drivers/net/wireless/ssv6051/smac/dev.h | 445 + + drivers/net/wireless/ssv6051/smac/dev_tbl.h | 141 + + drivers/net/wireless/ssv6051/smac/drv_comm.h | 61 + + drivers/net/wireless/ssv6051/smac/efuse.c | 334 + + drivers/net/wireless/ssv6051/smac/efuse.h | 40 + + drivers/net/wireless/ssv6051/smac/init.c | 1347 + + drivers/net/wireless/ssv6051/smac/init.h | 23 + + drivers/net/wireless/ssv6051/smac/lib.c | 33 + + drivers/net/wireless/ssv6051/smac/lib.h | 23 + + drivers/net/wireless/ssv6051/smac/linux_80211.h | 24 + + drivers/net/wireless/ssv6051/smac/p2p.c | 305 + + drivers/net/wireless/ssv6051/smac/p2p.h | 58 + + drivers/net/wireless/ssv6051/smac/sar.c | 208 + + drivers/net/wireless/ssv6051/smac/sar.h | 63 + + drivers/net/wireless/ssv6051/smac/sec.h | 52 + + drivers/net/wireless/ssv6051/smac/smartlink.c | 340 + + drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.c | 223 + + drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.h | 27 + + drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.c | 1384 + + drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.h | 247 + + drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c | 546 + + drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h | 31 + + drivers/net/wireless/ssv6051/smac/ssv_pm.c | 19 + + drivers/net/wireless/ssv6051/smac/ssv_pm.h | 20 + + drivers/net/wireless/ssv6051/smac/ssv_rc.c | 1716 + + drivers/net/wireless/ssv6051/smac/ssv_rc.h | 50 + + drivers/net/wireless/ssv6051/smac/ssv_rc_common.h | 175 + + drivers/net/wireless/ssv6051/ssv6051-generic-wlan.c | 76 + + drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c | 1765 + + drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h | 50 + + drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c | 256 + + 60 files changed, 48985 insertions(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig -index de5e37846397..aa2cac9abdd3 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -18,6 +18,7 @@ menuconfig WLAN @@ -137,7 +79,7 @@ index de5e37846397..aa2cac9abdd3 100644 source "drivers/net/wireless/ath/Kconfig" source "drivers/net/wireless/atmel/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile -index 92ffd2cef51c..8b56a42e97a6 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -3,6 +3,7 @@ @@ -150,7 +92,7 @@ index 92ffd2cef51c..8b56a42e97a6 100644 obj-$(CONFIG_WLAN_VENDOR_ATMEL) += atmel/ diff --git a/drivers/net/wireless/ssv6051/Kconfig b/drivers/net/wireless/ssv6051/Kconfig new file mode 100644 -index 000000000000..7706ad52ed7b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/Kconfig @@ -0,0 +1,11 @@ @@ -167,7 +109,7 @@ index 000000000000..7706ad52ed7b + diff --git a/drivers/net/wireless/ssv6051/Makefile b/drivers/net/wireless/ssv6051/Makefile new file mode 100644 -index 000000000000..985d730f3d50 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/Makefile @@ -0,0 +1,26 @@ @@ -199,7 +141,7 @@ index 000000000000..985d730f3d50 + diff --git a/drivers/net/wireless/ssv6051/Makefile.bak b/drivers/net/wireless/ssv6051/Makefile.bak new file mode 100644 -index 000000000000..2733fa4dd3b7 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/Makefile.bak @@ -0,0 +1,107 @@ @@ -312,7 +254,7 @@ index 000000000000..2733fa4dd3b7 +.PHONY: all modules clean install diff --git a/drivers/net/wireless/ssv6051/firmware/ssv6051-wifi.cfg b/drivers/net/wireless/ssv6051/firmware/ssv6051-wifi.cfg new file mode 100644 -index 000000000000..c072960f6dea +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/firmware/ssv6051-wifi.cfg @@ -0,0 +1,91 @@ @@ -409,7 +351,7 @@ index 000000000000..c072960f6dea +################################################## diff --git a/drivers/net/wireless/ssv6051/hci/hctrl.h b/drivers/net/wireless/ssv6051/hci/hctrl.h new file mode 100644 -index 000000000000..95218c8040e7 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hci/hctrl.h @@ -0,0 +1,178 @@ @@ -593,7 +535,7 @@ index 000000000000..95218c8040e7 +#endif diff --git a/drivers/net/wireless/ssv6051/hci/ssv_hci.c b/drivers/net/wireless/ssv6051/hci/ssv_hci.c new file mode 100644 -index 000000000000..9fedbeb55754 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hci/ssv_hci.c @@ -0,0 +1,967 @@ @@ -1566,7 +1508,7 @@ index 000000000000..9fedbeb55754 +EXPORT_SYMBOL(ssv6xxx_hci_exit); diff --git a/drivers/net/wireless/ssv6051/hci/ssv_hci.h b/drivers/net/wireless/ssv6051/hci/ssv_hci.h new file mode 100644 -index 000000000000..dd166c607d5d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hci/ssv_hci.h @@ -0,0 +1,77 @@ @@ -1649,7 +1591,7 @@ index 000000000000..dd166c607d5d +#endif diff --git a/drivers/net/wireless/ssv6051/hwif/hwif.h b/drivers/net/wireless/ssv6051/hwif/hwif.h new file mode 100644 -index 000000000000..6b5263d157d8 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hwif/hwif.h @@ -0,0 +1,84 @@ @@ -1739,7 +1681,7 @@ index 000000000000..6b5263d157d8 +#endif diff --git a/drivers/net/wireless/ssv6051/hwif/sdio/sdio.c b/drivers/net/wireless/ssv6051/hwif/sdio/sdio.c new file mode 100644 -index 000000000000..273777cd0485 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hwif/sdio/sdio.c @@ -0,0 +1,1254 @@ @@ -2999,7 +2941,7 @@ index 000000000000..273777cd0485 +EXPORT_SYMBOL(ssv6xxx_sdio_exit); diff --git a/drivers/net/wireless/ssv6051/hwif/sdio/sdio_def.h b/drivers/net/wireless/ssv6051/hwif/sdio/sdio_def.h new file mode 100644 -index 000000000000..57aefd3bf9fa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/hwif/sdio/sdio_def.h @@ -0,0 +1,80 @@ @@ -3085,7 +3027,7 @@ index 000000000000..57aefd3bf9fa +#endif diff --git a/drivers/net/wireless/ssv6051/include/cabrio.h b/drivers/net/wireless/ssv6051/include/cabrio.h new file mode 100644 -index 000000000000..0b1327865c6b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/cabrio.h @@ -0,0 +1,28 @@ @@ -3119,7 +3061,7 @@ index 000000000000..0b1327865c6b +#endif diff --git a/drivers/net/wireless/ssv6051/include/ssv6200.h b/drivers/net/wireless/ssv6051/include/ssv6200.h new file mode 100644 -index 000000000000..22eaceaf285d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200.h @@ -0,0 +1,76 @@ @@ -3201,7 +3143,7 @@ index 000000000000..22eaceaf285d +#endif diff --git a/drivers/net/wireless/ssv6051/include/ssv6200_aux.h b/drivers/net/wireless/ssv6051/include/ssv6200_aux.h new file mode 100644 -index 000000000000..03ec3f07d330 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200_aux.h @@ -0,0 +1,18221 @@ @@ -21428,7 +21370,7 @@ index 000000000000..03ec3f07d330 +#define SRAM_TAG_15_SZ 16 diff --git a/drivers/net/wireless/ssv6051/include/ssv6200_common.h b/drivers/net/wireless/ssv6051/include/ssv6200_common.h new file mode 100644 -index 000000000000..e6d30f3714f7 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200_common.h @@ -0,0 +1,452 @@ @@ -21886,7 +21828,7 @@ index 000000000000..e6d30f3714f7 +#endif diff --git a/drivers/net/wireless/ssv6051/include/ssv6200_configuration.h b/drivers/net/wireless/ssv6051/include/ssv6200_configuration.h new file mode 100644 -index 000000000000..0327393de3f5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200_configuration.h @@ -0,0 +1,317 @@ @@ -22209,7 +22151,7 @@ index 000000000000..0327393de3f5 +}; diff --git a/drivers/net/wireless/ssv6051/include/ssv6200_reg.h b/drivers/net/wireless/ssv6051/include/ssv6200_reg.h new file mode 100644 -index 000000000000..d4a99b25d61f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200_reg.h @@ -0,0 +1,9694 @@ @@ -31909,7 +31851,7 @@ index 000000000000..d4a99b25d61f +#define DEF_TAG_SRAM0_F_STATUS_7() (REG32(ADR_TAG_SRAM0_F_STATUS_7)) = (0x00000000) diff --git a/drivers/net/wireless/ssv6051/include/ssv6200_reg_sim.h b/drivers/net/wireless/ssv6051/include/ssv6200_reg_sim.h new file mode 100644 -index 000000000000..e15a481ba300 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv6200_reg_sim.h @@ -0,0 +1,176 @@ @@ -32091,7 +32033,7 @@ index 000000000000..e15a481ba300 +}; diff --git a/drivers/net/wireless/ssv6051/include/ssv_cfg.h b/drivers/net/wireless/ssv6051/include/ssv_cfg.h new file mode 100644 -index 000000000000..79b75619936e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv_cfg.h @@ -0,0 +1,60 @@ @@ -32157,7 +32099,7 @@ index 000000000000..79b75619936e +#endif diff --git a/drivers/net/wireless/ssv6051/include/ssv_firmware_version.h b/drivers/net/wireless/ssv6051/include/ssv_firmware_version.h new file mode 100644 -index 000000000000..7fabbe308f9d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv_firmware_version.h @@ -0,0 +1,25 @@ @@ -32188,7 +32130,7 @@ index 000000000000..7fabbe308f9d +#endif diff --git a/drivers/net/wireless/ssv6051/include/ssv_version.h b/drivers/net/wireless/ssv6051/include/ssv_version.h new file mode 100644 -index 000000000000..99be5354f783 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/include/ssv_version.h @@ -0,0 +1,12 @@ @@ -32206,7 +32148,7 @@ index 000000000000..99be5354f783 +#endif diff --git a/drivers/net/wireless/ssv6051/platform-config.mak b/drivers/net/wireless/ssv6051/platform-config.mak new file mode 100644 -index 000000000000..b1b6f0510d28 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/platform-config.mak @@ -0,0 +1,97 @@ @@ -32310,7 +32252,7 @@ index 000000000000..b1b6f0510d28 \ No newline at end of file diff --git a/drivers/net/wireless/ssv6051/rules.mak b/drivers/net/wireless/ssv6051/rules.mak new file mode 100644 -index 000000000000..b3262852249c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/rules.mak @@ -0,0 +1,19 @@ @@ -32335,7 +32277,7 @@ index 000000000000..b3262852249c + M=$(KBUILD_DIR) modules_install diff --git a/drivers/net/wireless/ssv6051/smac/ampdu.c b/drivers/net/wireless/ssv6051/smac/ampdu.c new file mode 100644 -index 000000000000..846830f3d209 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ampdu.c @@ -0,0 +1,2111 @@ @@ -34452,7 +34394,7 @@ index 000000000000..846830f3d209 +} diff --git a/drivers/net/wireless/ssv6051/smac/ampdu.h b/drivers/net/wireless/ssv6051/smac/ampdu.h new file mode 100644 -index 000000000000..faa61c4f9297 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ampdu.h @@ -0,0 +1,215 @@ @@ -34673,7 +34615,7 @@ index 000000000000..faa61c4f9297 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/ap.c b/drivers/net/wireless/ssv6051/smac/ap.c new file mode 100644 -index 000000000000..0f2ba6a31a05 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ap.c @@ -0,0 +1,598 @@ @@ -35277,7 +35219,7 @@ index 000000000000..0f2ba6a31a05 +} diff --git a/drivers/net/wireless/ssv6051/smac/ap.h b/drivers/net/wireless/ssv6051/smac/ap.h new file mode 100644 -index 000000000000..93b5275715b5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ap.h @@ -0,0 +1,41 @@ @@ -35324,7 +35266,7 @@ index 000000000000..93b5275715b5 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/dev.c b/drivers/net/wireless/ssv6051/smac/dev.c new file mode 100644 -index 000000000000..cd93fa42648b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/dev.c @@ -0,0 +1,3884 @@ @@ -39214,7 +39156,7 @@ index 000000000000..cd93fa42648b +#endif diff --git a/drivers/net/wireless/ssv6051/smac/dev.h b/drivers/net/wireless/ssv6051/smac/dev.h new file mode 100644 -index 000000000000..0a6357624b1c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/dev.h @@ -0,0 +1,445 @@ @@ -39665,7 +39607,7 @@ index 000000000000..0a6357624b1c +#endif diff --git a/drivers/net/wireless/ssv6051/smac/dev_tbl.h b/drivers/net/wireless/ssv6051/smac/dev_tbl.h new file mode 100644 -index 000000000000..5c49d0bde6a6 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/dev_tbl.h @@ -0,0 +1,141 @@ @@ -39812,7 +39754,7 @@ index 000000000000..5c49d0bde6a6 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/drv_comm.h b/drivers/net/wireless/ssv6051/smac/drv_comm.h new file mode 100644 -index 000000000000..f04fbae004c3 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/drv_comm.h @@ -0,0 +1,61 @@ @@ -39879,7 +39821,7 @@ index 000000000000..f04fbae004c3 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/efuse.c b/drivers/net/wireless/ssv6051/smac/efuse.c new file mode 100644 -index 000000000000..9a1f3f5488f2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/efuse.c @@ -0,0 +1,334 @@ @@ -40219,7 +40161,7 @@ index 000000000000..9a1f3f5488f2 +} diff --git a/drivers/net/wireless/ssv6051/smac/efuse.h b/drivers/net/wireless/ssv6051/smac/efuse.h new file mode 100644 -index 000000000000..c25280c5abad +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/efuse.h @@ -0,0 +1,40 @@ @@ -40265,7 +40207,7 @@ index 000000000000..c25280c5abad +#endif diff --git a/drivers/net/wireless/ssv6051/smac/init.c b/drivers/net/wireless/ssv6051/smac/init.c new file mode 100644 -index 000000000000..592c52a28381 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/init.c @@ -0,0 +1,1347 @@ @@ -41618,7 +41560,7 @@ index 000000000000..592c52a28381 +EXPORT_SYMBOL(ssv6xxx_exit); diff --git a/drivers/net/wireless/ssv6051/smac/init.h b/drivers/net/wireless/ssv6051/smac/init.h new file mode 100644 -index 000000000000..97994d00d4da +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/init.h @@ -0,0 +1,23 @@ @@ -41647,7 +41589,7 @@ index 000000000000..97994d00d4da +#endif diff --git a/drivers/net/wireless/ssv6051/smac/lib.c b/drivers/net/wireless/ssv6051/smac/lib.c new file mode 100644 -index 000000000000..ccf0974b0f20 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/lib.c @@ -0,0 +1,33 @@ @@ -41686,7 +41628,7 @@ index 000000000000..ccf0974b0f20 +} diff --git a/drivers/net/wireless/ssv6051/smac/lib.h b/drivers/net/wireless/ssv6051/smac/lib.h new file mode 100644 -index 000000000000..266cf7afac95 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/lib.h @@ -0,0 +1,23 @@ @@ -41715,7 +41657,7 @@ index 000000000000..266cf7afac95 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/linux_80211.h b/drivers/net/wireless/ssv6051/smac/linux_80211.h new file mode 100644 -index 000000000000..e268808e3c93 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/linux_80211.h @@ -0,0 +1,24 @@ @@ -41745,7 +41687,7 @@ index 000000000000..e268808e3c93 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/p2p.c b/drivers/net/wireless/ssv6051/smac/p2p.c new file mode 100644 -index 000000000000..60fd8effd6ec +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/p2p.c @@ -0,0 +1,305 @@ @@ -42056,7 +41998,7 @@ index 000000000000..60fd8effd6ec +#endif diff --git a/drivers/net/wireless/ssv6051/smac/p2p.h b/drivers/net/wireless/ssv6051/smac/p2p.h new file mode 100644 -index 000000000000..a5bb99c61bb0 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/p2p.h @@ -0,0 +1,58 @@ @@ -42120,7 +42062,7 @@ index 000000000000..a5bb99c61bb0 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/sar.c b/drivers/net/wireless/ssv6051/smac/sar.c new file mode 100644 -index 000000000000..44a47a5c7a0f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/sar.c @@ -0,0 +1,208 @@ @@ -42334,7 +42276,7 @@ index 000000000000..44a47a5c7a0f +} diff --git a/drivers/net/wireless/ssv6051/smac/sar.h b/drivers/net/wireless/ssv6051/smac/sar.h new file mode 100644 -index 000000000000..291d58f236eb +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/sar.h @@ -0,0 +1,63 @@ @@ -42403,7 +42345,7 @@ index 000000000000..291d58f236eb +#endif diff --git a/drivers/net/wireless/ssv6051/smac/sec.h b/drivers/net/wireless/ssv6051/smac/sec.h new file mode 100644 -index 000000000000..04a0f47c8ce2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/sec.h @@ -0,0 +1,52 @@ @@ -42461,7 +42403,7 @@ index 000000000000..04a0f47c8ce2 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/smartlink.c b/drivers/net/wireless/ssv6051/smac/smartlink.c new file mode 100644 -index 000000000000..69e8d5118e09 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/smartlink.c @@ -0,0 +1,340 @@ @@ -42807,7 +42749,7 @@ index 000000000000..69e8d5118e09 +EXPORT_SYMBOL(ksmartlink_exit); diff --git a/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.c b/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.c new file mode 100644 -index 000000000000..9be5ea96e7f9 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.c @@ -0,0 +1,223 @@ @@ -43036,7 +42978,7 @@ index 000000000000..9be5ea96e7f9 +}; diff --git a/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.h b/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.h new file mode 100644 -index 000000000000..39caceadda4a +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv6xxx_debugfs.h @@ -0,0 +1,27 @@ @@ -43069,7 +43011,7 @@ index 000000000000..39caceadda4a +#endif diff --git a/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.c b/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.c new file mode 100644 -index 000000000000..f0135447b1f3 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.c @@ -0,0 +1,1384 @@ @@ -44459,7 +44401,7 @@ index 000000000000..f0135447b1f3 +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(SSV_VENDOR_EXT_SUPPORT) */ diff --git a/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.h b/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.h new file mode 100644 -index 000000000000..6d8696fcd220 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_cfgvendor.h @@ -0,0 +1,247 @@ @@ -44712,7 +44654,7 @@ index 000000000000..6d8696fcd220 +#endif /* _RTW_CFGVENDOR_H_ */ diff --git a/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c b/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c new file mode 100644 -index 000000000000..fae819c43400 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.c @@ -0,0 +1,546 @@ @@ -45264,7 +45206,7 @@ index 000000000000..fae819c43400 +} diff --git a/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h b/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h new file mode 100644 -index 000000000000..275c3356e036 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_ht_rc.h @@ -0,0 +1,31 @@ @@ -45301,7 +45243,7 @@ index 000000000000..275c3356e036 +#endif diff --git a/drivers/net/wireless/ssv6051/smac/ssv_pm.c b/drivers/net/wireless/ssv6051/smac/ssv_pm.c new file mode 100644 -index 000000000000..fc3be2013f61 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_pm.c @@ -0,0 +1,19 @@ @@ -45326,7 +45268,7 @@ index 000000000000..fc3be2013f61 +#include "sar.h" diff --git a/drivers/net/wireless/ssv6051/smac/ssv_pm.h b/drivers/net/wireless/ssv6051/smac/ssv_pm.h new file mode 100644 -index 000000000000..9be260dd904e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_pm.h @@ -0,0 +1,20 @@ @@ -45352,7 +45294,7 @@ index 000000000000..9be260dd904e +#endif diff --git a/drivers/net/wireless/ssv6051/smac/ssv_rc.c b/drivers/net/wireless/ssv6051/smac/ssv_rc.c new file mode 100644 -index 000000000000..9c3574285364 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_rc.c @@ -0,0 +1,1716 @@ @@ -47074,7 +47016,7 @@ index 000000000000..9c3574285364 +} diff --git a/drivers/net/wireless/ssv6051/smac/ssv_rc.h b/drivers/net/wireless/ssv6051/smac/ssv_rc.h new file mode 100644 -index 000000000000..911c182897fa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_rc.h @@ -0,0 +1,50 @@ @@ -47130,7 +47072,7 @@ index 000000000000..911c182897fa +#endif diff --git a/drivers/net/wireless/ssv6051/smac/ssv_rc_common.h b/drivers/net/wireless/ssv6051/smac/ssv_rc_common.h new file mode 100644 -index 000000000000..13f3fdd8072b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/smac/ssv_rc_common.h @@ -0,0 +1,175 @@ @@ -47311,7 +47253,7 @@ index 000000000000..13f3fdd8072b +#endif diff --git a/drivers/net/wireless/ssv6051/ssv6051-generic-wlan.c b/drivers/net/wireless/ssv6051/ssv6051-generic-wlan.c new file mode 100644 -index 000000000000..10a9a77081db +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/ssv6051-generic-wlan.c @@ -0,0 +1,76 @@ @@ -47393,7 +47335,7 @@ index 000000000000..10a9a77081db + diff --git a/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c b/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c new file mode 100644 -index 000000000000..503df1ea6dc3 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c @@ -0,0 +1,1765 @@ @@ -49164,7 +49106,7 @@ index 000000000000..503df1ea6dc3 +} diff --git a/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h b/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h new file mode 100644 -index 000000000000..d96bfcc54954 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h @@ -0,0 +1,50 @@ @@ -49220,7 +49162,7 @@ index 000000000000..d96bfcc54954 +#endif diff --git a/drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c b/drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c new file mode 100644 -index 000000000000..eb848553798f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c @@ -0,0 +1,256 @@ @@ -49481,5 +49423,5 @@ index 000000000000..eb848553798f +EXPORT_SYMBOL(ssvdevice_init); +EXPORT_SYMBOL(ssvdevice_exit); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0002-rockchip-from-list.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0002-rockchip-from-list.patch index fbb292deb..c62edf839 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0002-rockchip-from-list.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0002-rockchip-from-list.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 17 Feb 2019 22:14:38 +0000 -Subject: [PATCH] mmc: core: set initial signal voltage on power off +Subject: mmc: core: set initial signal voltage on power off Some boards have SD card connectors where the power rail cannot be switched off by the driver. If the card has not been power cycled, it may still be @@ -23,7 +23,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index ef53a2578824..d4c53074154a 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1368,6 +1368,14 @@ void mmc_power_off(struct mmc_host *host) @@ -41,4 +41,6 @@ index ef53a2578824..d4c53074154a 100644 mmc_pwrseq_power_off(host); host->ios.clock = 0; +-- +Armbian diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0011-v4l2-from-list.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0011-v4l2-from-list.patch index ed0c61c2c..be94fa982 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0011-v4l2-from-list.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-0011-v4l2-from-list.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:35 +0000 -Subject: [PATCH] media: v4l2-common: Add helpers to calculate bytesperline and +Subject: media: v4l2-common: Add helpers to calculate bytesperline and sizeimage Add helper functions to calculate plane bytesperline and sizeimage, these @@ -13,14 +13,14 @@ use of block width and height. Signed-off-by: Jonas Karlman --- - drivers/media/v4l2-core/v4l2-common.c | 77 +++++++++++++-------------- + drivers/media/v4l2-core/v4l2-common.c | 77 +++++----- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c -index e0fbe6ba4b6c..cb2f1acab7cf 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c -@@ -338,6 +338,33 @@ static inline unsigned int v4l2_format_block_height(const struct v4l2_format_inf +@@ -363,6 +363,33 @@ static inline unsigned int v4l2_format_block_height(const struct v4l2_format_inf return info->block_h[plane]; } @@ -54,7 +54,7 @@ index e0fbe6ba4b6c..cb2f1acab7cf 100644 void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, const struct v4l2_frmsize_stepwise *frmsize) { -@@ -373,37 +400,19 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, +@@ -398,37 +425,19 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, if (info->mem_planes == 1) { plane = &pixfmt->plane_fmt[0]; @@ -99,7 +99,7 @@ index e0fbe6ba4b6c..cb2f1acab7cf 100644 } } return 0; -@@ -427,22 +436,12 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, +@@ -452,22 +461,12 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, pixfmt->width = width; pixfmt->height = height; pixfmt->pixelformat = pixelformat; @@ -126,11 +126,13 @@ index e0fbe6ba4b6c..cb2f1acab7cf 100644 return 0; } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:36 +0000 -Subject: [PATCH] media: v4l2: Add NV15 and NV20 pixel formats +Subject: media: v4l2: Add NV15 and NV20 pixel formats Add NV15 and NV20 pixel formats used by the Rockchip Video Decoder for 10-bit buffers. @@ -154,12 +156,12 @@ Signed-off-by: Jonas Karlman 3 files changed, 8 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c -index cb2f1acab7cf..8446a1deffd8 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c -@@ -268,6 +268,9 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) - { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, +@@ -284,6 +284,9 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) { .format = V4L2_PIX_FMT_P010, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_P012, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV15, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 5, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2, .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 } }, + { .format = V4L2_PIX_FMT_NV20, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 5, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1, .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 } }, @@ -168,10 +170,10 @@ index cb2f1acab7cf..8446a1deffd8 100644 { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 4 }, { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 1 }, diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c -index e6fd355a2e92..24771edaa4f2 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c -@@ -1354,6 +1354,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +@@ -1366,6 +1366,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_NV42: descr = "Y/VU 4:4:4"; break; case V4L2_PIX_FMT_P010: descr = "10-bit Y/UV 4:2:0"; break; case V4L2_PIX_FMT_P012: descr = "12-bit Y/UV 4:2:0"; break; @@ -181,25 +183,27 @@ index e6fd355a2e92..24771edaa4f2 100644 case V4L2_PIX_FMT_NV12_16L16: descr = "Y/UV 4:2:0 (16x16 Linear)"; break; case V4L2_PIX_FMT_NV12_32L32: descr = "Y/UV 4:2:0 (32x32 Linear)"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h -index 01e630f2ec78..cea44992aea3 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -628,6 +628,9 @@ struct v4l2_pix_format { - #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/VU 4:4:4 */ - #define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0') /* 24 Y/UV 4:2:0 10-bit per component */ +@@ -650,6 +650,9 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0') /* 24 Y/CbCr 4:2:0 10-bit per component */ + #define V4L2_PIX_FMT_P012 v4l2_fourcc('P', '0', '1', '2') /* 24 Y/CbCr 4:2:0 12-bit per component */ +#define V4L2_PIX_FMT_NV15 v4l2_fourcc('N', 'V', '1', '5') /* 15 Y/UV 4:2:0 10-bit packed */ +#define V4L2_PIX_FMT_NV20 v4l2_fourcc('N', 'V', '2', '0') /* 20 Y/UV 4:2:2 10-bit packed */ + /* two non contiguous planes - one Y, one Cr + Cb interleaved */ - #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/UV 4:2:0 */ - #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/VU 4:2:0 */ + #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ + #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:36 +0000 -Subject: [PATCH] media: rkvdec: h264: Use bytesperline and buffer height to - calculate stride +Subject: media: rkvdec: h264: Use bytesperline and buffer height to calculate + stride Use bytesperline and buffer height to calculate the strides configured. @@ -212,7 +216,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index 4fc167b42cf0..a8635105e387 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -896,9 +896,9 @@ static void config_registers(struct rkvdec_ctx *ctx, @@ -239,12 +243,13 @@ index 4fc167b42cf0..a8635105e387 100644 y_virstride = hor_virstride * ver_virstride; if (sps->chroma_format_idc == 0) +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:37 +0000 -Subject: [PATCH] media: rkvdec: Extract rkvdec_fill_decoded_pixfmt helper - method +Subject: media: rkvdec: Extract rkvdec_fill_decoded_pixfmt helper method This extract setting decoded pixfmt into a helper method, current code is replaced with a call to the new helper method. @@ -253,11 +258,11 @@ The helper method is also called from a new function in next patch. Signed-off-by: Jonas Karlman --- - drivers/staging/media/rkvdec/rkvdec.c | 29 ++++++++++++++------------- + drivers/staging/media/rkvdec/rkvdec.c | 29 +++++----- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 7bab7586918c..40cc791aef26 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -27,6 +27,17 @@ @@ -295,7 +300,7 @@ index 7bab7586918c..40cc791aef26 100644 } static int rkvdec_enum_framesizes(struct file *file, void *priv, -@@ -264,13 +271,7 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, +@@ -270,13 +277,7 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, &pix_mp->height, &coded_desc->frmsize); @@ -310,11 +315,13 @@ index 7bab7586918c..40cc791aef26 100644 return 0; } +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:37 +0000 -Subject: [PATCH] media: rkvdec: Lock capture pixel format in s_ctrl and s_fmt +Subject: media: rkvdec: Lock capture pixel format in s_ctrl and s_fmt Add an optional valid_fmt operation that should return the valid pixelformat of CAPTURE buffers. @@ -324,12 +331,12 @@ and 4:2:2 content. Signed-off-by: Jonas Karlman --- - drivers/staging/media/rkvdec/rkvdec.c | 67 +++++++++++++++++++++++---- + drivers/staging/media/rkvdec/rkvdec.c | 67 ++++++++-- drivers/staging/media/rkvdec/rkvdec.h | 2 + 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 40cc791aef26..e93e1cb0f829 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -38,19 +38,56 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, @@ -399,7 +406,7 @@ index 40cc791aef26..e93e1cb0f829 100644 rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; f->fmt.pix_mp.width = ctx->coded_fmt.fmt.pix_mp.width; -@@ -256,13 +294,17 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, +@@ -262,13 +300,17 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, if (WARN_ON(!coded_desc)) return -EINVAL; @@ -423,7 +430,7 @@ index 40cc791aef26..e93e1cb0f829 100644 /* Always apply the frmsize constraint of the coded end. */ pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width); -@@ -326,6 +368,7 @@ static int rkvdec_s_capture_fmt(struct file *file, void *priv, +@@ -332,6 +374,7 @@ static int rkvdec_s_capture_fmt(struct file *file, void *priv, return ret; ctx->decoded_fmt = *f; @@ -431,7 +438,7 @@ index 40cc791aef26..e93e1cb0f829 100644 return 0; } -@@ -429,6 +472,14 @@ static int rkvdec_enum_capture_fmt(struct file *file, void *priv, +@@ -435,6 +478,14 @@ static int rkvdec_enum_capture_fmt(struct file *file, void *priv, if (WARN_ON(!ctx->coded_fmt_desc)) return -EINVAL; @@ -447,7 +454,7 @@ index 40cc791aef26..e93e1cb0f829 100644 return -EINVAL; diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -index 633335ebb9c4..b9e219438bc9 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ b/drivers/staging/media/rkvdec/rkvdec.h @@ -66,6 +66,7 @@ vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) @@ -466,11 +473,13 @@ index 633335ebb9c4..b9e219438bc9 100644 const struct rkvdec_coded_fmt_desc *coded_fmt_desc; struct v4l2_ctrl_handler ctrl_hdl; struct rkvdec_dev *dev; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 6 Jul 2020 21:54:37 +0000 -Subject: [PATCH] media: rkvdec: h264: Support High 10 and 4:2:2 profiles +Subject: media: rkvdec: h264: Support High 10 and 4:2:2 profiles Add support and enable decoding of H264 High 10 and 4:2:2 profiles. @@ -482,12 +491,12 @@ for the provided SPS control. Signed-off-by: Jonas Karlman --- - drivers/staging/media/rkvdec/rkvdec-h264.c | 33 ++++++++++++++++------ - drivers/staging/media/rkvdec/rkvdec.c | 19 +++++++++---- + drivers/staging/media/rkvdec/rkvdec-h264.c | 33 +++++++--- + drivers/staging/media/rkvdec/rkvdec.c | 19 ++++-- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index a8635105e387..0069d3d198db 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -1031,19 +1031,14 @@ static int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, @@ -549,7 +558,7 @@ index a8635105e387..0069d3d198db 100644 .stop = rkvdec_h264_stop, .run = rkvdec_h264_run, diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index e93e1cb0f829..4f5436c89e08 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -31,7 +31,7 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, @@ -607,11 +616,13 @@ index e93e1cb0f829..4f5436c89e08 100644 } }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 27 Mar 2022 14:18:07 +0200 -Subject: [PATCH] media: rkvdec-h264: Don't hardcode SPS/PPS parameters +Subject: media: rkvdec-h264: Don't hardcode SPS/PPS parameters Some SPS/PPS parameters are currently hardcoded in the driver even though so do exist in the uapi which is stable by now. @@ -620,11 +631,11 @@ Use them instead of hardcoding them. Signed-off-by: Alex Bee --- - drivers/staging/media/rkvdec/rkvdec-h264.c | 13 +++++++------ + drivers/staging/media/rkvdec/rkvdec-h264.c | 13 +++++----- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index 0069d3d198db..2c27acaba85e 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -655,13 +655,14 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, @@ -657,3 +668,6 @@ index 0069d3d198db..2c27acaba85e 100644 WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE), ENTROPY_CODING_MODE_FLAG); WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT), +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1000-drm-rockchip.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1000-drm-rockchip.patch index 6af1e51fe..2c4d28e28 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1000-drm-rockchip.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1000-drm-rockchip.patch @@ -1,8 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 3 May 2020 16:51:31 +0000 -Subject: [PATCH] drm/rockchip: vop: filter modes outside 0.5% pixel clock - tolerance +Subject: drm/rockchip: vop: filter modes outside 0.5% pixel clock tolerance Filter modes that require a pixel clock that differ more then 0.5% from the requested pixel clock. @@ -12,15 +11,15 @@ This filter is only applied to tmds only connector and/or encoders. Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 54 +++++++++++++++++++++ - 1 file changed, 54 insertions(+) + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 53 ++++++++++ + 1 file changed, 53 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index dbe4d411b30f..fac23d370ee0 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -1207,6 +1207,59 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc) - spin_unlock_irqrestore(&vop->irq_lock, flags); +@@ -1207,6 +1207,59 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + return MODE_OK; } +static bool vop_crtc_is_tmds(struct drm_crtc *crtc) @@ -79,11 +78,13 @@ index dbe4d411b30f..fac23d370ee0 100644 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 15:15:50 +0000 -Subject: [PATCH] drm/rockchip: vop: filter interlaced modes +Subject: drm/rockchip: vop: filter interlaced modes The current version of the driver does not support interlaced modes, lets filter any interlaced mode. @@ -94,10 +95,10 @@ Signed-off-by: Jonas Karlman 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index fac23d370ee0..9f7326c5b1f5 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -1245,6 +1245,9 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, +@@ -1245,6 +1245,9 @@ static enum drm_mode_status vop_crtc_mode_valid5(struct drm_crtc *crtc, if (!vop_crtc_is_tmds(crtc)) return MODE_OK; @@ -107,22 +108,24 @@ index fac23d370ee0..9f7326c5b1f5 100644 rounded_rate = clk_round_rate(vop->dclk, mode->clock * 1000 + 999); if (rounded_rate < 0) return MODE_NOCLOCK; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 11:46:16 +0000 -Subject: [PATCH] drm/rockchip: vop: filter modes above max output supported +Subject: drm/rockchip: vop: filter modes above max output supported Filter any mode with a resolution not supported by the VOP. Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 48 +++++++++++++++------ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 48 +++++++--- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 9f7326c5b1f5..30e252ba7184 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1229,6 +1229,24 @@ static bool vop_crtc_is_tmds(struct drm_crtc *crtc) @@ -150,7 +153,7 @@ index 9f7326c5b1f5..30e252ba7184 100644 /* * The VESA DMT standard specifies a 0.5% pixel clock frequency tolerance. * The CVT spec reuses that tolerance in its examples. -@@ -1242,25 +1260,24 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, +@@ -1242,25 +1260,24 @@ static enum drm_mode_status vop_crtc_mode_valid5(struct drm_crtc *crtc, long rounded_rate; long lowest, highest; @@ -199,11 +202,13 @@ index 9f7326c5b1f5..30e252ba7184 100644 /* * Clock craziness. * +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Mon, 11 Jul 2016 19:05:39 +0800 -Subject: [PATCH] drm/rockchip: dw_hdmi: adjust cklvl & txlvl for RF/EMI +Subject: drm/rockchip: dw_hdmi: adjust cklvl & txlvl for RF/EMI Dut to the high HDMI signal voltage driver, Mickey have meet a serious RF/EMI problem, so we decided to reduce HDMI signal @@ -241,7 +246,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index c14f88893868..4411ca8fd7ed 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -201,7 +201,7 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { @@ -253,11 +258,13 @@ index c14f88893868..4411ca8fd7ed 100644 { 297000000, 0x8039, 0x0005, 0x028d}, { ~0UL, 0x0000, 0x0000, 0x0000} }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nickey Yang Date: Mon, 13 Feb 2017 15:40:29 +0800 -Subject: [PATCH] drm/rockchip: dw_hdmi: add phy_config for 594Mhz pixel clock +Subject: drm/rockchip: dw_hdmi: add phy_config for 594Mhz pixel clock Add phy_config for 594Mhz pixel clock used for 4K@60hz @@ -268,7 +275,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 4411ca8fd7ed..bec381cde0bc 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -203,6 +203,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = { @@ -279,11 +286,13 @@ index 4411ca8fd7ed..bec381cde0bc 100644 { ~0UL, 0x0000, 0x0000, 0x0000} }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 11 Jul 2016 19:05:36 +0800 -Subject: [PATCH] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always +Subject: drm/rockchip: dw_hdmi: Set cur_ctr to 0 always Jitter was improved by lowering the MPLL bandwidth to account for high frequency noise in the rk3288 PLL. In each case MPLL bandwidth was @@ -294,11 +303,11 @@ Signed-off-by: Douglas Anderson Signed-off-by: Yakir Yang Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 14 ---------- + 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index bec381cde0bc..72c1d65c7b75 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -178,20 +178,6 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { @@ -320,24 +329,26 @@ index bec381cde0bc..72c1d65c7b75 100644 - 148500000, { 0x0000, 0x0038, 0x0038 }, - }, { 600000000, { 0x0000, 0x0000, 0x0000 }, - }, { + }, { ~0UL, { 0x0000, 0x0000, 0x0000}, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 10:16:32 +0000 -Subject: [PATCH] drm/rockchip: dw-hdmi: encoder error handling +Subject: drm/rockchip: dw-hdmi: encoder error handling Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 11 +++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 38dded2baaf7..9e460b7e14a4 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -592,7 +592,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -590,7 +590,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, if (IS_ERR(hdmi->phy)) { ret = PTR_ERR(hdmi->phy); if (ret != -EPROBE_DEFER) @@ -346,7 +357,7 @@ index 38dded2baaf7..9e460b7e14a4 100644 return ret; } -@@ -605,7 +605,12 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -603,7 +603,12 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, } drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); @@ -360,7 +371,7 @@ index 38dded2baaf7..9e460b7e14a4 100644 platform_set_drvdata(pdev, hdmi); -@@ -624,7 +629,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -622,7 +627,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, err_bind: drm_encoder_cleanup(encoder); @@ -369,22 +380,24 @@ index 38dded2baaf7..9e460b7e14a4 100644 return ret; } +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 14:32:21 +0000 -Subject: [PATCH] drm/rockchip: vop: split rk3288 vop +Subject: drm/rockchip: vop: split rk3288 vop Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 21 ++++++++++++++++++--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 21 ++++++++-- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 9b25b8ffd0ce..a2b281e290e0 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -740,7 +740,7 @@ static const struct vop_intr rk3288_vop_intr = { +@@ -762,7 +762,7 @@ static const struct vop_intr rk3288_vop_intr = { .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), }; @@ -392,9 +405,9 @@ index 9b25b8ffd0ce..a2b281e290e0 100644 +static const struct vop_data rk3288_vop_big = { .version = VOP_VERSION(3, 1), .feature = VOP_FEATURE_OUTPUT_RGB10, + .intr = &rk3288_vop_intr, +@@ -780,6 +780,19 @@ static const struct vop_data rk3288_vop = { .max_output = { 3840, 2160 }, -@@ -753,6 +753,19 @@ static const struct vop_data rk3288_vop = { - .lut_size = 1024, }; +static const struct vop_data rk3288_vop_lit = { @@ -413,7 +426,7 @@ index 9b25b8ffd0ce..a2b281e290e0 100644 static const int rk3368_vop_intrs[] = { FS_INTR, 0, 0, -@@ -1142,8 +1155,10 @@ static const struct of_device_id vop_driver_dt_match[] = { +@@ -1245,8 +1258,10 @@ static const struct of_device_id vop_driver_dt_match[] = { .data = &rk3066_vop }, { .compatible = "rockchip,rk3188-vop", .data = &rk3188_vop }, @@ -426,11 +439,13 @@ index 9b25b8ffd0ce..a2b281e290e0 100644 { .compatible = "rockchip,rk3368-vop", .data = &rk3368_vop }, { .compatible = "rockchip,rk3366-vop", +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 14:33:30 +0000 -Subject: [PATCH] ARM: dts: rockchip: split rk3288 vop +Subject: ARM: dts: rockchip: split rk3288 vop Signed-off-by: Jonas Karlman --- @@ -438,10 +453,10 @@ Signed-off-by: Jonas Karlman 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 487b0e03d4b4..c60eacab8a79 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1017,7 +1017,7 @@ rga: rga@ff920000 { +@@ -1026,7 +1026,7 @@ rga: rga@ff920000 { }; vopb: vop@ff930000 { @@ -450,7 +465,7 @@ index 487b0e03d4b4..c60eacab8a79 100644 reg = <0x0 0xff930000 0x0 0x19c>, <0x0 0xff931000 0x0 0x1000>; interrupts = ; clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; -@@ -1066,7 +1066,7 @@ vopb_mmu: iommu@ff930300 { +@@ -1075,7 +1075,7 @@ vopb_mmu: iommu@ff930300 { }; vopl: vop@ff940000 { @@ -459,25 +474,26 @@ index 487b0e03d4b4..c60eacab8a79 100644 reg = <0x0 0xff940000 0x0 0x19c>, <0x0 0xff941000 0x0 0x1000>; interrupts = ; clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 18:00:44 +0000 -Subject: [PATCH] drm/bridge: dw-hdmi: add mtmdsclock parameter to phy - configure ops +Subject: drm/bridge: dw-hdmi: add mtmdsclock parameter to phy configure ops Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 ++++++---- - drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c | 3 ++- - include/drm/bridge/dw_hdmi.h | 3 ++- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 ++++++---- + drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c | 3 ++- + include/drm/bridge/dw_hdmi.h | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 40d8ca37f5bc..22af42a08980 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -138,7 +138,8 @@ struct dw_hdmi_phy_data { +@@ -125,7 +125,8 @@ struct dw_hdmi_phy_data { bool has_svsret; int (*configure)(struct dw_hdmi *hdmi, const struct dw_hdmi_plat_data *pdata, @@ -487,7 +503,7 @@ index 40d8ca37f5bc..22af42a08980 100644 }; struct dw_hdmi { -@@ -1585,7 +1586,8 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) +@@ -1568,7 +1569,8 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) */ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, const struct dw_hdmi_plat_data *pdata, @@ -497,7 +513,7 @@ index 40d8ca37f5bc..22af42a08980 100644 { const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; -@@ -1660,9 +1662,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, +@@ -1643,9 +1645,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, /* Write to the PHY as configured by the platform */ if (pdata->configure_phy) @@ -510,7 +526,7 @@ index 40d8ca37f5bc..22af42a08980 100644 dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", mpixelclock); diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c -index 18ed14911b98..9c75095a25c5 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c @@ -53,7 +53,8 @@ rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, @@ -524,7 +540,7 @@ index 18ed14911b98..9c75095a25c5 100644 const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index f668e75fbabe..48fb72f9614f 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -159,7 +159,8 @@ struct dw_hdmi_plat_data { @@ -537,24 +553,26 @@ index f668e75fbabe..48fb72f9614f 100644 unsigned int disable_cec : 1; }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 21:34:48 +0000 -Subject: [PATCH] drm/bridge: dw-hdmi: support configuring phy for deep color +Subject: drm/bridge: dw-hdmi: support configuring phy for deep color Q: Should we rename dw_hdmi_curr_ctrl and dw_hdmi_phy_config mpixelclock to mtmdsclock ? Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 ++++++++++++----- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +++++++--- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 22af42a08980..7fd45a7006b1 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1592,6 +1592,7 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, +@@ -1575,6 +1575,7 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; @@ -562,7 +580,7 @@ index 22af42a08980..7fd45a7006b1 100644 /* TOFIX Will need 420 specific PHY configuration tables */ -@@ -1601,11 +1602,11 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, +@@ -1584,11 +1585,11 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, break; for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) @@ -576,7 +594,7 @@ index 22af42a08980..7fd45a7006b1 100644 break; if (mpll_config->mpixelclock == ~0UL || -@@ -1613,11 +1614,17 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, +@@ -1596,11 +1597,17 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, phy_config->mpixelclock == ~0UL) return -EINVAL; @@ -597,11 +615,13 @@ index 22af42a08980..7fd45a7006b1 100644 HDMI_3D_TX_PHY_CURRCTRL); dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 22:25:15 +0000 -Subject: [PATCH] drm/bridge: dw-hdmi: add mpll_cfg_420 for ycbcr420 mode +Subject: drm/bridge: dw-hdmi: add mpll_cfg_420 for ycbcr420 mode Signed-off-by: Jonas Karlman --- @@ -610,10 +630,10 @@ Signed-off-by: Jonas Karlman 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 7fd45a7006b1..a2d101ebf7a7 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1594,7 +1594,9 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, +@@ -1577,7 +1577,9 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; int depth; @@ -625,7 +645,7 @@ index 7fd45a7006b1..a2d101ebf7a7 100644 /* PLL/MPLL Cfg - always match on final entry */ for (; mpll_config->mpixelclock != ~0UL; mpll_config++) diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 48fb72f9614f..02554d324b4b 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -156,6 +156,7 @@ struct dw_hdmi_plat_data { @@ -636,22 +656,24 @@ index 48fb72f9614f..02554d324b4b 100644 const struct dw_hdmi_curr_ctrl *cur_ctr; const struct dw_hdmi_phy_config *phy_config; int (*configure_phy)(struct dw_hdmi *hdmi, void *data, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 22:26:19 +0000 -Subject: [PATCH] drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3399 +Subject: drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3399 Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 ++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index d42ac9fa3246..a37565649c13 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -177,6 +177,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { +@@ -175,6 +175,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { } }; @@ -698,7 +720,7 @@ index d42ac9fa3246..a37565649c13 100644 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ { -@@ -474,6 +514,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { +@@ -495,6 +535,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { .mode_valid = dw_hdmi_rockchip_mode_valid, .mpll_cfg = rockchip_mpll_cfg, @@ -706,23 +728,25 @@ index d42ac9fa3246..a37565649c13 100644 .cur_ctr = rockchip_cur_ctr, .phy_config = rockchip_phy_config, .phy_data = &rk3399_chip_data, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shunqing Chen Date: Wed, 15 Jul 2020 15:19:11 +0800 -Subject: [PATCH] drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3288w +Subject: drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3288w Signed-off-by: Shunqing Chen Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 ++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index a37565649c13..66fee351f4a7 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -217,6 +217,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = { +@@ -215,6 +215,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = { } }; @@ -769,7 +793,7 @@ index a37565649c13..66fee351f4a7 100644 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ { -@@ -479,6 +519,7 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = { +@@ -498,6 +538,7 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = { static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = { .mode_valid = dw_hdmi_rockchip_mode_valid, .mpll_cfg = rockchip_mpll_cfg, @@ -777,12 +801,13 @@ index a37565649c13..66fee351f4a7 100644 .cur_ctr = rockchip_cur_ctr, .phy_config = rockchip_phy_config, .phy_data = &rk3288_chip_data, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 20 Dec 2019 08:12:42 +0000 -Subject: [PATCH] drm/rockchip: dw-hdmi: add bridge and switch to - drm_bridge_funcs +Subject: drm/rockchip: dw-hdmi: add bridge and switch to drm_bridge_funcs Switch the dw-hdmi driver to drm_bridge_funcs by implementing a new local bridge, connecting it to the dw-hdmi bridge. @@ -792,11 +817,11 @@ atomic_get_input_bus_fmts and support for 8-bit RGB 4:4:4. Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 118 ++++++++++++++------ + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 118 +++++++--- 1 file changed, 81 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 66fee351f4a7..d6d8f3335813 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -5,6 +5,7 @@ @@ -807,14 +832,14 @@ index 66fee351f4a7..d6d8f3335813 100644 #include #include #include -@@ -72,6 +73,7 @@ struct rockchip_hdmi_chip_data { +@@ -73,6 +74,7 @@ struct rockchip_hdmi_chip_data { struct rockchip_hdmi { struct device *dev; struct regmap *regmap; + struct drm_bridge bridge; struct rockchip_encoder encoder; const struct rockchip_hdmi_chip_data *chip_data; - struct clk *ref_clk; + const struct dw_hdmi_plat_data *plat_data; @@ -82,11 +84,9 @@ struct rockchip_hdmi { struct phy *phy; }; @@ -829,9 +854,9 @@ index 66fee351f4a7..d6d8f3335813 100644 } static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { -@@ -335,31 +335,21 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, +@@ -351,31 +351,21 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, - return MODE_OK; + return MODE_BAD; } - -static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) @@ -870,8 +895,8 @@ index 66fee351f4a7..d6d8f3335813 100644 u32 val; int ret; -@@ -387,10 +377,21 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) - ret ? "LIT" : "BIG"); +@@ -402,10 +392,21 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) + drm_dbg(hdmi, "vop %s output to hdmi\n", ret ? "LIT" : "BIG"); } +static bool is_rgb(u32 format) @@ -895,7 +920,7 @@ index 66fee351f4a7..d6d8f3335813 100644 { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); -@@ -400,12 +401,38 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, +@@ -415,12 +416,38 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, return 0; } @@ -940,7 +965,7 @@ index 66fee351f4a7..d6d8f3335813 100644 }; static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, -@@ -602,6 +629,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -624,6 +651,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, struct dw_hdmi_plat_data *plat_data; const struct of_device_id *match; struct drm_device *drm = data; @@ -948,7 +973,7 @@ index 66fee351f4a7..d6d8f3335813 100644 struct drm_encoder *encoder; struct rockchip_hdmi *hdmi; int ret; -@@ -679,20 +707,21 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -684,20 +712,21 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, RK3568_HDMI_SCLIN_MSK)); } @@ -974,7 +999,7 @@ index 66fee351f4a7..d6d8f3335813 100644 * which would have called the encoder cleanup. Do it manually. */ if (IS_ERR(hdmi->hdmi)) { -@@ -700,8 +729,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, +@@ -705,8 +734,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, goto err_bind; } @@ -998,20 +1023,22 @@ index 66fee351f4a7..d6d8f3335813 100644 err_bind: drm_encoder_cleanup(encoder); err_disable_clk: -@@ -719,7 +763,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, +@@ -718,7 +762,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, { struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); - dw_hdmi_unbind(hdmi->hdmi); + dw_hdmi_remove(hdmi->hdmi); drm_encoder_cleanup(&hdmi->encoder.encoder); - clk_disable_unprepare(hdmi->ref_clk); + } +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 9 Oct 2020 15:29:27 +0000 -Subject: [PATCH] drm/rockchip: vop: add immutable zpos property +Subject: drm/rockchip: vop: add immutable zpos property Signed-off-by: Jonas Karlman --- @@ -1020,10 +1047,10 @@ Signed-off-by: Jonas Karlman 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c -index 092bf863110b..e2ee0d6a8d55 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c -@@ -133,6 +133,8 @@ void rockchip_drm_mode_config_init(struct drm_device *dev) +@@ -81,6 +81,8 @@ void rockchip_drm_mode_config_init(struct drm_device *dev) dev->mode_config.max_width = 4096; dev->mode_config.max_height = 4096; @@ -1033,7 +1060,7 @@ index 092bf863110b..e2ee0d6a8d55 100644 dev->mode_config.helper_private = &rockchip_mode_config_helpers; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 30e252ba7184..897f7980ee5d 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1917,7 +1917,7 @@ static irqreturn_t vop_isr(int irq, void *data) @@ -1063,19 +1090,21 @@ index 30e252ba7184..897f7980ee5d 100644 if (plane->type == DRM_PLANE_TYPE_PRIMARY) primary = plane; else if (plane->type == DRM_PLANE_TYPE_CURSOR) +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 09:20:44 +0000 -Subject: [PATCH] drm/rockchip: vop: add plane color properties +Subject: drm/rockchip: vop: add plane color properties Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 32 +++++++++++++++++++-- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 32 +++++++++- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 897f7980ee5d..eadf1b0f1704 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1917,8 +1917,23 @@ static irqreturn_t vop_isr(int irq, void *data) @@ -1132,12 +1161,13 @@ index 897f7980ee5d..eadf1b0f1704 100644 if (plane->type == DRM_PLANE_TYPE_PRIMARY) primary = plane; else if (plane->type == DRM_PLANE_TYPE_CURSOR) +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nickey Yang Date: Mon, 17 Jul 2017 16:35:34 +0800 -Subject: [PATCH] HACK: clk: rockchip: rk3288: dedicate npll for vopb and hdmi - use +Subject: HACK: clk: rockchip: rk3288: dedicate npll for vopb and hdmi use MINIARM: set npll be used for hdmi only @@ -1145,15 +1175,15 @@ Signed-off-by: Nickey Yang Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- - arch/arm/boot/dts/rockchip/rk3288.dtsi | 2 ++ - drivers/clk/rockchip/clk-rk3288.c | 9 +++++---- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 2 ++ + drivers/clk/rockchip/clk-rk3288.c | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index c60eacab8a79..d1ae42757242 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1026,6 +1026,8 @@ vopb: vop@ff930000 { +@@ -1035,6 +1035,8 @@ vopb: vop@ff930000 { resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>; reset-names = "axi", "ahb", "dclk"; iommus = <&vopb_mmu>; @@ -1163,7 +1193,7 @@ index c60eacab8a79..d1ae42757242 100644 vopb_out: port { diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c -index baa5aebd3277..5cfcbaaa154e 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,9 @@ PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; @@ -1196,23 +1226,25 @@ index baa5aebd3277..5cfcbaaa154e 100644 RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, RK3288_CLKGATE_CON(3), 1, GFLAGS), COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 4 Aug 2018 14:51:14 +0200 -Subject: [PATCH] HACK: clk: rockchip: rk3288: use npll table to to improve - HDMI compatibility +Subject: HACK: clk: rockchip: rk3288: use npll table to to improve HDMI + compatibility Based on https://github.com/TinkerBoard/debian_kernel/commit/3d90870530b8a2901681f7b7fa598ee7381e49f3 Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- - drivers/clk/rockchip/clk-rk3288.c | 39 ++++++++++++++++++++++++++++++- + drivers/clk/rockchip/clk-rk3288.c | 39 +++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c -index 5cfcbaaa154e..fa1c6e646bdf 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -121,6 +121,43 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = { @@ -1268,12 +1300,13 @@ index 5cfcbaaa154e..fa1c6e646bdf 100644 }; static struct clk_div_table div_hclk_cpu_t[] = { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 25 May 2020 20:36:45 +0000 -Subject: [PATCH] HACK: clk: rockchip: rk3399: dedicate vpll for vopb and hdmi - use +Subject: HACK: clk: rockchip: rk3399: dedicate vpll for vopb and hdmi use Rockchip PLLs are kown provide the least jitter for vco rates between 800 MHz and 2 GHz. I added the @@ -1287,11 +1320,11 @@ output. Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- - drivers/clk/rockchip/clk-rk3399.c | 49 ++++++++++++++++++++++++++----- + drivers/clk/rockchip/clk-rk3399.c | 49 ++++++++-- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c -index 306910a3a0d3..436d2789611c 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -105,6 +105,39 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { @@ -1386,22 +1419,24 @@ index 306910a3a0d3..436d2789611c 100644 RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, RK3399_CLKGATE_CON(10), 12, GFLAGS), +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 19 Jul 2020 16:35:11 +0000 -Subject: [PATCH] HACK: dts: rockchip: do not use vopl for hdmi +Subject: HACK: dts: rockchip: do not use vopl for hdmi --- - arch/arm/boot/dts/rockchip/rk3288.dtsi | 9 --------- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 9 --------- arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 9 --------- 2 files changed, 18 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index d1ae42757242..7b2cde230b87 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1083,11 +1083,6 @@ vopl_out: port { +@@ -1092,11 +1092,6 @@ vopl_out: port { #address-cells = <1>; #size-cells = <0>; @@ -1413,7 +1448,7 @@ index d1ae42757242..7b2cde230b87 100644 vopl_out_edp: endpoint@1 { reg = <1>; remote-endpoint = <&edp_in_vopl>; -@@ -1227,10 +1222,6 @@ hdmi_in_vopb: endpoint@0 { +@@ -1264,10 +1259,6 @@ hdmi_in_vopb: endpoint@0 { remote-endpoint = <&vopb_out_hdmi>; }; @@ -1422,10 +1457,10 @@ index d1ae42757242..7b2cde230b87 100644 - remote-endpoint = <&vopl_out_hdmi>; - }; }; - }; + hdmi_out: port@1 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -index 92c2207e686c..980b12cb0a49 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi @@ -1846,11 +1846,6 @@ vopl_out_edp: endpoint@1 { @@ -1449,24 +1484,25 @@ index 92c2207e686c..980b12cb0a49 100644 - remote-endpoint = <&vopl_out_hdmi>; - }; }; - }; - }; + + hdmi_out: port@1 { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 20 Dec 2019 08:12:43 +0000 -Subject: [PATCH] WIP: drm/bridge: dw-hdmi: limit mode and bus format to - max_tmds_clock +Subject: WIP: drm/bridge: dw-hdmi: limit mode and bus format to max_tmds_clock --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 120 ++++++++++++++-------- - 1 file changed, 76 insertions(+), 44 deletions(-) + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 117 ++++++---- + 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index a2d101ebf7a7..7f6ffbc3e7b2 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -2003,6 +2003,21 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi, +@@ -1986,6 +1986,21 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi, HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN); } @@ -1488,7 +1524,7 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 static void hdmi_av_composer(struct dw_hdmi *hdmi, const struct drm_display_info *display, const struct drm_display_mode *mode) -@@ -2014,29 +2029,11 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, +@@ -1997,29 +2012,11 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, unsigned int vdisplay, hdisplay; vmode->mpixelclock = mode->clock * 1000; @@ -1521,7 +1557,7 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock); /* Set up HDMI_FC_INVIDCONF */ -@@ -2663,8 +2660,21 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) +@@ -2645,8 +2642,21 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) * - MEDIA_BUS_FMT_RGB888_1X24, */ @@ -1545,7 +1581,7 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, -@@ -2676,8 +2686,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -2658,8 +2668,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, struct drm_display_info *info = &conn->display_info; struct drm_display_mode *mode = &crtc_state->mode; u8 max_bpc = conn_state->max_requested_bpc; @@ -1554,7 +1590,7 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 u32 *output_fmts; unsigned int i = 0; -@@ -2701,25 +2709,28 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -2683,25 +2691,28 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, * If the current mode enforces 4:2:0, force the output but format * to 4:2:0 and do not add the YUV422/444/RGB formats */ @@ -1588,9 +1624,9 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 + if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY8_0_5X24)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; - if (drm_mode_is_420_only(info, mode)) + if (drm_mode_is_420_only(info, mode)) { *num_output_fmts = i; -@@ -2732,40 +2744,51 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -2715,39 +2726,50 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, */ /* Default 8bit RGB fallback */ @@ -1652,8 +1688,7 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; *num_output_fmts = i; - -@@ -2946,11 +2969,20 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, +@@ -2929,11 +2951,20 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, struct dw_hdmi *hdmi = bridge->driver_private; const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; enum drm_mode_status mode_status = MODE_OK; @@ -1674,19 +1709,21 @@ index a2d101ebf7a7..7f6ffbc3e7b2 100644 if (pdata->mode_valid) mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info, mode); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 20 Dec 2019 08:12:42 +0000 -Subject: [PATCH] WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format +Subject: WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 42 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 42 ++++++++++ drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + 2 files changed, 43 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index d6d8f3335813..89424c5bc24a 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -84,6 +84,8 @@ struct rockchip_hdmi { @@ -1698,7 +1735,7 @@ index d6d8f3335813..89424c5bc24a 100644 static struct rockchip_hdmi *to_rockchip_hdmi(struct drm_bridge *bridge) { return container_of(bridge, struct rockchip_hdmi, bridge); -@@ -341,6 +343,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, +@@ -357,6 +359,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *adjusted_mode) { struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); @@ -1710,7 +1747,7 @@ index d6d8f3335813..89424c5bc24a 100644 clk_set_rate(hdmi->ref_clk, adjusted_mode->clock * 1000); } -@@ -381,6 +388,17 @@ static bool is_rgb(u32 format) +@@ -396,6 +403,17 @@ static bool is_rgb(u32 format) { switch (format) { case MEDIA_BUS_FMT_RGB888_1X24: @@ -1728,7 +1765,7 @@ index d6d8f3335813..89424c5bc24a 100644 return true; default: return false; -@@ -394,9 +412,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -409,9 +427,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); @@ -1753,7 +1790,7 @@ index d6d8f3335813..89424c5bc24a 100644 return 0; } -@@ -408,10 +441,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -423,10 +456,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, u32 output_fmt, unsigned int *num_input_fmts) { @@ -1774,10 +1811,10 @@ index d6d8f3335813..89424c5bc24a 100644 return NULL; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -index 1641440837af..381e5ccab5f3 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -@@ -34,6 +34,7 @@ struct rockchip_crtc_state { +@@ -53,6 +53,7 @@ struct rockchip_crtc_state { u32 bus_format; u32 bus_flags; int color_space; @@ -1785,11 +1822,13 @@ index 1641440837af..381e5ccab5f3 100644 }; #define to_rockchip_crtc_state(s) \ container_of(s, struct rockchip_crtc_state, base) +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 8 Dec 2019 23:42:44 +0000 -Subject: [PATCH] WIP: drm: dw-hdmi: add content type connector property +Subject: WIP: drm: dw-hdmi: add content type connector property Signed-off-by: Jonas Karlman --- @@ -1797,10 +1836,10 @@ Signed-off-by: Jonas Karlman 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 7f6ffbc3e7b2..ae4c49e84470 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1790,6 +1790,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, +@@ -1773,6 +1773,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, const struct drm_connector *connector, const struct drm_display_mode *mode) { @@ -1808,7 +1847,7 @@ index 7f6ffbc3e7b2..ae4c49e84470 100644 struct hdmi_avi_infoframe frame; u8 val; -@@ -1847,6 +1848,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, +@@ -1830,6 +1831,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; } @@ -1817,7 +1856,7 @@ index 7f6ffbc3e7b2..ae4c49e84470 100644 /* * The Designware IP uses a different byte format from standard * AVI info frames, though generally the bits are in the correct -@@ -2551,7 +2554,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, +@@ -2533,7 +2536,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, if (!crtc) return 0; @@ -1827,7 +1866,7 @@ index 7f6ffbc3e7b2..ae4c49e84470 100644 crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); -@@ -2619,6 +2623,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) +@@ -2601,6 +2605,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) drm_connector_attach_max_bpc_property(connector, 8, 16); @@ -1836,24 +1875,26 @@ index 7f6ffbc3e7b2..ae4c49e84470 100644 if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) drm_connector_attach_hdr_output_metadata_property(connector); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 20 Dec 2019 08:12:43 +0000 -Subject: [PATCH] WIP: drm/rockchip: add yuv444 support +Subject: WIP: drm/rockchip: add yuv444 support --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++++++++++++++- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++++++ - drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 6 +++++ - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 19 ++++++++++++++ + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 +++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 ++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 6 ++ + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 19 ++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 89424c5bc24a..05de2052d95d 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -68,6 +68,7 @@ struct rockchip_hdmi_chip_data { +@@ -69,6 +69,7 @@ struct rockchip_hdmi_chip_data { u32 lcdsel_big; u32 lcdsel_lit; int max_tmds_clock; @@ -1861,7 +1902,7 @@ index 89424c5bc24a..05de2052d95d 100644 }; struct rockchip_hdmi { -@@ -395,10 +396,22 @@ static bool is_rgb(u32 format) +@@ -410,10 +411,22 @@ static bool is_rgb(u32 format) } } @@ -1884,7 +1925,7 @@ index 89424c5bc24a..05de2052d95d 100644 return true; default: return false; -@@ -415,12 +428,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -430,12 +443,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, struct drm_atomic_state *state = bridge_state->base.state; struct drm_crtc_state *old_crtc_state; struct rockchip_crtc_state *old_state; @@ -1907,7 +1948,7 @@ index 89424c5bc24a..05de2052d95d 100644 s->bus_width = is_10bit(format) ? 10 : 8; old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); -@@ -454,7 +477,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -469,7 +492,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, if (!has_10bit && is_10bit(output_fmt)) return NULL; @@ -1919,7 +1960,7 @@ index 89424c5bc24a..05de2052d95d 100644 return NULL; input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); -@@ -604,6 +630,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { +@@ -624,6 +650,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { static struct rockchip_hdmi_chip_data rk3328_chip_data = { .lcdsel_grf_reg = -1, .max_tmds_clock = 594000, @@ -1928,11 +1969,11 @@ index 89424c5bc24a..05de2052d95d 100644 static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index eadf1b0f1704..0e4eca0d5121 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -347,6 +347,17 @@ static int vop_convert_afbc_format(uint32_t format) - return -EINVAL; +@@ -344,6 +344,17 @@ static int vop_convert_afbc_format(uint32_t format) + } } +static bool is_yuv_output(uint32_t bus_format) @@ -1949,7 +1990,7 @@ index eadf1b0f1704..0e4eca0d5121 100644 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, uint32_t dst, bool is_horizontal, int vsu_mode, int *vskiplines) -@@ -1455,6 +1466,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, +@@ -1456,6 +1467,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, u16 vact_end = vact_st + vdisplay; uint32_t pin_pol, val; int dither_bpc = s->output_bpc ? s->output_bpc : 10; @@ -1957,7 +1998,7 @@ index eadf1b0f1704..0e4eca0d5121 100644 int ret; if (old_state && old_state->self_refresh_active) { -@@ -1520,6 +1532,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, +@@ -1521,6 +1533,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) s->output_mode = ROCKCHIP_OUT_MODE_P888; @@ -1966,7 +2007,7 @@ index eadf1b0f1704..0e4eca0d5121 100644 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) VOP_REG_SET(vop, common, pre_dither_down, 1); else -@@ -1535,6 +1549,21 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, +@@ -1536,6 +1550,21 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, VOP_REG_SET(vop, common, out_mode, s->output_mode); @@ -1989,11 +2030,11 @@ index eadf1b0f1704..0e4eca0d5121 100644 val = hact_st << 16; val |= hact_end; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -index ca4e2b7415fe..47ad74ef1afb 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -@@ -119,10 +119,16 @@ struct vop_common { - struct vop_reg mmu_en; +@@ -125,10 +125,16 @@ struct vop_common { + struct vop_reg dma_stop; struct vop_reg out_mode; struct vop_reg standby; + @@ -2010,10 +2051,10 @@ index ca4e2b7415fe..47ad74ef1afb 100644 struct vop_intr { diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index a2b281e290e0..b16a4c42773c 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -705,6 +705,11 @@ static const struct vop_common rk3288_common = { +@@ -727,6 +727,11 @@ static const struct vop_common rk3288_common = { .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), @@ -2025,7 +2066,7 @@ index a2b281e290e0..b16a4c42773c 100644 }; /* -@@ -926,6 +931,11 @@ static const struct vop_common rk3399_common = { +@@ -952,6 +957,11 @@ static const struct vop_common rk3399_common = { .dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18), .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0), .cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0), @@ -2037,7 +2078,7 @@ index a2b281e290e0..b16a4c42773c 100644 }; static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = { -@@ -1096,6 +1106,10 @@ static const struct vop_output rk3328_output = { +@@ -1146,6 +1156,10 @@ static const struct vop_output rk3328_output = { static const struct vop_misc rk3328_misc = { .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11), @@ -2048,7 +2089,7 @@ index a2b281e290e0..b16a4c42773c 100644 }; static const struct vop_common rk3328_common = { -@@ -1108,6 +1122,11 @@ static const struct vop_common rk3328_common = { +@@ -1158,6 +1172,11 @@ static const struct vop_common rk3328_common = { .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), @@ -2060,24 +2101,26 @@ index a2b281e290e0..b16a4c42773c 100644 }; static const struct vop_intr rk3328_vop_intr = { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 20 Dec 2019 08:12:43 +0000 -Subject: [PATCH] WIP: drm/rockchip: add yuv420 support +Subject: WIP: drm/rockchip: add yuv420 support --- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++++ - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 +++++++++++++++++- - drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++++++---- - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++ - 4 files changed, 48 insertions(+), 5 deletions(-) + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 ++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 +++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 + + 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 05de2052d95d..cb201612199f 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -407,9 +407,21 @@ static bool is_yuv444(u32 format) +@@ -422,9 +422,21 @@ static bool is_yuv444(u32 format) } } @@ -2099,7 +2142,7 @@ index 05de2052d95d..cb201612199f 100644 case MEDIA_BUS_FMT_RGB101010_1X30: case MEDIA_BUS_FMT_YUV10_1X30: return true; -@@ -446,6 +458,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -461,6 +473,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, s->bus_width = is_10bit(format) ? 10 : 8; @@ -2111,7 +2154,7 @@ index 05de2052d95d..cb201612199f 100644 old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); if (old_crtc_state && !crtc_state->mode_changed) { old_state = to_rockchip_crtc_state(old_crtc_state); -@@ -466,6 +483,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -481,6 +498,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, { struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); struct drm_encoder *encoder = bridge->encoder; @@ -2119,7 +2162,7 @@ index 05de2052d95d..cb201612199f 100644 u32 *input_fmt; bool has_10bit = true; -@@ -480,6 +498,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -495,6 +513,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, if (is_yuv444(output_fmt)) { if (!hdmi->chip_data->ycbcr_444_allowed) return NULL; @@ -2129,7 +2172,7 @@ index 05de2052d95d..cb201612199f 100644 } else if (!is_rgb(output_fmt)) return NULL; -@@ -640,6 +661,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { +@@ -660,6 +681,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { .phy_name = "inno_dw_hdmi_phy2", .phy_force_vendor = true, .use_drm_infoframe = true, @@ -2138,7 +2181,7 @@ index 05de2052d95d..cb201612199f 100644 static struct rockchip_hdmi_chip_data rk3399_chip_data = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 0e4eca0d5121..e50f71ad3ceb 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -10,6 +10,7 @@ @@ -2148,8 +2191,8 @@ index 0e4eca0d5121..e50f71ad3ceb 100644 +#include #include #include - #include -@@ -348,6 +349,19 @@ static int vop_convert_afbc_format(uint32_t format) + #include +@@ -345,6 +346,19 @@ static int vop_convert_afbc_format(uint32_t format) } static bool is_yuv_output(uint32_t bus_format) @@ -2169,7 +2212,7 @@ index 0e4eca0d5121..e50f71ad3ceb 100644 { switch (bus_format) { case MEDIA_BUS_FMT_YUV8_1X24: -@@ -1532,7 +1546,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, +@@ -1533,7 +1547,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) s->output_mode = ROCKCHIP_OUT_MODE_P888; @@ -2178,7 +2221,7 @@ index 0e4eca0d5121..e50f71ad3ceb 100644 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) VOP_REG_SET(vop, common, pre_dither_down, 1); -@@ -1549,6 +1563,9 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, +@@ -1550,6 +1564,9 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, VOP_REG_SET(vop, common, out_mode, s->output_mode); @@ -2189,10 +2232,10 @@ index 0e4eca0d5121..e50f71ad3ceb 100644 VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -index 47ad74ef1afb..94a615dca672 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -@@ -121,6 +121,7 @@ struct vop_common { +@@ -127,6 +127,7 @@ struct vop_common { struct vop_reg standby; struct vop_reg overlay_mode; @@ -2201,10 +2244,10 @@ index 47ad74ef1afb..94a615dca672 100644 struct vop_reg dsp_out_yuv; struct vop_reg dsp_background; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index b16a4c42773c..5463b04240f7 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -707,6 +707,7 @@ static const struct vop_common rk3288_common = { +@@ -729,6 +729,7 @@ static const struct vop_common rk3288_common = { .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16), @@ -2212,7 +2255,7 @@ index b16a4c42773c..5463b04240f7 100644 .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12), .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2), .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), -@@ -1124,6 +1125,7 @@ static const struct vop_common rk3328_common = { +@@ -1174,6 +1175,7 @@ static const struct vop_common rk3328_common = { .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16), @@ -2220,22 +2263,24 @@ index b16a4c42773c..5463b04240f7 100644 .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12), .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 15 Aug 2020 23:20:34 +0200 -Subject: [PATCH] drm/rockchip: enable ycbcr_420_allowed and ycbcr_444_allowed - for RK3228 +Subject: drm/rockchip: enable ycbcr_420_allowed and ycbcr_444_allowed for + RK3228 --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index cb201612199f..8627f6826bfe 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -616,6 +616,7 @@ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { +@@ -634,6 +634,7 @@ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { static struct rockchip_hdmi_chip_data rk3228_chip_data = { .lcdsel_grf_reg = -1, .max_tmds_clock = 594000, @@ -2243,7 +2288,7 @@ index cb201612199f..8627f6826bfe 100644 }; static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { -@@ -624,6 +625,7 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { +@@ -642,6 +643,7 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { .phy_ops = &rk3228_hdmi_phy_ops, .phy_name = "inno_dw_hdmi_phy2", .phy_force_vendor = true, @@ -2251,18 +2296,20 @@ index cb201612199f..8627f6826bfe 100644 }; static struct rockchip_hdmi_chip_data rk3288_chip_data = { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 18 Nov 2017 11:09:39 +0100 -Subject: [PATCH] rockchip: vop: force skip lines if image too big +Subject: rockchip: vop: force skip lines if image too big --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 +++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index e50f71ad3ceb..ef0a078c22f4 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -958,6 +958,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, @@ -2299,7 +2346,7 @@ index e50f71ad3ceb..ef0a078c22f4 100644 VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); VOP_WIN_SET(vop, win, y_mir_en, @@ -1040,7 +1047,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, - offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + offset += (src->y1 >> 16) * fb->pitches[1] / fb->format->vsub; dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; - VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); @@ -2307,11 +2354,13 @@ index e50f71ad3ceb..ef0a078c22f4 100644 VOP_WIN_SET(vop, win, uv_mst, dma_addr); for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 10 Apr 2021 16:54:26 +0200 -Subject: [PATCH] drm/bridge: dw-hdmi: fix RGB to YUV color space conversion +Subject: drm/bridge: dw-hdmi: fix RGB to YUV color space conversion We are currently providing color space conversion coefficents for RGB to YUV conversion for full range to full range. @@ -2330,14 +2379,14 @@ and BT709 colorspaces. Fixes: 9aaf880ed4ee ("imx-drm: Add mx6 hdmi transmitter support") Signed-off-by: Alex Bee --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 ++++++------ + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 +++++----- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index ae4c49e84470..92e621f2714f 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -82,15 +82,15 @@ static const u16 csc_coeff_rgb_out_eitu709[3][4] = { +@@ -69,15 +69,15 @@ static const u16 csc_coeff_rgb_out_eitu709[3][4] = { }; static const u16 csc_coeff_rgb_in_eitu601[3][4] = { @@ -2359,12 +2408,14 @@ index ae4c49e84470..92e621f2714f 100644 }; static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 1 Oct 2019 20:52:42 +0000 -Subject: [PATCH] media: cec-adap: add debounce support when setting an invalid - phys addr +Subject: media: cec-adap: add debounce support when setting an invalid phys + addr When EDID is refreshed, HDMI cable is unplugged/replugged or an AVR is power cycled the CEC phys addr gets invalidated. @@ -2412,17 +2463,17 @@ Power on AVR (cec.debounce_ms=5000): Signed-off-by: Jonas Karlman --- - drivers/media/cec/core/cec-adap.c | 9 ++++++++- - drivers/media/cec/core/cec-core.c | 18 ++++++++++++++++++ + drivers/media/cec/core/cec-adap.c | 9 ++++- + drivers/media/cec/core/cec-core.c | 18 ++++++++++ drivers/media/cec/core/cec-priv.h | 1 + include/media/cec.h | 2 ++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c -index 41a79293ee02..542ab1425339 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c -@@ -1674,8 +1674,15 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) +@@ -1733,8 +1733,15 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) if (IS_ERR_OR_NULL(adap)) return; @@ -2440,7 +2491,7 @@ index 41a79293ee02..542ab1425339 100644 } EXPORT_SYMBOL_GPL(cec_s_phys_addr); diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c -index af358e901b5f..bece8c56e5af 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -40,6 +40,10 @@ static bool debug_phys_addr; @@ -2454,7 +2505,7 @@ index af358e901b5f..bece8c56e5af 100644 static dev_t cec_dev_t; /* Active devices */ -@@ -188,6 +192,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap) +@@ -159,6 +163,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap) mutex_unlock(&devnode->lock); @@ -2463,7 +2514,7 @@ index af358e901b5f..bece8c56e5af 100644 mutex_lock(&adap->lock); __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); __cec_s_log_addrs(adap, NULL, false); -@@ -246,6 +252,17 @@ static const struct file_operations cec_error_inj_fops = { +@@ -219,6 +225,17 @@ static const struct file_operations cec_error_inj_fops = { }; #endif @@ -2481,7 +2532,7 @@ index af358e901b5f..bece8c56e5af 100644 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, const char *name, u32 caps, u8 available_las) -@@ -283,6 +300,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, +@@ -256,6 +273,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, INIT_LIST_HEAD(&adap->transmit_queue); INIT_LIST_HEAD(&adap->wait_queue); init_waitqueue_head(&adap->kthread_waitq); @@ -2490,7 +2541,7 @@ index af358e901b5f..bece8c56e5af 100644 /* adap->devnode initialization */ INIT_LIST_HEAD(&adap->devnode.fhs); diff --git a/drivers/media/cec/core/cec-priv.h b/drivers/media/cec/core/cec-priv.h -index b78df931aa74..ebbea63ea9de 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/cec/core/cec-priv.h +++ b/drivers/media/cec/core/cec-priv.h @@ -37,6 +37,7 @@ static inline bool msg_is_raw(const struct cec_msg *msg) @@ -2502,10 +2553,10 @@ index b78df931aa74..ebbea63ea9de 100644 /* cec-adap.c */ int cec_monitor_all_cnt_inc(struct cec_adapter *adap); diff --git a/include/media/cec.h b/include/media/cec.h -index abee41ae02d0..544eedb5d671 100644 +index 111111111111..222222222222 100644 --- a/include/media/cec.h +++ b/include/media/cec.h -@@ -236,6 +236,8 @@ struct cec_adapter { +@@ -253,6 +253,8 @@ struct cec_adapter { struct task_struct *kthread; wait_queue_head_t kthread_waitq; @@ -2514,12 +2565,13 @@ index abee41ae02d0..544eedb5d671 100644 const struct cec_adap_ops *ops; void *priv; u32 capabilities; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 22 Oct 2021 11:17:30 +0200 -Subject: [PATCH] WIP: drm/bridge: synopsys: Fix CEC not working after - power-cyclying +Subject: WIP: drm/bridge: synopsys: Fix CEC not working after power-cyclying This fixes standby -> power-on on Rockchip platform for, at least, RK3288/RK3328/RK3399 where CEC wasn't working after powering on again. @@ -2530,14 +2582,14 @@ depending on sink's implementation. Signed-off-by: Alex Bee --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 14 ++++++++------ + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 14 ++++++---- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 92e621f2714f..7551e3ab77d6 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -3179,12 +3179,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) +@@ -3163,12 +3163,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) phy_stat & HDMI_PHY_HPD, phy_stat & HDMI_PHY_RX_SENSE); @@ -2550,7 +2602,7 @@ index 92e621f2714f..7551e3ab77d6 100644 if (phy_stat & HDMI_PHY_HPD) status = connector_status_connected; -@@ -3201,6 +3195,14 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) +@@ -3185,6 +3179,14 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) drm_helper_hpd_irq_event(hdmi->bridge.dev); drm_bridge_hpd_notify(&hdmi->bridge, status); } @@ -2565,19 +2617,21 @@ index 92e621f2714f..7551e3ab77d6 100644 } hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 9 Oct 2020 15:24:53 +0000 -Subject: [PATCH] drm/rockchip: vop: create planes in window order +Subject: drm/rockchip: vop: create planes in window order Signed-off-by: Jonas Karlman --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 +++------------------ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 ++-------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 49619f794061..9915bf124374 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -2023,19 +2023,10 @@ static int vop_create_crtc(struct vop *vop) @@ -2637,3 +2691,6 @@ index 49619f794061..9915bf124374 100644 } port = of_get_child_by_name(dev->of_node, "port"); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1001-v4l2-rockchip.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1001-v4l2-rockchip.patch index de0cb6026..a55fe1870 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1001-v4l2-rockchip.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1001-v4l2-rockchip.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 23 May 2020 10:16:01 +0000 -Subject: [PATCH] WIP: media: rkvdec: pm runtime dont use autosuspend before - disable and cleanup +Subject: WIP: media: rkvdec: pm runtime dont use autosuspend before disable + and cleanup Signed-off-by: Jonas Karlman --- @@ -10,10 +10,10 @@ Signed-off-by: Jonas Karlman 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 4f5436c89e08..eaf2f133a264 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -1125,9 +1125,9 @@ static int rkvdec_remove(struct platform_device *pdev) +@@ -1136,9 +1136,9 @@ static void rkvdec_remove(struct platform_device *pdev) cancel_delayed_work_sync(&rkvdec->watchdog_work); @@ -25,11 +25,13 @@ index 4f5436c89e08..eaf2f133a264 100644 } #ifdef CONFIG_PM +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Randy Li Date: Sun, 6 Jan 2019 01:48:37 +0800 -Subject: [PATCH] soc: rockchip: power-domain: export idle request +Subject: soc: rockchip: power-domain: export idle request We need to put the power status of HEVC IP into IDLE unless we can't reset that IP or the SoC would crash down. @@ -40,17 +42,16 @@ Signed-off-by: Caesar Wang Signed-off-by: Jeffy Chen Signed-off-by: Randy Li --- - drivers/pmdomain/rockchip/pm-domains.c | 23 +++++++++++++++++++++++ - include/linux/rockchip_pmu.h | 15 +++++++++++++++ - include/soc/rockchip/pm_domains.h | 6 ++++++ + drivers/pmdomain/rockchip/pm-domains.c | 23 ++++++++++ + include/linux/rockchip_pmu.h | 15 ++++++ + include/soc/rockchip/pm_domains.h | 6 +++ 3 files changed, 44 insertions(+) - create mode 100644 include/linux/rockchip_pmu.h diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index 89795abac951..ffb5d62c9d52 100644 +index 111111111111..222222222222 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -309,6 +309,29 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, +@@ -392,6 +392,29 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, return 0; } @@ -82,7 +83,7 @@ index 89795abac951..ffb5d62c9d52 100644 int i; diff --git a/include/linux/rockchip_pmu.h b/include/linux/rockchip_pmu.h new file mode 100644 -index 000000000000..720b3314e71a +index 000000000000..111111111111 --- /dev/null +++ b/include/linux/rockchip_pmu.h @@ -0,0 +1,15 @@ @@ -102,7 +103,7 @@ index 000000000000..720b3314e71a + +#endif /* _LINUX_ROCKCHIP_PM_H */ diff --git a/include/soc/rockchip/pm_domains.h b/include/soc/rockchip/pm_domains.h -index 7dbd941fc937..c5a59dd71754 100644 +index 111111111111..222222222222 100644 --- a/include/soc/rockchip/pm_domains.h +++ b/include/soc/rockchip/pm_domains.h @@ -10,6 +10,7 @@ @@ -125,21 +126,23 @@ index 7dbd941fc937..c5a59dd71754 100644 #endif /* CONFIG_ROCKCHIP_PM_DOMAINS */ #endif /* __SOC_ROCKCHIP_PM_DOMAINS_H__ */ +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 20 May 2020 17:04:47 +0200 -Subject: [PATCH] WIP: media: rkvdec: implement reset controls +Subject: WIP: media: rkvdec: implement reset controls --- - .../bindings/media/rockchip,vdec.yaml | 19 +++++++ - drivers/staging/media/rkvdec/rkvdec-regs.h | 5 ++ - drivers/staging/media/rkvdec/rkvdec.c | 53 +++++++++++++++++++ - drivers/staging/media/rkvdec/rkvdec.h | 11 +++- + Documentation/devicetree/bindings/media/rockchip,vdec.yaml | 19 ++++ + drivers/staging/media/rkvdec/rkvdec-regs.h | 5 + + drivers/staging/media/rkvdec/rkvdec.c | 53 ++++++++++ + drivers/staging/media/rkvdec/rkvdec.h | 11 +- 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -index 3bcfb8e12333..dd6958df1de8 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml @@ -53,6 +53,18 @@ properties: @@ -183,7 +186,7 @@ index 3bcfb8e12333..dd6958df1de8 100644 ... diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h -index 15b9bee92016..3acc914888f6 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-regs.h +++ b/drivers/staging/media/rkvdec/rkvdec-regs.h @@ -28,6 +28,11 @@ @@ -199,7 +202,7 @@ index 15b9bee92016..3acc914888f6 100644 #define RKVDEC_REG_SYSCTRL 0x008 #define RKVDEC_IN_ENDIAN BIT(0) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index eaf2f133a264..f55abb7c377f 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -10,12 +10,15 @@ @@ -218,7 +221,7 @@ index eaf2f133a264..f55abb7c377f 100644 #include #include #include -@@ -717,6 +720,11 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx, +@@ -726,6 +729,11 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx, pm_runtime_mark_last_busy(rkvdec->dev); pm_runtime_put_autosuspend(rkvdec->dev); @@ -230,7 +233,7 @@ index eaf2f133a264..f55abb7c377f 100644 rkvdec_job_finish_no_pm(ctx, result); } -@@ -754,6 +762,33 @@ static void rkvdec_device_run(void *priv) +@@ -763,6 +771,33 @@ static void rkvdec_device_run(void *priv) if (WARN_ON(!desc)) return; @@ -264,7 +267,7 @@ index eaf2f133a264..f55abb7c377f 100644 ret = pm_runtime_resume_and_get(rkvdec->dev); if (ret < 0) { -@@ -1020,6 +1055,11 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) +@@ -1029,6 +1064,11 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) if (cancel_delayed_work(&rkvdec->watchdog_work)) { struct rkvdec_ctx *ctx; @@ -276,7 +279,7 @@ index eaf2f133a264..f55abb7c377f 100644 ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); rkvdec_job_finish(ctx, state); } -@@ -1037,6 +1077,7 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1046,6 +1086,7 @@ static void rkvdec_watchdog_func(struct work_struct *work) ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); if (ctx) { dev_err(rkvdec->dev, "Frame processing timed out!\n"); @@ -284,7 +287,7 @@ index eaf2f133a264..f55abb7c377f 100644 writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT); writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL); rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); -@@ -1105,6 +1146,18 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1114,6 +1155,18 @@ static int rkvdec_probe(struct platform_device *pdev) return ret; } @@ -304,7 +307,7 @@ index eaf2f133a264..f55abb7c377f 100644 pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -index b9e219438bc9..f02f79c405f0 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ b/drivers/staging/media/rkvdec/rkvdec.h @@ -11,10 +11,11 @@ @@ -342,21 +345,23 @@ index b9e219438bc9..f02f79c405f0 100644 }; struct rkvdec_ctx { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 18 Aug 2020 11:38:04 +0200 -Subject: [PATCH] WIP: arm64: dts: add resets to vdec for RK3399 +Subject: WIP: arm64: dts: add resets to vdec for RK3399 --- arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -index 980b12cb0a49..6e3149e587c5 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -1345,6 +1348,11 @@ vdec: video-codec@ff660000 { +@@ -1463,6 +1463,11 @@ vdec: video-codec@ff660000 { clock-names = "axi", "ahb", "cabac", "core"; iommus = <&vdec_mmu>; power-domains = <&power RK3399_PD_VDU>; @@ -368,26 +373,26 @@ index 980b12cb0a49..6e3149e587c5 100644 }; vdec_mmu: iommu@ff660480 { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 21 Aug 2021 16:12:36 +0200 -Subject: [PATCH] media: hantro: rockchip: Increase RK3288's max ACLK +Subject: media: hantro: rockchip: Increase RK3288's max ACLK Required to proper decode H.264@4K Signed-off-by: Alex Bee --- - drivers/media/platform/verisilicon/rockchip_vpu_hw.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) + drivers/media/platform/verisilicon/rockchip_vpu_hw.c | 15 ++++++++-- + 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c -index 8de6fd2e8eef..002b1a600f93 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c -@@ -14,11 +14,13 @@ - #include "hantro_h1_regs.h" - #include "rockchip_vpu2_regs.h" +@@ -16,7 +16,9 @@ #include "rockchip_vpu981_regs.h" #define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000) @@ -398,9 +403,7 @@ index 8de6fd2e8eef..002b1a600f93 100644 #define ROCKCHIP_VPU981_MIN_SIZE 64 - /* - * Supported formats. -@@ -346,13 +347,20 @@ static int rk3066_vpu_hw_init(struct hantro_dev *vpu) +@@ -439,13 +441,20 @@ static int rk3066_vpu_hw_init(struct hantro_dev *vpu) return 0; } @@ -422,7 +425,7 @@ index 8de6fd2e8eef..002b1a600f93 100644 static void rk3066_vpu_dec_reset(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; -@@ -592,7 +600,7 @@ const struct hantro_variant rk3288_vpu_variant = { +@@ -701,7 +710,7 @@ const struct hantro_variant rk3288_vpu_variant = { .codec_ops = rk3288_vpu_codec_ops, .irqs = rockchip_vpu1_irqs, .num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs), @@ -431,12 +434,13 @@ index 8de6fd2e8eef..002b1a600f93 100644 .clk_names = rockchip_vpu_clk_names, .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 4 Jul 2021 15:19:44 +0200 -Subject: [PATCH] media: rkvdec: disable QoS for VP9 (corruptions on RK3328 - otherwise) +Subject: media: rkvdec: disable QoS for VP9 (corruptions on RK3328 otherwise) Signed-off-by: Alex Bee --- @@ -445,7 +449,7 @@ Signed-off-by: Alex Bee 2 files changed, 10 insertions(+) diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h -index 3acc914888f6..265f5234f4eb 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-regs.h +++ b/drivers/staging/media/rkvdec/rkvdec-regs.h @@ -222,6 +222,8 @@ @@ -458,10 +462,10 @@ index 3acc914888f6..265f5234f4eb 100644 #define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450 diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c -index d8c1c0db15c7..a289bc968e91 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-vp9.c +++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c -@@ -802,6 +802,7 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) +@@ -803,6 +803,7 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) struct rkvdec_dev *rkvdec = ctx->dev; struct rkvdec_vp9_run run = { }; int ret; @@ -469,7 +473,7 @@ index d8c1c0db15c7..a289bc968e91 100644 ret = rkvdec_vp9_run_preamble(ctx, &run); if (ret) { -@@ -823,6 +824,13 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) +@@ -824,6 +825,13 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); @@ -483,21 +487,23 @@ index d8c1c0db15c7..a289bc968e91 100644 /* Start decoding! */ writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Thu, 16 Jun 2022 13:18:22 +0200 -Subject: [PATCH] WIP: arm64: dts: add resets to vdec for RK3328 +Subject: WIP: arm64: dts: add resets to vdec for RK3328 --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 5519347232f6..431c4ec198be 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -674,6 +674,11 @@ vdec: video-codec@ff360000 { +@@ -705,6 +705,11 @@ vdec: video-codec@ff360000 { assigned-clocks = <&cru ACLK_RKVDEC>, <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; assigned-clock-rates = <400000000>, <400000000>, <300000000>; @@ -509,3 +515,6 @@ index 5519347232f6..431c4ec198be 100644 iommus = <&vdec_mmu>; power-domains = <&power RK3328_PD_VIDEO>; }; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1002-for-libreelec.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1002-for-libreelec.patch index b642cb149..1f6ff27dc 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1002-for-libreelec.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-1002-for-libreelec.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 2 Sep 2020 19:52:02 +0200 -Subject: [PATCH] arm64: dts: rockchip: add gpu powerdomain, gpu opp-table and - cooling cell for RK3328 +Subject: arm64: dts: rockchip: add gpu powerdomain, gpu opp-table and cooling + cell for RK3328 Note: since the regulator that supplies the GPU usually also supplies other SoC components, we have to make sure voltage is never lower then @@ -11,16 +11,16 @@ is running at the same time (voltage to high) Signed-off-by: Alex Bee --- - .../arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 4 +++ - .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 +++ - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 35 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 4 ++ + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 ++ + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 35 ++++++++++ 3 files changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index aa22a0c22265..51c7723d6762 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -166,6 +166,10 @@ &gmac2io { +@@ -165,6 +165,10 @@ &gmac2io { status = "okay"; }; @@ -32,10 +32,10 @@ index aa22a0c22265..51c7723d6762 100644 status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -index f69a38f42d2d..c198a8a7f95a 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -@@ -162,6 +162,10 @@ &gmac2io { +@@ -153,6 +153,10 @@ &gmac2io { status = "okay"; }; @@ -44,13 +44,13 @@ index f69a38f42d2d..c198a8a7f95a 100644 +}; + &hdmi { - status = "okay"; - }; + avdd-0v9-supply = <&vdd_10>; + avdd-1v8-supply = <&vcc_18>; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 431c4ec198be..eec03adf0902 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -300,6 +300,11 @@ power: power-controller { +@@ -331,6 +331,11 @@ power: power-controller { #address-cells = <1>; #size-cells = <0>; @@ -61,8 +61,8 @@ index 431c4ec198be..eec03adf0902 100644 + }; power-domain@RK3328_PD_HEVC { reg = ; - #power-domain-cells = <0>; -@@ -539,6 +544,11 @@ map0 { + clocks = <&cru SCLK_VENC_CORE>; +@@ -570,6 +575,11 @@ map0 { <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; contribution = <4096>; }; @@ -74,7 +74,7 @@ index 431c4ec198be..eec03adf0902 100644 }; }; -@@ -620,7 +630,32 @@ gpu: gpu@ff300000 { +@@ -651,7 +661,32 @@ gpu: gpu@ff300000 { "ppmmu1"; clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; clock-names = "bus", "core"; @@ -107,19 +107,21 @@ index 431c4ec198be..eec03adf0902 100644 }; h265e_mmu: iommu@ff330200 { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 2 Feb 2021 17:22:21 +0200 -Subject: [PATCH] ARM: dts: RK3288 miqi add hdmi sound nodes +Subject: ARM: dts: RK3288 miqi add hdmi sound nodes Signed-off-by: Alex Bee --- - arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 20 ++++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 20 ++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 713f55e143c6..8d30c49f406e 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts @@ -78,6 +78,21 @@ vcc_sys: vsys-regulator { @@ -144,7 +146,7 @@ index 713f55e143c6..8d30c49f406e 100644 }; &cpu0 { -@@ -284,6 +299,11 @@ &i2c5 { +@@ -283,6 +298,11 @@ &i2c5 { status = "okay"; }; @@ -156,20 +158,22 @@ index 713f55e143c6..8d30c49f406e 100644 &io_domains { status = "okay"; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 2 Apr 2021 17:54:22 +0200 -Subject: [PATCH] ARM/arm64: dts: rockchip: align sound card names +Subject: ARM/arm64: dts: rockchip: align sound card names Signed-off-by: Alex Bee --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 2 +- + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 2 +- arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index 09618bb7d872..db9106a3dd22 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi @@ -73,7 +73,7 @@ sdio_pwrseq: sdio-pwrseq { @@ -182,10 +186,10 @@ index 09618bb7d872..db9106a3dd22 100644 simple-audio-card,codec { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -index 093ebe070775..a10fe60b7680 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -1893,7 +1893,7 @@ hdmi_sound: hdmi-sound { +@@ -2008,7 +2008,7 @@ hdmi_sound: hdmi-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <256>; @@ -194,22 +198,24 @@ index 093ebe070775..a10fe60b7680 100644 status = "disabled"; simple-audio-card,cpu { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 27 Feb 2021 17:52:02 +0100 -Subject: [PATCH] arm64: dts: rockchip: add SPDIF nodes for RK3328 A1 board +Subject: arm64: dts: rockchip: add SPDIF nodes for RK3328 A1 board Signed-off-by: Alex Bee --- - arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 23 ++++++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 23 ++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -index 40bf808642b9..27a1799027c2 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -@@ -57,6 +57,24 @@ ir-receiver { +@@ -58,6 +58,24 @@ ir-receiver { gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; linux,rc-map-name = "rc-beelink-gs1"; }; @@ -234,7 +240,7 @@ index 40bf808642b9..27a1799027c2 100644 }; &analog_sound { -@@ -325,6 +343,11 @@ &sdmmc { +@@ -326,6 +344,11 @@ &sdmmc { status = "okay"; }; @@ -246,22 +252,24 @@ index 40bf808642b9..27a1799027c2 100644 &tsadc { rockchip,hw-tshut-mode = <0>; rockchip,hw-tshut-polarity = <0>; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 27 Feb 2021 18:01:13 +0100 -Subject: [PATCH] arm64: dts: rockchip: Add ir-receiver node for RK3328 ROC CC +Subject: arm64: dts: rockchip: Add ir-receiver node for RK3328 ROC CC Signed-off-by: Alex Bee --- - arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 14 ++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 14 ++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index 51c7723d6762..cf321302daec 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -88,6 +88,13 @@ vcc_phy: vcc-phy-regulator { +@@ -89,6 +89,13 @@ vcc_phy: vcc-phy-regulator { regulator-boot-on; }; @@ -275,7 +283,7 @@ index 51c7723d6762..cf321302daec 100644 leds { compatible = "gpio-leds"; -@@ -312,6 +319,13 @@ &io_domains { +@@ -311,6 +318,13 @@ &io_domains { }; &pinctrl { @@ -289,18 +297,20 @@ index 51c7723d6762..cf321302daec 100644 pmic { pmic_int_l: pmic-int-l { rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 1 Mar 2021 21:24:15 +0100 -Subject: [PATCH] ARM: dts: add cec pinctrl for RK3288 miqi board +Subject: ARM: dts: add cec pinctrl for RK3288 miqi board --- arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 8d30c49f406e..6d90db5a3b75 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts @@ -145,6 +145,8 @@ &gpu { @@ -312,21 +322,23 @@ index 8d30c49f406e..6d90db5a3b75 100644 status = "okay"; }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 1 Mar 2021 19:22:15 +0100 -Subject: [PATCH] HACK: arm64: dts: enable FE phy for Beelink A1 also +Subject: HACK: arm64: dts: enable FE phy for Beelink A1 also --- arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -index 27a1799027c2..7de9dfa71d89 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -@@ -147,6 +147,14 @@ rtl8211f: ethernet-phy@0 { +@@ -148,6 +148,14 @@ rtl8211f: ethernet-phy@0 { }; }; @@ -341,18 +353,20 @@ index 27a1799027c2..7de9dfa71d89 100644 &gpu { mali-supply = <&vdd_logic>; }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 26 Feb 2019 20:45:14 +0000 -Subject: [PATCH] WIP: dw-hdmi-cec: sleep 100ms on error +Subject: WIP: dw-hdmi-cec: sleep 100ms on error --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 18 ++++++++++++++++-- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 18 ++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -index c8f44bcb298a..d4280ce4542c 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c @@ -4,6 +4,7 @@ @@ -363,7 +377,7 @@ index c8f44bcb298a..d4280ce4542c 100644 #include #include #include -@@ -129,8 +130,15 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) +@@ -133,8 +134,15 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0); @@ -381,8 +395,8 @@ index c8f44bcb298a..d4280ce4542c 100644 cec->tx_done = true; ret = IRQ_WAKE_THREAD; } else if (stat & CEC_STAT_DONE) { -@@ -141,6 +149,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - cec->tx_status = CEC_TX_STATUS_NACK; +@@ -149,6 +157,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) + cec->tx_status = CEC_TX_STATUS_ARB_LOST; cec->tx_done = true; ret = IRQ_WAKE_THREAD; + } else if (stat & CEC_STAT_ERROR_INIT) { @@ -392,7 +406,7 @@ index c8f44bcb298a..d4280ce4542c 100644 } if (stat & CEC_STAT_EOM) { -@@ -173,6 +185,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) +@@ -181,6 +193,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) if (cec->tx_done) { cec->tx_done = false; @@ -401,11 +415,13 @@ index c8f44bcb298a..d4280ce4542c 100644 cec_transmit_attempt_done(adap, cec->tx_status); } if (cec->rx_done) { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 5 May 2021 19:11:12 +0200 -Subject: [PATCH] arm64: boot: dts: Increase ACLK_PERILP0 clock rate for RK3399 +Subject: arm64: boot: dts: Increase ACLK_PERILP0 clock rate for RK3399 As per vendor kernel. Leaving this clock at the lower rate will result in poor DMA controller performance @@ -416,10 +432,10 @@ Signed-off-by: Alex Bee 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -index a10fe60b7680..dbe6a9cb98a5 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -1477,7 +1477,7 @@ cru: clock-controller@ff760000 { +@@ -1592,7 +1592,7 @@ cru: clock-controller@ff760000 { <1000000000>, <150000000>, <75000000>, <37500000>, @@ -428,11 +444,13 @@ index a10fe60b7680..dbe6a9cb98a5 100644 <50000000>, <600000000>, <100000000>, <50000000>, <400000000>, <400000000>, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 21 Aug 2021 17:04:46 +0200 -Subject: [PATCH] arm64: dts: rockchip: Enable USB3 for rk3328 Beelink A1 +Subject: arm64: dts: rockchip: Enable USB3 for rk3328 Beelink A1 Signed-off-by: Alex Bee --- @@ -440,10 +458,10 @@ Signed-off-by: Alex Bee 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -index 7de9dfa71d89..e857e5a727f4 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -@@ -389,6 +389,11 @@ &usb_host0_ehci { +@@ -390,6 +390,11 @@ &usb_host0_ehci { status = "okay"; }; @@ -455,12 +473,13 @@ index 7de9dfa71d89..e857e5a727f4 100644 &vop { status = "okay"; }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 30 Oct 2021 12:19:19 +0200 -Subject: [PATCH] WIP: drm: bridge: dw-hdmi: switch from .hw_parmas to .prepare - for i2s +Subject: WIP: drm: bridge: dw-hdmi: switch from .hw_parmas to .prepare for i2s Seems to be the only way to get AES bits correctly as set by userspace. @@ -472,7 +491,7 @@ Signed-off-by: Alex Bee 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -index a2f0860b20bb..8961f9c7885d 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -34,9 +34,9 @@ static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset) @@ -497,11 +516,13 @@ index a2f0860b20bb..8961f9c7885d 100644 .audio_startup = dw_hdmi_i2s_audio_startup, .audio_shutdown = dw_hdmi_i2s_audio_shutdown, .get_eld = dw_hdmi_i2s_get_eld, +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 18 Sep 2022 10:35:52 +0200 -Subject: [PATCH] arm64: dts: rockchip: Disbake fusb for rk3399-roc-pc +Subject: arm64: dts: rockchip: Disbake fusb for rk3399-roc-pc As it will lead to an unbootable device in case one if those ports is used to power up the device. @@ -511,7 +532,7 @@ See https://lkml.org/lkml/2022/6/20/413 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi -index 2f4b1b2e3ac7..7217ead94d39 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi @@ -215,7 +215,7 @@ vdd_log: vdd-log { @@ -541,3 +562,6 @@ index 2f4b1b2e3ac7..7217ead94d39 100644 }; mp8859: regulator@66 { +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2000-v4l2-wip-rkvdec-hevc.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2000-v4l2-wip-rkvdec-hevc.patch index 58b3e72e5..797a4957b 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2000-v4l2-wip-rkvdec-hevc.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2000-v4l2-wip-rkvdec-hevc.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 23 May 2020 15:17:45 +0000 -Subject: [PATCH] WIP: media: rkvdec: add HEVC backend +Subject: WIP: media: rkvdec: add HEVC backend NOTE: cabac table and scailing list code is copied 1:1 from mpp TODO: fix lowdelay flag and rework the scaling list part @@ -10,15 +10,14 @@ Signed-off-by: Jonas Karlman Signed-off-by: Alex Bee --- drivers/staging/media/rkvdec/Makefile | 2 +- - drivers/staging/media/rkvdec/rkvdec-hevc.c | 2572 ++++++++++++++++++++ + drivers/staging/media/rkvdec/rkvdec-hevc.c | 2572 ++++++++++ drivers/staging/media/rkvdec/rkvdec-regs.h | 1 + drivers/staging/media/rkvdec/rkvdec.c | 73 +- drivers/staging/media/rkvdec/rkvdec.h | 1 + 5 files changed, 2647 insertions(+), 2 deletions(-) - create mode 100644 drivers/staging/media/rkvdec/rkvdec-hevc.c diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile -index cb86b429cfaa..a77122641d14 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/Makefile +++ b/drivers/staging/media/rkvdec/Makefile @@ -1,3 +1,3 @@ @@ -28,7 +27,7 @@ index cb86b429cfaa..a77122641d14 100644 +rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-hevc.o rkvdec-vp9.o diff --git a/drivers/staging/media/rkvdec/rkvdec-hevc.c b/drivers/staging/media/rkvdec/rkvdec-hevc.c new file mode 100644 -index 000000000000..7a375a23eaf1 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/staging/media/rkvdec/rkvdec-hevc.c @@ -0,0 +1,2572 @@ @@ -2605,7 +2604,7 @@ index 000000000000..7a375a23eaf1 + .valid_fmt = rkvdec_hevc_valid_fmt, +}; diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h -index 265f5234f4eb..4319ee3ccbbc 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-regs.h +++ b/drivers/staging/media/rkvdec/rkvdec-regs.h @@ -48,6 +48,7 @@ @@ -2617,7 +2616,7 @@ index 265f5234f4eb..4319ee3ccbbc 100644 #define RKVDEC_MODE_VP9 2 #define RKVDEC_RPS_MODE BIT(24) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index f55abb7c377f..00a9bf583596 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -74,7 +74,7 @@ static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl) @@ -2715,7 +2714,7 @@ index f55abb7c377f..00a9bf583596 100644 .fourcc = V4L2_PIX_FMT_VP9_FRAME, .frmsize = { diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -index f02f79c405f0..d6222a2588be 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ b/drivers/staging/media/rkvdec/rkvdec.h @@ -133,6 +133,7 @@ void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); @@ -2726,11 +2725,13 @@ index f02f79c405f0..d6222a2588be 100644 extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops; #endif /* RKVDEC_H_ */ +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 30 Jan 2021 18:16:39 +0100 -Subject: [PATCH] media: rkvdec: add variants support +Subject: media: rkvdec: add variants support rkvdec IP has different versions which among others differ in the supported decoding formats. @@ -2744,12 +2745,12 @@ the better soultion than duplicatiing code for every newly added IP. Signed-off-by: Alex Bee --- - drivers/staging/media/rkvdec/rkvdec.c | 105 ++++++++++++++++++-------- - drivers/staging/media/rkvdec/rkvdec.h | 10 +++ + drivers/staging/media/rkvdec/rkvdec.c | 105 +++++++--- + drivers/staging/media/rkvdec/rkvdec.h | 10 + 2 files changed, 85 insertions(+), 30 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 00a9bf583596..955c53afe20f 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -14,6 +14,7 @@ @@ -2865,7 +2866,7 @@ index 00a9bf583596..955c53afe20f 100644 if (!fmt) return -EINVAL; -@@ -406,10 +426,11 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv, +@@ -412,10 +432,11 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv, struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); const struct rkvdec_coded_fmt_desc *desc; @@ -2880,7 +2881,7 @@ index 00a9bf583596..955c53afe20f 100644 } v4l2_apply_frmsize_constraints(&pix_mp->width, -@@ -487,7 +508,8 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv, +@@ -493,7 +514,8 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv, if (ret) return ret; @@ -2890,7 +2891,7 @@ index 00a9bf583596..955c53afe20f 100644 if (!desc) return -EINVAL; ctx->coded_fmt_desc = desc; -@@ -538,7 +560,10 @@ static int rkvdec_g_capture_fmt(struct file *file, void *priv, +@@ -544,7 +566,10 @@ static int rkvdec_g_capture_fmt(struct file *file, void *priv, static int rkvdec_enum_output_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -2902,7 +2903,7 @@ index 00a9bf583596..955c53afe20f 100644 return -EINVAL; f->pixelformat = rkvdec_coded_fmts[f->index].fourcc; -@@ -946,14 +971,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) +@@ -955,14 +980,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) int ret; for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) @@ -2924,7 +2925,7 @@ index 00a9bf583596..955c53afe20f 100644 } ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); -@@ -1155,8 +1183,17 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1164,8 +1192,17 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } @@ -2943,7 +2944,7 @@ index 00a9bf583596..955c53afe20f 100644 { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); -@@ -1168,6 +1205,7 @@ static const char * const rkvdec_clk_names[] = { +@@ -1177,6 +1214,7 @@ static const char * const rkvdec_clk_names[] = { static int rkvdec_probe(struct platform_device *pdev) { struct rkvdec_dev *rkvdec; @@ -2951,7 +2952,7 @@ index 00a9bf583596..955c53afe20f 100644 unsigned int i; int ret, irq; -@@ -1193,6 +1231,13 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1202,6 +1240,13 @@ static int rkvdec_probe(struct platform_device *pdev) if (ret) return ret; @@ -2966,7 +2967,7 @@ index 00a9bf583596..955c53afe20f 100644 if (IS_ERR(rkvdec->regs)) return PTR_ERR(rkvdec->regs); diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -index d6222a2588be..ad8e83884121 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ b/drivers/staging/media/rkvdec/rkvdec.h @@ -29,6 +29,10 @@ @@ -3007,11 +3008,13 @@ index d6222a2588be..ad8e83884121 100644 }; struct rkvdec_ctx { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 30 Jan 2021 18:21:59 +0100 -Subject: [PATCH] media: rkvdec: add RK3288 variant +Subject: media: rkvdec: add RK3288 variant This adds RK3288 variant to rkvdec driver. In this earlier version of the IP only HEVC decoding is supported. @@ -3022,10 +3025,10 @@ Signed-off-by: Alex Bee 1 file changed, 8 insertions(+) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 955c53afe20f..4e228cd82f21 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -1189,11 +1189,19 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { +@@ -1198,11 +1198,19 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { RKVDEC_CAPABILITY_VP9 }; @@ -3045,22 +3048,24 @@ index 955c53afe20f..4e228cd82f21 100644 { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 30 Jan 2021 18:27:30 +0100 -Subject: [PATCH] ARM: dts: RK3288: add hevc node +Subject: ARM: dts: RK3288: add hevc node Signed-off-by: Alex Bee --- - arch/arm/boot/dts/rockchip/rk3288.dtsi | 21 ++++++++++++++++++++- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 21 +++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 7b2cde230b87..59fba3ac6aae 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1248,6 +1248,25 @@ vpu_mmu: iommu@ff9a0800 { +@@ -1289,6 +1289,25 @@ vpu_mmu: iommu@ff9a0800 { power-domains = <&power RK3288_PD_VIDEO>; }; @@ -3086,7 +3091,7 @@ index 7b2cde230b87..59fba3ac6aae 100644 hevc_mmu: iommu@ff9c0440 { compatible = "rockchip,iommu"; reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>; -@@ -1255,7 +1274,7 @@ hevc_mmu: iommu@ff9c0440 { +@@ -1296,7 +1315,7 @@ hevc_mmu: iommu@ff9c0440 { clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>; clock-names = "aclk", "iface"; #iommu-cells = <0>; @@ -3095,11 +3100,13 @@ index 7b2cde230b87..59fba3ac6aae 100644 }; gpu: gpu@ffa30000 { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 10 May 2022 14:37:29 -0400 -Subject: [PATCH] media: rkvdec: Fix HEVC RPS bit offsets +Subject: media: rkvdec: Fix HEVC RPS bit offsets The offsets from the uAPI need to be extended to include some bits that can be calculated from the parameters. This has been compared @@ -3114,11 +3121,11 @@ Fixed by this change: Signed-off-by: Nicolas Dufresne --- - drivers/staging/media/rkvdec/rkvdec-hevc.c | 26 +++++++++++++++++++--- + drivers/staging/media/rkvdec/rkvdec-hevc.c | 26 ++++++++-- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec-hevc.c b/drivers/staging/media/rkvdec/rkvdec-hevc.c -index 7a375a23eaf1..580073d49b6a 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-hevc.c +++ b/drivers/staging/media/rkvdec/rkvdec-hevc.c @@ -10,6 +10,7 @@ @@ -3177,11 +3184,13 @@ index 7a375a23eaf1..580073d49b6a 100644 LONG_TERM_RPS_BIT_OFFSET); WRITE_RPS(sl_params->short_term_ref_pic_set_size, SHORT_TERM_RPS_BIT_OFFSET); +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 10 May 2022 15:12:03 -0400 -Subject: [PATCH] media: rkvdec: Fix number of HEVC references being set in RPS +Subject: media: rkvdec: Fix number of HEVC references being set in RPS The numbers from the bitstream are values between 1 - 16 (as they are the number - 1). The difference between 0 and 1 needs to be determined @@ -3194,7 +3203,7 @@ Signed-off-by: Nicolas Dufresne 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/rkvdec/rkvdec-hevc.c b/drivers/staging/media/rkvdec/rkvdec-hevc.c -index 580073d49b6a..ce15028918b2 100644 +index 111111111111..222222222222 100644 --- a/drivers/staging/media/rkvdec/rkvdec-hevc.c +++ b/drivers/staging/media/rkvdec/rkvdec-hevc.c @@ -2199,6 +2199,8 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, @@ -3224,3 +3233,6 @@ index 580073d49b6a..ce15028918b2 100644 WRITE_RPS(!!(dpb[sl_params->ref_idx_l1[i]].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE), REF_PIC_LONG_TERM_L1(i)); WRITE_RPS(sl_params->ref_idx_l1[i], REF_PIC_IDX_L1(i)); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2001-v4l2-wip-iep-driver.patch b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2001-v4l2-wip-iep-driver.patch index 541c84937..29f426550 100644 --- a/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2001-v4l2-wip-iep-driver.patch +++ b/patch/kernel/archive/rockchip-6.12/patches.libreelec/linux-2001-v4l2-wip-iep-driver.patch @@ -1,17 +1,16 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 11 Oct 2020 17:03:12 +0200 -Subject: [PATCH] dt-bindings: media: Add Rockchip IEP binding +Subject: dt-bindings: media: Add Rockchip IEP binding Signed-off-by: Alex Bee --- - .../bindings/media/rockchip-iep.yaml | 73 +++++++++++++++++++ + Documentation/devicetree/bindings/media/rockchip-iep.yaml | 73 ++++++++++ 1 file changed, 73 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/rockchip-iep.yaml diff --git a/Documentation/devicetree/bindings/media/rockchip-iep.yaml b/Documentation/devicetree/bindings/media/rockchip-iep.yaml new file mode 100644 -index 000000000000..a9efcda13fc1 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip-iep.yaml @@ -0,0 +1,73 @@ @@ -88,30 +87,27 @@ index 000000000000..a9efcda13fc1 + iommus = <&iep_mmu>; + power-domains = <&power RK3228_PD_VIO>; + }; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 11 Oct 2020 21:24:10 +0200 -Subject: [PATCH] media: rockchip: Add Rockchip IEP driver +Subject: media: rockchip: Add Rockchip IEP driver Signed-off-by: Alex Bee --- - drivers/media/platform/rockchip/Kconfig | 1 + - drivers/media/platform/rockchip/Makefile | 1 + - drivers/media/platform/rockchip/iep/Kconfig | 16 + - drivers/media/platform/rockchip/iep/Makefile | 5 + - .../media/platform/rockchip/iep/iep-regs.h | 291 +++++ - drivers/media/platform/rockchip/iep/iep.c | 1089 +++++++++++++++++ - drivers/media/platform/rockchip/iep/iep.h | 112 ++ - 7 files changed, 1515 insertions(+) - create mode 100644 drivers/media/platform/rockchip/iep/Kconfig - create mode 100644 drivers/media/platform/rockchip/iep/Makefile - create mode 100644 drivers/media/platform/rockchip/iep/iep-regs.h - create mode 100644 drivers/media/platform/rockchip/iep/iep.c - create mode 100644 drivers/media/platform/rockchip/iep/iep.h + drivers/media/platform/rockchip/Kconfig | 1 + + drivers/media/platform/rockchip/Makefile | 1 + + drivers/media/platform/rockchip/iep/Kconfig | 16 + + drivers/media/platform/rockchip/iep/Makefile | 5 + + drivers/media/platform/rockchip/iep/iep-regs.h | 291 +++ + drivers/media/platform/rockchip/iep/iep.c | 1087 ++++++++++ + drivers/media/platform/rockchip/iep/iep.h | 112 + + 7 files changed, 1513 insertions(+) diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig -index b41d3960c1b4..9ff362805ded 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/Kconfig +++ b/drivers/media/platform/rockchip/Kconfig @@ -2,5 +2,6 @@ @@ -122,7 +118,7 @@ index b41d3960c1b4..9ff362805ded 100644 source "drivers/media/platform/rockchip/rga/Kconfig" source "drivers/media/platform/rockchip/rkisp1/Kconfig" diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile -index 4f782b876ac9..c075ecc2fa14 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/Makefile +++ b/drivers/media/platform/rockchip/Makefile @@ -1,3 +1,4 @@ @@ -132,7 +128,7 @@ index 4f782b876ac9..c075ecc2fa14 100644 obj-y += rkisp1/ diff --git a/drivers/media/platform/rockchip/iep/Kconfig b/drivers/media/platform/rockchip/iep/Kconfig new file mode 100644 -index 000000000000..d95155a95133 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/iep/Kconfig @@ -0,0 +1,16 @@ @@ -154,7 +150,7 @@ index 000000000000..d95155a95133 + will be called rockchip-iep diff --git a/drivers/media/platform/rockchip/iep/Makefile b/drivers/media/platform/rockchip/iep/Makefile new file mode 100644 -index 000000000000..5c89b3277469 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/iep/Makefile @@ -0,0 +1,5 @@ @@ -165,7 +161,7 @@ index 000000000000..5c89b3277469 +obj-$(CONFIG_VIDEO_ROCKCHIP_IEP) += rockchip-iep.o diff --git a/drivers/media/platform/rockchip/iep/iep-regs.h b/drivers/media/platform/rockchip/iep/iep-regs.h new file mode 100644 -index 000000000000..a68685ef3604 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/iep/iep-regs.h @@ -0,0 +1,291 @@ @@ -462,7 +458,7 @@ index 000000000000..a68685ef3604 +#endif diff --git a/drivers/media/platform/rockchip/iep/iep.c b/drivers/media/platform/rockchip/iep/iep.c new file mode 100644 -index 000000000000..f4b9320733be +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/iep/iep.c @@ -0,0 +1,1087 @@ @@ -1555,7 +1551,7 @@ index 000000000000..f4b9320733be +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/rockchip/iep/iep.h b/drivers/media/platform/rockchip/iep/iep.h new file mode 100644 -index 000000000000..7d9fc61624b6 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/iep/iep.h @@ -0,0 +1,112 @@ @@ -1671,24 +1667,26 @@ index 000000000000..7d9fc61624b6 +}; + +#endif +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 14 Oct 2020 20:22:38 +0200 -Subject: [PATCH] ARM64: dts: rockchip: Add IEP node for RK3328 +Subject: ARM64: dts: rockchip: Add IEP node for RK3328 while at that also add the mmu required Signed-off-by: Alex Bee --- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 22 ++++++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 22 ++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index eec03adf0902..5455a46c9a6b 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -760,6 +760,28 @@ vop_mmu: iommu@ff373f00 { +@@ -791,6 +791,28 @@ vop_mmu: iommu@ff373f00 { status = "disabled"; }; @@ -1717,22 +1715,24 @@ index eec03adf0902..5455a46c9a6b 100644 hdmi: hdmi@ff3c0000 { compatible = "rockchip,rk3328-dw-hdmi"; reg = <0x0 0xff3c0000 0x0 0x20000>; +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 14 Oct 2020 20:43:12 +0200 -Subject: [PATCH] ARM64: dts: rockchip: Add IEP node for RK3399 +Subject: ARM64: dts: rockchip: Add IEP node for RK3399 Signed-off-by: Alex Bee --- - arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 13 ++++++++++++- + arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 13 +++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -index dbe6a9cb98a5..f0629b7a81c6 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -1365,14 +1365,25 @@ vdec_mmu: iommu@ff660480 { +@@ -1480,14 +1480,25 @@ vdec_mmu: iommu@ff660480 { #iommu-cells = <0>; }; @@ -1759,22 +1759,24 @@ index dbe6a9cb98a5..f0629b7a81c6 100644 }; rga: rga@ff680000 { +-- +Armbian From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 14 Oct 2020 20:53:56 +0200 -Subject: [PATCH] ARM: dts: rockchip: Add IEP node for RK3288 +Subject: ARM: dts: rockchip: Add IEP node for RK3288 Signed-off-by: Alex Bee --- - arch/arm/boot/dts/rockchip/rk3288.dtsi | 13 ++++++++++++- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 13 +++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 59fba3ac6aae..06545f423de2 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -984,14 +984,25 @@ crypto: crypto@ff8a0000 { +@@ -993,14 +993,25 @@ crypto: crypto@ff8a0000 { reset-names = "crypto-rst"; }; @@ -1801,3 +1803,6 @@ index 59fba3ac6aae..06545f423de2 100644 }; isp_mmu: iommu@ff914000 { +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/0001-temp-workaround-dma-reset.patch b/patch/kernel/archive/rockchip-6.17/0001-temp-workaround-dma-reset.patch index 5a7958751..3155ed399 100644 --- a/patch/kernel/archive/rockchip-6.17/0001-temp-workaround-dma-reset.patch +++ b/patch/kernel/archive/rockchip-6.17/0001-temp-workaround-dma-reset.patch @@ -1,14 +1,28 @@ -Temporary patch to workaround a DMA reset issue with rockchip -devices experienced at least on rk3288 and rk3328 with a message -like this: +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Wed, 20 Aug 2025 21:40:48 +0200 +Subject: [ARCHEOLOGY] workaround for rockchip gigabit ethernet not able to + init dma -rk_gmac-dwmac ff290000.ethernet end0: Failed to reset the dma +> X-Git-Archeology: - Revision ae11ad5db511f41448066fd29c1c9f5e661b023c: https://github.com/armbian/build/commit/ae11ad5db511f41448066fd29c1c9f5e661b023c +> X-Git-Archeology: Date: Wed, 20 Aug 2025 21:40:48 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: workaround for rockchip gigabit ethernet not able to init dma +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index e0fb06af1f94..156a5d25d1fd 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3133,8 +3133,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) +@@ -3134,8 +3134,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) ret = stmmac_reset(priv, priv->ioaddr); if (ret) { @@ -19,3 +33,6 @@ index e0fb06af1f94..156a5d25d1fd 100644 } /* DMA Configuration */ +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/kernel-6.8-tools-cgroup-makefile.patch b/patch/kernel/archive/rockchip-6.17/kernel-6.8-tools-cgroup-makefile.patch index 068fe8368..bbb8b1fbd 100644 --- a/patch/kernel/archive/rockchip-6.17/kernel-6.8-tools-cgroup-makefile.patch +++ b/patch/kernel/archive/rockchip-6.17/kernel-6.8-tools-cgroup-makefile.patch @@ -1,6 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 25 Mar 2024 19:38:38 +0100 +Subject: [ARCHEOLOGY] rockchip: bump edge kernel to 6.8 + +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + tools/cgroup/Makefile | 11 ++++++++++ + 1 file changed, 11 insertions(+) + diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile new file mode 100644 -index 000000000000..ffca068e4a76 +index 000000000000..111111111111 --- /dev/null +++ b/tools/cgroup/Makefile @@ -0,0 +1,11 @@ @@ -15,3 +74,6 @@ index 000000000000..ffca068e4a76 + +clean: + $(RM) cgroup_event_listener +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/libreelec.series b/patch/kernel/archive/rockchip-6.17/libreelec.series index a717d0ef3..d7a4fe3bb 100644 --- a/patch/kernel/archive/rockchip-6.17/libreelec.series +++ b/patch/kernel/archive/rockchip-6.17/libreelec.series @@ -63,7 +63,7 @@ patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch - patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch +# patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-ds1307.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-ds1307.dtbo deleted file mode 100644 index 937c261ae..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-ds1307.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c1.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c1.dtbo deleted file mode 100644 index fd1b3d988..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c1.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c4.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c4.dtbo deleted file mode 100644 index aa2836e20..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-i2c4.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi0.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi0.dtbo deleted file mode 100644 index 060d23bce..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi0.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi2.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi2.dtbo deleted file mode 100644 index 7bedbcbee..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spi2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev0.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev0.dtbo deleted file mode 100644 index 2423a6ca4..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev0.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev2.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev2.dtbo deleted file mode 100644 index 65f6860c6..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-spidev2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart1.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart1.dtbo deleted file mode 100644 index 0b820aa44..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart1.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart2.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart2.dtbo deleted file mode 100644 index 3e57168c2..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart2.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart3.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart3.dtbo deleted file mode 100644 index d171ece89..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart3.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart4.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart4.dtbo deleted file mode 100644 index 795fdebae..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-uart4.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-w1-gpio.dtbo b/patch/kernel/archive/rockchip-6.17/overlay/rockchip-w1-gpio.dtbo deleted file mode 100644 index 6bbc11452..000000000 Binary files a/patch/kernel/archive/rockchip-6.17/overlay/rockchip-w1-gpio.dtbo and /dev/null differ diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/bt-broadcom-serdev-workaround.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/bt-broadcom-serdev-workaround.patch index a876f6973..3b37fa347 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/bt-broadcom-serdev-workaround.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/bt-broadcom-serdev-workaround.patch @@ -9,12 +9,10 @@ Subject: Workaround to make several broadcom bluetooth serdev devices work 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c -index 3a3a56ddbb06..de66fe473595 100644 +index 111111111111..222222222222 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c -@@ -133,11 +133,11 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) - !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) { - /* Try falling back to BDADDR EFI variable */ +@@ -135,7 +135,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) if (btbcm_set_bdaddr_from_efi(hdev) != 0) { bt_dev_info(hdev, "BCM: Using default device address (%pMR)", &bda->bdaddr); @@ -23,8 +21,6 @@ index 3a3a56ddbb06..de66fe473595 100644 } } - kfree_skb(skb); - --- +-- Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/clk-rk322x-composite-mmc-clk.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/clk-rk322x-composite-mmc-clk.patch index 1c889e358..4d8ca1bdf 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/clk-rk322x-composite-mmc-clk.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/clk-rk322x-composite-mmc-clk.patch @@ -1,17 +1,17 @@ -From 9e105544fcb63f8f79b199d1b194a36a354519b3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 2 Apr 2023 10:53:07 +0000 -Subject: [PATCH 2/2] rk322x: better handle mmc/sdio clocks +Subject: rk322x: better handle mmc/sdio clocks --- drivers/clk/rockchip/clk-rk3228.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 996f8bfee..0f690dd84 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -371,17 +371,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -383,17 +383,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, RK2928_CLKGATE_CON(2), 11, GFLAGS), @@ -34,5 +34,5 @@ index 996f8bfee..0f690dd84 100644 /* * Clock-Architecture Diagram 2 -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk322x-audio-codec.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk322x-audio-codec.patch index a4492b9d3..8c41f3504 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk322x-audio-codec.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk322x-audio-codec.patch @@ -1,25 +1,22 @@ -From 50a8db983c682918cd2efe02ede48db93892d52a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 20 Jul 2024 13:51:55 +0200 -Subject: [PATCH] rk3228: add analog audio codec +Subject: rk3228: add analog audio codec --- - .../bindings/sound/rockchip,rk3228-codec.txt | 22 + - arch/arm/boot/dts/rockchip/rk322x.dtsi | 9 + - drivers/clk/rockchip/clk-rk3228.c | 2 +- - include/dt-bindings/clock/rk3228-cru.h | 1 + - sound/soc/codecs/Kconfig | 6 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/rk3228_codec.c | 545 ++++++++++++++++++ - sound/soc/codecs/rk3228_codec.h | 218 +++++++ + Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt | 22 + + arch/arm/boot/dts/rockchip/rk322x.dtsi | 9 + + drivers/clk/rockchip/clk-rk3228.c | 2 +- + include/dt-bindings/clock/rk3228-cru.h | 1 + + sound/soc/codecs/Kconfig | 6 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/rk3228_codec.c | 545 ++++++++++ + sound/soc/codecs/rk3228_codec.h | 218 ++++ 8 files changed, 804 insertions(+), 1 deletion(-) - create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt - create mode 100644 sound/soc/codecs/rk3228_codec.c - create mode 100644 sound/soc/codecs/rk3228_codec.h diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt new file mode 100644 -index 000000000000..9191a8593380 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt @@ -0,0 +1,22 @@ @@ -46,10 +43,10 @@ index 000000000000..9191a8593380 + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index cc5a5e609f04..d13dc979a67e 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -249,6 +249,15 @@ i2s1: i2s1@100b0000 { +@@ -148,6 +148,15 @@ i2s1: i2s1@100b0000 { status = "disabled"; }; @@ -66,10 +63,10 @@ index cc5a5e609f04..d13dc979a67e 100644 compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100c0000 0x4000>; diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 0db8a97007f2..0f690dd84650 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -603,7 +603,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -618,7 +618,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), @@ -79,10 +76,10 @@ index 0db8a97007f2..0f690dd84650 100644 GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h -index 911824731866..9162f9132657 100644 +index 111111111111..222222222222 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h -@@ -116,6 +116,7 @@ +@@ -115,6 +115,7 @@ #define PCLK_HDMI_CTRL 364 #define PCLK_HDMI_PHY 365 #define PCLK_GMAC 367 @@ -91,10 +88,10 @@ index 911824731866..9162f9132657 100644 /* hclk gates */ #define HCLK_I2S0_8CH 442 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 4afc43d3f71f..183a69249160 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -182,6 +182,7 @@ config SND_SOC_ALL_CODECS +@@ -193,6 +193,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_PCM6240 imply SND_SOC_PEB2466 imply SND_SOC_RK3308 @@ -102,7 +99,7 @@ index 4afc43d3f71f..183a69249160 100644 imply SND_SOC_RK3328 imply SND_SOC_RK817 imply SND_SOC_RT274 -@@ -1457,6 +1458,11 @@ config SND_SOC_RK3308 +@@ -1554,6 +1555,11 @@ config SND_SOC_RK3308 It has 8 24-bit ADCs and 2 24-bit DACs. The maximum supported sampling rate is 192 kHz. @@ -115,10 +112,10 @@ index 4afc43d3f71f..183a69249160 100644 tristate "Rockchip RK3328 audio CODEC" depends on ARCH_ROCKCHIP || COMPILE_TEST diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index b4df22186e25..454179eb7b73 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -207,6 +207,7 @@ snd-soc-pcm512x-spi-y := pcm512x-spi.o +@@ -223,6 +223,7 @@ snd-soc-pcm512x-spi-y := pcm512x-spi.o snd-soc-pcm6240-y := pcm6240.o snd-soc-peb2466-y := peb2466.o snd-soc-rk3308-y := rk3308_codec.o @@ -126,7 +123,7 @@ index b4df22186e25..454179eb7b73 100644 snd-soc-rk3328-y := rk3328_codec.o snd-soc-rk817-y := rk817_codec.o snd-soc-rl6231-y := rl6231.o -@@ -599,6 +600,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +@@ -643,6 +644,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o obj-$(CONFIG_SND_SOC_PCM6240) += snd-soc-pcm6240.o obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o @@ -136,7 +133,7 @@ index b4df22186e25..454179eb7b73 100644 obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o diff --git a/sound/soc/codecs/rk3228_codec.c b/sound/soc/codecs/rk3228_codec.c new file mode 100644 -index 000000000000..197e7e2e0d8b +index 000000000000..111111111111 --- /dev/null +++ b/sound/soc/codecs/rk3228_codec.c @@ -0,0 +1,545 @@ @@ -687,7 +684,7 @@ index 000000000000..197e7e2e0d8b +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rk3228_codec.h b/sound/soc/codecs/rk3228_codec.h new file mode 100644 -index 000000000000..7283d0ba86e8 +index 000000000000..111111111111 --- /dev/null +++ b/sound/soc/codecs/rk3228_codec.h @@ -0,0 +1,218 @@ @@ -910,5 +907,5 @@ index 000000000000..7283d0ba86e8 + +#endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk3288-gpiomem.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk3288-gpiomem.patch index e2f887bdd..8fe777043 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk3288-gpiomem.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-rk3288-gpiomem.patch @@ -1,8 +1,153 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Igor Pecovnik +Date: Thu, 24 May 2018 15:44:15 +0200 +Subject: [ARCHEOLOGY] Merging Rockchip family + +> X-Git-Archeology: - Revision 7d2f3af08f23049c91c88eec5062613bbfbc85d4: https://github.com/armbian/build/commit/7d2f3af08f23049c91c88eec5062613bbfbc85d4 +> X-Git-Archeology: Date: Thu, 24 May 2018 15:44:15 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Merging Rockchip family +> X-Git-Archeology: +> X-Git-Archeology: - Revision fafd26db7e055a87e775fdc18de8e64f95e53d41: https://github.com/armbian/build/commit/fafd26db7e055a87e775fdc18de8e64f95e53d41 +> X-Git-Archeology: Date: Thu, 28 Jun 2018 22:11:59 -0400 +> X-Git-Archeology: From: Tony +> X-Git-Archeology: Subject: Rockchip default merge (#1026) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96e78c102f8c9a3719b9cb4a9eb6becb063891ce: https://github.com/armbian/build/commit/96e78c102f8c9a3719b9cb4a9eb6becb063891ce +> X-Git-Archeology: Date: Sun, 08 Jul 2018 13:19:07 -0700 +> X-Git-Archeology: From: Rabit +> X-Git-Archeology: Subject: ASUS Tinkerboard: Restore justice - author of the gpiomem port +> X-Git-Archeology: +> X-Git-Archeology: - Revision 106685906579e4c5528fcd22abf79c6719d633fb: https://github.com/armbian/build/commit/106685906579e4c5528fcd22abf79c6719d633fb +> X-Git-Archeology: Date: Sun, 08 Jul 2018 14:12:15 -0700 +> X-Git-Archeology: From: Rabit +> X-Git-Archeology: Subject: ASUS Tinkerboard: Added gpio & i2c groups with udev rules to devices +> X-Git-Archeology: +> X-Git-Archeology: - Revision de41d3dbce3ed5e467019c0f74ac93dbeb866ded: https://github.com/armbian/build/commit/de41d3dbce3ed5e467019c0f74ac93dbeb866ded +> X-Git-Archeology: Date: Fri, 10 Aug 2018 10:33:42 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Rockchip default cleanup. (Temporally) moving back to Rockchip upstream. This source builds but doesn't boot ... +> X-Git-Archeology: +> X-Git-Archeology: - Revision fc1715450015ae62374a13d77f19b0ab53bb1d4c: https://github.com/armbian/build/commit/fc1715450015ae62374a13d77f19b0ab53bb1d4c +> X-Git-Archeology: Date: Sat, 13 Jul 2019 15:14:54 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: rockchip-dev: bump to 5.2, adjust pathes, add gpio_mem driver +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 744ea89a589d62cb6f409baab60fc6664520bc39: https://github.com/armbian/build/commit/744ea89a589d62cb6f409baab60fc6664520bc39 +> X-Git-Archeology: Date: Wed, 08 Sep 2021 17:51:34 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bumping EDGE kernel to 5.14.y (#3125) +> X-Git-Archeology: +> X-Git-Archeology: - Revision a1d044de8e0bb6ca504386bc31f5615a9d169067: https://github.com/armbian/build/commit/a1d044de8e0bb6ca504386bc31f5615a9d169067 +> X-Git-Archeology: Date: Tue, 12 Oct 2021 15:59:01 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: update support for edge kernel 5.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9: https://github.com/armbian/build/commit/4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9 +> X-Git-Archeology: Date: Tue, 09 Nov 2021 21:58:35 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Rockchip 5.15 (#3242) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 3f704692a7933a67b5e8cc6ff690d92ef3a5e735: https://github.com/armbian/build/commit/3f704692a7933a67b5e8cc6ff690d92ef3a5e735 +> X-Git-Archeology: Date: Fri, 24 Mar 2023 23:12:56 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.2 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4605bcab83d3d0c0360da7dd0f9ee90e884b58e4: https://github.com/armbian/build/commit/4605bcab83d3d0c0360da7dd0f9ee90e884b58e4 +> X-Git-Archeology: Date: Sun, 09 Jul 2023 11:24:10 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge kernel to 6.4 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 3 + + arch/arm/boot/dts/rockchip/rk3288.dtsi | 6 + + drivers/char/Kconfig | 1 + + drivers/char/Makefile | 2 + + drivers/char/rockchip/Kconfig | 16 + + drivers/char/rockchip/Makefile | 1 + + drivers/char/rockchip/rk3288-gpiomem.c | 303 ++++++++++ + 7 files changed, 332 insertions(+) + diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index e5b7ef1a5..f88c913ff 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -544,3 +544,6 @@ +@@ -544,3 +544,6 @@ &vopl_mmu { &wdt { status = "okay"; }; @@ -10,13 +155,13 @@ index e5b7ef1a5..f88c913ff 100644 + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index f3ca55496..14bbcb192 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1418,6 +1418,12 @@ +@@ -1468,6 +1468,12 @@ gic: interrupt-controller@ffc01000 { interrupts = ; }; - + + gpiomem: rk3288-gpiomem@ff750000 { + compatible = "rockchip,rk3288-gpiomem"; + reg = <0x0 0xff750000 0x0 0x1000>; @@ -26,27 +171,26 @@ index f3ca55496..14bbcb192 100644 pinctrl: pinctrl { compatible = "rockchip,rk3288-pinctrl"; rockchip,grf = <&grf>; - diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index 3143db5..9c18b74 100644 +index 111111111111..222222222222 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig -@@ -5,6 +5,7 @@ +@@ -6,6 +6,7 @@ menu "Character devices" - + source "drivers/tty/Kconfig" +source "drivers/char/rockchip/Kconfig" - - config DEVMEM - bool "/dev/mem virtual device support" + + config TTY_PRINTK + tristate "TTY driver to output user messages via printk" diff --git a/drivers/char/Makefile b/drivers/char/Makefile -index 264eb398f..9fd5f240b 100644 +index 111111111111..222222222222 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile -@@ -43,6 +43,8 @@ obj-$(CONFIG_TCG_TPM) += tpm/ - +@@ -40,6 +40,8 @@ obj-$(CONFIG_TCG_TPM) += tpm/ + obj-$(CONFIG_PS3_FLASH) += ps3flash.o - + +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ + obj-$(CONFIG_XILLYBUS_CLASS) += xillybus/ @@ -54,7 +198,7 @@ index 264eb398f..9fd5f240b 100644 obj-$(CONFIG_ADI) += adi.o diff --git a/drivers/char/rockchip/Kconfig b/drivers/char/rockchip/Kconfig new file mode 100644 -index 0000000..6e97486 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/Kconfig @@ -0,0 +1,16 @@ @@ -77,7 +221,7 @@ index 0000000..6e97486 \ No newline at end of file diff --git a/drivers/char/rockchip/Makefile b/drivers/char/rockchip/Makefile new file mode 100644 -index 0000000..2287ec2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/Makefile @@ -0,0 +1 @@ @@ -85,7 +229,7 @@ index 0000000..2287ec2 \ No newline at end of file diff --git a/drivers/char/rockchip/rk3288-gpiomem.c b/drivers/char/rockchip/rk3288-gpiomem.c new file mode 100644 -index 0000000..984471c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/char/rockchip/rk3288-gpiomem.c @@ -0,0 +1,303 @@ @@ -393,3 +537,6 @@ index 0000000..984471c +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); \ No newline at end of file +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-tinkerboard-alc4040-codec.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-tinkerboard-alc4040-codec.patch index f85f24fb7..37f814394 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-tinkerboard-alc4040-codec.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/driver-tinkerboard-alc4040-codec.patch @@ -1,8 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony +Date: Sun, 15 Apr 2018 14:40:58 -0400 +Subject: [ARCHEOLOGY] Rockchip next sync master and development + +> X-Git-Archeology: > recovered message: > includes kernel panic fix on veth interfaces and audio device patch to enable Tinkerboard audio +> X-Git-Archeology: - Revision b1a21a44cde3d976b9b8ebce4f265e5aa79b2d8a: https://github.com/armbian/build/commit/b1a21a44cde3d976b9b8ebce4f265e5aa79b2d8a +> X-Git-Archeology: Date: Sun, 15 Apr 2018 14:40:58 -0400 +> X-Git-Archeology: From: Tony +> X-Git-Archeology: Subject: Rockchip next sync master and development +> X-Git-Archeology: +> X-Git-Archeology: - Revision b6f1503dfdb215429cc6dee6c2b94ca9ddc96fbc: https://github.com/armbian/build/commit/b6f1503dfdb215429cc6dee6c2b94ca9ddc96fbc +> X-Git-Archeology: Date: Mon, 26 Nov 2018 01:38:25 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ tinkerboard ] dev kernel add audio support +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + sound/usb/card.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + diff --git a/sound/usb/card.c b/sound/usb/card.c -index 2bfe4e80a..cea93aaf5 100644 +index 111111111111..222222222222 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c -@@ -382,6 +382,14 @@ static void usb_audio_make_shortname(struct usb_device *dev, +@@ -623,6 +623,14 @@ static void usb_audio_make_shortname(struct usb_device *dev, } strim(card->shortname); @@ -17,3 +82,6 @@ index 2bfe4e80a..cea93aaf5 100644 } static void usb_audio_make_longname(struct usb_device *dev, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-plane-overlay.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-plane-overlay.patch index 15319a894..e5ad3e427 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-plane-overlay.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-plane-overlay.patch @@ -1,9 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: paolo +Date: Sat, 19 Sep 2020 15:20:16 +0000 +Subject: [ARCHEOLOGY] Many changes for rk322x target: + +> X-Git-Archeology: > recovered message: > - Chanaged default x.org configuration to disable glamor +> X-Git-Archeology: > recovered message: > - Reintroduce patch to use DRM cursor plane as overlay in rk322x-current and -dev +> X-Git-Archeology: > recovered message: > - Updated wifi patches for kernel 5.8.10 +> X-Git-Archeology: > recovered message: > - Bumped rk322x to u-boot v2020.07, removed reserved zones from device trees +> X-Git-Archeology: > recovered message: > - Updated OPTEE to v3.10, using ddrbin v1.10 +> X-Git-Archeology: > recovered message: > - Bumped rk322x-current to kernel 5.8.y +> X-Git-Archeology: > recovered message: > - Imported new patches from knaerzche's LibreELEC fork for rk322x-dev (kernel 5.8.y) +> X-Git-Archeology: > recovered message: > - Adjusted existing patches to match changes, updated rk322x-dev kernel config file +> X-Git-Archeology: > recovered message: > - Add default modprobe conf file for esp8089 to force the crystal frequency to 40Mhz for rk322x targets +> X-Git-Archeology: > recovered message: > - Removed ssv6051 firmware packages to move to armbian-firmware repository +> X-Git-Archeology: > recovered message: > - Switching ssv6051-wifi.cfg to /lib/firmware for rk322x-legacy +> X-Git-Archeology: > recovered message: > - Removed P2P interface for esp8089 driver for rk322x-legacy +> X-Git-Archeology: > recovered message: > - Optimized ssv6051 performance: kernel module gains -Os flag, disabled p2p interface, enabled HW crypto for CCMP cipher +> X-Git-Archeology: > recovered message: > - Enabled remote control interface, IR GPIO kernel module and HDMI CEC modules +> X-Git-Archeology: - Revision bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076: https://github.com/armbian/build/commit/bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076 +> X-Git-Archeology: Date: Sat, 19 Sep 2020 15:20:16 +0000 +> X-Git-Archeology: From: paolo +> X-Git-Archeology: Subject: Many changes for rk322x target: +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 44 +++++++++- + 1 file changed, 41 insertions(+), 3 deletions(-) + diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 73d24c6bbf05..d4ac6e161ef2 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -614,6 +614,44 @@ static const struct vop_common rk3288_common = { - .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), +@@ -729,6 +729,44 @@ static const struct vop_common rk3288_common = { + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), }; +static const struct vop_win_phy rk3228_win0_data = { @@ -47,7 +110,7 @@ index 73d24c6bbf05..d4ac6e161ef2 100644 /* * Note: rk3288 has a dedicated 'cursor' window, however, that window requires * special support to get alpha blending working. For now, just use overlay -@@ -864,10 +902,10 @@ static const struct vop_data rk3399_vop_lit = { +@@ -1088,10 +1126,10 @@ static const struct vop_data rk3399_vop_lit = { }; static const struct vop_win_data rk3228_vop_win_data[] = { @@ -62,5 +125,5 @@ index 73d24c6bbf05..d4ac6e161ef2 100644 static const struct vop_data rk3228_vop = { -- -2.17.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-yuv-10bit-modes.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-yuv-10bit-modes.patch index acd738f00..9e01747e0 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-yuv-10bit-modes.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rk322x-yuv-10bit-modes.patch @@ -1,17 +1,17 @@ -From 2d42546642fa4299d88fa4ae414fa1ab205dad70 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 11 Sep 2021 17:38:48 +0000 -Subject: [PATCH] rk322x: enable YUV modes for win1, 10-bit for win0/win1 +Subject: rk322x: enable YUV modes for win1, 10-bit for win0/win1 --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 70930b410..3fd00b323 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -719,10 +719,11 @@ static const struct vop_common rk3288_common = { +@@ -731,10 +731,11 @@ static const struct vop_common rk3288_common = { static const struct vop_win_phy rk3228_win0_data = { .scl = &rk3288_win_full_scl, @@ -25,7 +25,7 @@ index 70930b410..3fd00b323 100644 .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), -@@ -738,10 +739,11 @@ static const struct vop_win_phy rk3228_win0_data = { +@@ -750,10 +751,11 @@ static const struct vop_win_phy rk3228_win0_data = { static const struct vop_win_phy rk3228_win1_data = { .scl = &rk3288_win_full_scl, @@ -40,5 +40,5 @@ index 70930b410..3fd00b323 100644 .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rockchip-hardware-cursor.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rockchip-hardware-cursor.patch index bd5993ce0..4b5922bbe 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rockchip-hardware-cursor.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/drm-rockchip-hardware-cursor.patch @@ -1,16 +1,16 @@ -From e5bb429dc58c8b4fc7a52dcb2fb134a838a4a952 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 16 Sep 2025 14:08:52 +0200 -Subject: [PATCH] drm rockchip hardware cursor +Subject: drm rockchip hardware cursor --- - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 208 +++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 208 +++++++++- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 3 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 21 +- 3 files changed, 229 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index ba6b0528d1e5..b488df65cfea 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1144,6 +1144,197 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane, @@ -250,7 +250,7 @@ index ba6b0528d1e5..b488df65cfea 100644 if (plane->type == DRM_PLANE_TYPE_PRIMARY) primary = plane; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h -index f04c9731ae7b..3de7e79a2a80 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -206,6 +206,8 @@ struct vop_win_phy { @@ -271,7 +271,7 @@ index f04c9731ae7b..3de7e79a2a80 100644 }; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 95a0a44ba457..2c9f523c9250 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -696,6 +696,19 @@ static const struct vop_win_phy rk3288_win23_data = { @@ -328,5 +328,5 @@ index 95a0a44ba457..2c9f523c9250 100644 .common = &rk3288_common, .modeset = &rk3288_modeset, -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-fan.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-fan.patch index b4b05a4ab..3c12f55f8 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-fan.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-fan.patch @@ -1,7 +1,7 @@ -From c27e445527e949f3ef46d5326066196969c17d23 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Date: Sun, 12 Mar 2017 19:43:15 +0000 -Subject: [PATCH 06/28] ARM: dts: rockchip: add the MiQi board's fan definition +Subject: ARM: dts: rockchip: add the MiQi board's fan definition The MiQi board is sold with an enclosure in which a fan is connected to the second LED output, and configured by default in "heartbeat" @@ -24,10 +24,10 @@ Signed-off-by: Myy 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index a1c3cdaa..0e383595 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -67,6 +67,13 @@ +@@ -30,6 +30,13 @@ ext_gmac: external-gmac-clock { leds { compatible = "gpio-leds"; @@ -42,4 +42,5 @@ index a1c3cdaa..0e383595 100644 gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>; label = "miqi:green:user"; -- -2.11.0 +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-hevc-rga.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-hevc-rga.patch index f1d54b97c..b4f17f38a 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-hevc-rga.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-hevc-rga.patch @@ -1,17 +1,17 @@ -From 2fdd826a704ef70df42d92b38ad88ef869c3729b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 18 Sep 2021 12:32:05 +0000 -Subject: [PATCH 2/2] rockchip: enable hevc, hevc_mmu and rga nodes for miqi +Subject: rockchip: enable hevc, hevc_mmu and rga nodes for miqi --- - arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 12 ++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 12 ++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 94bc76099..68eb766f0 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -162,6 +162,14 @@ &hdmi { +@@ -157,6 +157,14 @@ &hdmi { status = "okay"; }; @@ -26,7 +26,7 @@ index 94bc76099..68eb766f0 100644 &i2c0 { clock-frequency = <400000>; status = "okay"; -@@ -405,6 +413,10 @@ host_vbus_drv: host-vbus-drv { +@@ -399,6 +407,10 @@ host_vbus_drv: host-vbus-drv { }; }; @@ -38,5 +38,5 @@ index 94bc76099..68eb766f0 100644 vref-supply = <&vcc_18>; status = "okay"; -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-mali-gpu.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-mali-gpu.patch index 6a07886e7..a4a8d73be 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-mali-gpu.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-mali-gpu.patch @@ -1,7 +1,7 @@ -From 604ea7fc311af2b3a41e7fe3b4fbde0ee03dfb9c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Thu, 19 Oct 2017 21:09:50 +0200 -Subject: [PATCH 04/28] dts: rk3288: miqi: Enabling the Mali GPU node +Subject: dts: rk3288: miqi: Enabling the Mali GPU node Why is the MiQi the only one left without a working mali GPU node ? @@ -15,11 +15,11 @@ Signed-off-by: Myy Miouyouyou 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 4d923aa6..3cd60674 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -149,6 +149,11 @@ - status = "ok"; +@@ -150,6 +150,11 @@ &gpu { + status = "okay"; }; +&gpu { @@ -29,7 +29,7 @@ index 4d923aa6..3cd60674 100644 + &hdmi { ddc-i2c-bus = <&i2c5>; - status = "okay"; + pinctrl-names = "default"; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-regulator-fix.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-regulator-fix.patch index 01c66a95f..0d715fb96 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-regulator-fix.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-miqi-regulator-fix.patch @@ -1,8 +1,7 @@ -From 89e5763110ca77d68a4be00cd97a638adc2401d5 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 2 Aug 2016 08:31:00 +0200 -Subject: [PATCH 05/28] ARM: dts: rockchip: fix the regulator's voltage range - on MiQi board +Subject: ARM: dts: rockchip: fix the regulator's voltage range on MiQi board The board declared too narrow a voltage range for the CPU and GPU regulators, preventing it from using the full CPU frequency range. @@ -15,10 +14,10 @@ Signed-off-by: Willy Tarreau 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 3cd60674..a1c3cdaa 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -@@ -168,8 +168,8 @@ +@@ -179,8 +179,8 @@ vdd_cpu: syr827@40 { fcs,suspend-voltage-selector = <1>; reg = <0x40>; regulator-name = "vdd_cpu"; @@ -29,7 +28,7 @@ index 3cd60674..a1c3cdaa 100644 regulator-always-on; regulator-boot-on; regulator-enable-ramp-delay = <300>; -@@ -182,8 +182,8 @@ +@@ -193,8 +193,8 @@ vdd_gpu: syr828@41 { fcs,suspend-voltage-selector = <1>; reg = <0x41>; regulator-name = "vdd_gpu"; @@ -41,5 +40,5 @@ index 3cd60674..a1c3cdaa 100644 vin-supply = <&vcc_sys>; }; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-iep-node.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-iep-node.patch index 994f01e8e..0bc155d77 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-iep-node.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-iep-node.patch @@ -1,17 +1,17 @@ -From adecdd57a0155e0d96af2c84cc4fa52309fbb535 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 19:14:08 +0000 -Subject: [PATCH] add iep node for rk322x +Subject: add iep node for rk322x --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 11 +++++++++++ + arch/arm/boot/dts/rockchip/rk322x.dtsi | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 0ae753c1d..271e7835f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -834,6 +834,17 @@ rga: rga@20060000 { +@@ -714,6 +714,17 @@ rga: rga@20060000 { reset-names = "core", "axi", "ahb"; }; @@ -30,5 +30,5 @@ index 0ae753c1d..271e7835f 100644 compatible = "rockchip,iommu"; reg = <0x20070800 0x100>; -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-pinctrl-nand.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-pinctrl-nand.patch index 6c6ab33ff..f13c6b52a 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-pinctrl-nand.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk322x-pinctrl-nand.patch @@ -1,8 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Fri, 19 Jun 2020 17:27:27 +0200 +Subject: [ARCHEOLOGY] Introducing Rockchip RK322X SoC support (#2032) + +> X-Git-Archeology: > recovered message: > * Introducing Rockchip rk322x SoC support +> X-Git-Archeology: > recovered message: > Main features: +> X-Git-Archeology: > recovered message: > - Legacy kernel flavour based upon stable v2.x rk3288 Rockchip branch (https://github.com/rockchip-linux/kernel/tree/stable-4.4-rk3288-linux-v2.x) +> X-Git-Archeology: > recovered message: > - Current kernel flavour based on mainline 5.6.y kernel +> X-Git-Archeology: > recovered message: > - Mainline u-boot (v2020.04) +> X-Git-Archeology: > recovered message: > - Single generic tv box target (rk322x-box) which boots on all the known tv boxes +> X-Git-Archeology: > recovered message: > - Hardware devices (eMMC/NAND, led wiring configuration, SoC variant selection) modulation done by user at runtime via device tree overlays - a script (rk322x-config) is provided for autodetection and simple configuration by inexperienced users; +> X-Git-Archeology: > recovered message: > - Bits added to armbian-hardware-optimization to set affinity for irq handlers +> X-Git-Archeology: > recovered message: > - rk322x-box targets already added to targets.conf for automatic image creation +> X-Git-Archeology: > recovered message: > * Removed disabled patches +> X-Git-Archeology: > recovered message: > * Restored mysteriously removed comment character +> X-Git-Archeology: - Revision 23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7: https://github.com/armbian/build/commit/23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7 +> X-Git-Archeology: Date: Fri, 19 Jun 2020 17:27:27 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Introducing Rockchip RK322X SoC support (#2032) +> X-Git-Archeology: +> X-Git-Archeology: - Revision bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076: https://github.com/armbian/build/commit/bd17d4dbd0025908b6f0aa58d74f2bc8cfedb076 +> X-Git-Archeology: Date: Sat, 19 Sep 2020 15:20:16 +0000 +> X-Git-Archeology: From: paolo +> X-Git-Archeology: Subject: Many changes for rk322x target: +> X-Git-Archeology: +> X-Git-Archeology: - Revision 95425c27b9d3bbb96e7936cc531638c9150538f9: https://github.com/armbian/build/commit/95425c27b9d3bbb96e7936cc531638c9150538f9 +> X-Git-Archeology: Date: Fri, 12 Mar 2021 20:20:12 +0000 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: Changes and fixes to rk322x uboot and kernel config +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9: https://github.com/armbian/build/commit/4c3dcbf4fcd3616999cb91a1dddfa74668eb6de9 +> X-Git-Archeology: Date: Tue, 09 Nov 2021 21:58:35 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Rockchip 5.15 (#3242) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0a2892aeba4dec4633a86f8ad573bf62f09cdb38: https://github.com/armbian/build/commit/0a2892aeba4dec4633a86f8ad573bf62f09cdb38 +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:47:01 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rk322x: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk322x.dtsi | 75 ++++++++++ + 1 file changed, 75 insertions(+) + diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 48e6e8d44..1dfd27f9f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -712,6 +712,22 @@ emmc: mmc@30020000 { +@@ -817,6 +817,22 @@ emmc: mmc@30020000 { status = "disabled"; }; @@ -25,7 +105,7 @@ index 48e6e8d44..1dfd27f9f 100644 usb_otg: usb@30040000 { compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb", "snps,dwc2"; -@@ -950,6 +966,65 @@ emmc_bus8: emmc-bus8 { +@@ -1100,6 +1116,65 @@ emmc_bus8: emmc-bus8 { }; }; @@ -91,3 +171,6 @@ index 48e6e8d44..1dfd27f9f 100644 gmac { rgmii_pins: rgmii-pins { rockchip,pins = <2 RK_PB6 1 &pcfg_pull_none>, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-disable-serial-dma.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-disable-serial-dma.patch index b54cf9d59..7a4203364 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-disable-serial-dma.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-disable-serial-dma.patch @@ -1,8 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Sun, 14 Jun 2020 22:59:24 +0200 +Subject: [ARCHEOLOGY] [RK3288] Bump rockchip-dev to kernel 5.7 (#2018) + +> X-Git-Archeology: > recovered message: > * Moved rockchip-dev to kernel 5.7, removed already upstreamed patch (1016), adjusted conflicting patch (1015) +> X-Git-Archeology: > recovered message: > Most kernel configuration answer left at default, notables: +> X-Git-Archeology: > recovered message: > - Wireguard (as module) +> X-Git-Archeology: > recovered message: > - Zswap default compression set to LZO +> X-Git-Archeology: > recovered message: > - RK3288 GPIOMEM (as module) +> X-Git-Archeology: > recovered message: > - Enabled some new DMABUF bits (heaps, cmas) +> X-Git-Archeology: > recovered message: > - Hantro driver +> X-Git-Archeology: > recovered message: > - F2FS compression +> X-Git-Archeology: > recovered message: > * Disabled rx/tx dma for uarts, on my board causes system freeze during bluetooth initialization. Don't know if they ever worked, tried to enable them ages ago and they were already not working +> X-Git-Archeology: - Revision 8f9f12065eab021a57bc782916da77348998074f: https://github.com/armbian/build/commit/8f9f12065eab021a57bc782916da77348998074f +> X-Git-Archeology: Date: Sun, 14 Jun 2020 22:59:24 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: [RK3288] Bump rockchip-dev to kernel 5.7 (#2018) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 812245def37a695bce9e7ece148b2920d82c8b37: https://github.com/armbian/build/commit/812245def37a695bce9e7ece148b2920d82c8b37 +> X-Git-Archeology: Date: Sat, 18 Jul 2020 23:07:01 +0200 +> X-Git-Archeology: From: Werner +> X-Git-Archeology: Subject: Move rockchip/64 current to 5.7.y (#2099) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54bc65b3bbd244820d950366523149f1c437223f: https://github.com/armbian/build/commit/54bc65b3bbd244820d950366523149f1c437223f +> X-Git-Archeology: Date: Wed, 17 Feb 2021 01:36:25 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump DEV kernels to 5.11.y (#2636) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 8 -------- + 1 file changed, 8 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 0cd88774d..07681f1f0 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -420,8 +420,6 @@ +@@ -384,8 +384,6 @@ uart0: serial@ff180000 { reg-io-width = <4>; clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; @@ -11,7 +89,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>; status = "disabled"; -@@ -435,8 +433,6 @@ +@@ -399,8 +397,6 @@ uart1: serial@ff190000 { reg-io-width = <4>; clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; clock-names = "baudclk", "apb_pclk"; @@ -20,7 +98,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "disabled"; -@@ -463,8 +459,6 @@ +@@ -427,8 +423,6 @@ uart3: serial@ff1b0000 { reg-io-width = <4>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; @@ -29,7 +107,7 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart3_xfer>; status = "disabled"; -@@ -478,8 +472,6 @@ +@@ -442,8 +436,6 @@ uart4: serial@ff1c0000 { reg-io-width = <4>; clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; clock-names = "baudclk", "apb_pclk"; @@ -38,3 +116,6 @@ index 0cd88774d..07681f1f0 100644 pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer>; status = "disabled"; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-fix-mmc-aliases.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-fix-mmc-aliases.patch index dede52866..98e437690 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-fix-mmc-aliases.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-fix-mmc-aliases.patch @@ -1,8 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 26 Dec 2023 16:45:30 +0100 +Subject: [ARCHEOLOGY] consolidate rk322x and rockchip 32 bit families + +> X-Git-Archeology: > recovered message: > * merge patches from rockchip and rk322x families for current and edge +> X-Git-Archeology: > recovered message: > kernels +> X-Git-Archeology: > recovered message: > * adjust patches for tinkerboard to remove some cruft and overclocking +> X-Git-Archeology: > recovered message: > * rework kernel configs +> X-Git-Archeology: > recovered message: > * fix rk322x dmc to avoid lockup on rk3288 +> X-Git-Archeology: > recovered message: > * migrate rockchip-6.6 into patch series, rename all patches with +> X-Git-Archeology: > recovered message: > more understandable names +> X-Git-Archeology: > recovered message: > * add gen-series.sh script in tools directory (it is a naive tool to +> X-Git-Archeology: > recovered message: > create patch series when you don't want to rebase everything) +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 511ca864c1b2..d7ecb6b4de40 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -25,10 +25,10 @@ aliases { +@@ -34,10 +34,10 @@ aliases { i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; @@ -17,4 +65,6 @@ index 511ca864c1b2..d7ecb6b4de40 100644 serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; +-- +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch index 6a91d9226..205e9f1dc 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-gpu-500mhz-opp.patch @@ -1,7 +1,7 @@ -From 73258d32daf3a661281bb5c77c5e2e06c7ff714e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Fri, 3 Jul 2020 02:02:18 +0200 -Subject: [PATCH] arm: dtsi: rk3288: add GPU 500 Mhz OPP again +Subject: arm: dtsi: rk3288: add GPU 500 Mhz OPP again Undoing the very bizarre mainline kernel patch, 75481833c6dbab4c29d15452f6b4337c16f5407b @@ -23,10 +23,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index a66412547..ef7457f79 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -1312,6 +1312,10 @@ opp-400000000 { +@@ -1343,6 +1343,10 @@ opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1100000>; }; @@ -38,5 +38,5 @@ index a66412547..ef7457f79 100644 opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1250000>; -- -2.27.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-pinctrl-spi2.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-pinctrl-spi2.patch index f34e8fa8e..cd6488675 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-pinctrl-spi2.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-pinctrl-spi2.patch @@ -1,7 +1,7 @@ -From 062488e4b8fd552c01e1104b3bc91a6f7ffe6c41 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Thu, 19 Oct 2017 21:24:47 +0200 -Subject: [PATCH 10/28] RK3288: DTSI: rk3288.dtsi: Add missing SPI2 pinctrl +Subject: RK3288: DTSI: rk3288.dtsi: Add missing SPI2 pinctrl The spi2_cs1 pin reference is missing in the spi2 first pin control definition. @@ -14,10 +14,10 @@ Signed-off-by: Myy Miouyouyou 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 5b789528..9ed532cc 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -334,7 +334,7 @@ +@@ -317,7 +317,7 @@ spi2: spi@ff130000 { dma-names = "tx", "rx"; interrupts = ; pinctrl-names = "default"; @@ -27,5 +27,5 @@ index 5b789528..9ed532cc 100644 #address-cells = <1>; #size-cells = <0>; -- -2.11.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch index c9ae49db3..f9d63e97e 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-rk3288-thermal-rearrange-zones.patch @@ -1,8 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tonymac32 +Date: Mon, 18 Sep 2017 15:04:14 +0000 +Subject: [ARCHEOLOGY] Add files via upload + +> X-Git-Archeology: - Revision 3d96c26b0f4d6f94f1be3b42c1599f74a0f93465: https://github.com/armbian/build/commit/3d96c26b0f4d6f94f1be3b42c1599f74a0f93465 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 15:04:14 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: Add files via upload +> X-Git-Archeology: +> X-Git-Archeology: - Revision 97d06e86c19d3d7d73c0a978fbad7d022b915922: https://github.com/armbian/build/commit/97d06e86c19d3d7d73c0a978fbad7d022b915922 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 15:05:37 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: RK3288 get cpu to thermal_zone0 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7ee8ff8e3bd040e4cc02596327b01c5f89dc1027: https://github.com/armbian/build/commit/7ee8ff8e3bd040e4cc02596327b01c5f89dc1027 +> X-Git-Archeology: Date: Mon, 18 Sep 2017 18:09:24 +0000 +> X-Git-Archeology: From: Tonymac32 +> X-Git-Archeology: Subject: rk3288 dtsi thermal zone adjustment +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0d2da12129218170ac244cc8d6fc1b94e6f49089: https://github.com/armbian/build/commit/0d2da12129218170ac244cc8d6fc1b94e6f49089 +> X-Git-Archeology: Date: Sun, 17 Dec 2017 20:33:45 -0500 +> X-Git-Archeology: From: tonymac32 +> X-Git-Archeology: Subject: Re-fix RK3288 Next Thermal Zones +> X-Git-Archeology: +> X-Git-Archeology: - Revision f831a2a014d9305e272fc7541fa7d85f32c7dbab: https://github.com/armbian/build/commit/f831a2a014d9305e272fc7541fa7d85f32c7dbab +> X-Git-Archeology: Date: Mon, 19 Feb 2018 00:30:58 -0500 +> X-Git-Archeology: From: tonymac32 +> X-Git-Archeology: Subject: Rockchip Dev fixup. Boots. +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 3b3d85e25c2ecde30df7b5274fc6f1b9c0299ea2: https://github.com/armbian/build/commit/3b3d85e25c2ecde30df7b5274fc6f1b9c0299ea2 +> X-Git-Archeology: Date: Sat, 22 May 2021 17:08:44 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Upgrade EDGE to 5.12.y (#2825) +> X-Git-Archeology: +> X-Git-Archeology: - Revision e7377248b3cae186e24e2be781cd3365b43246f0: https://github.com/armbian/build/commit/e7377248b3cae186e24e2be781cd3365b43246f0 +> X-Git-Archeology: Date: Thu, 22 Jul 2021 00:15:54 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Second part of EDGE bumping to 5.13.y (#3045) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 06d5054cce5d269b3fe8a0e23918c0c31a91140c: https://github.com/armbian/build/commit/06d5054cce5d269b3fe8a0e23918c0c31a91140c +> X-Git-Archeology: Date: Sun, 24 Sep 2023 19:22:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 14 +++++----- + 1 file changed, 7 insertions(+), 7 deletions(-) + diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index bc3601a..37ae378 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi -@@ -467,13 +467,6 @@ +@@ -454,13 +454,6 @@ dmac_peri: dma-controller@ff250000 { }; thermal-zones { @@ -16,7 +110,7 @@ index bc3601a..37ae378 100644 cpu_thermal: cpu-thermal { polling-delay-passive = <100>; /* milliseconds */ polling-delay = <5000>; /* milliseconds */ -@@ -539,6 +532,13 @@ +@@ -532,6 +525,13 @@ map0 { }; }; }; @@ -30,3 +124,6 @@ index bc3601a..37ae378 100644 }; tsadc: tsadc@ff280000 { +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch index e56921406..8dc221cff 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-rtl8723bs.patch @@ -1,17 +1,17 @@ -From 87313f95f809fc34f499c1ceff1b95cd4efa0f3f Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 22 Mar 2022 22:02:46 +0000 -Subject: [PATCH] rockchip: add tinkerboard bluetooth +Subject: rockchip: add tinkerboard bluetooth --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 11 +++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index ff2c6de3216..23acfdecee7 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -510,6 +510,17 @@ &tsadc { +@@ -491,6 +491,17 @@ &tsadc { &uart0 { status = "okay"; @@ -30,5 +30,5 @@ index ff2c6de3216..23acfdecee7 100644 &uart1 { -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-uart-pins.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-uart-pins.patch index 50da0ecae..99e9fe274 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-uart-pins.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-bt-uart-pins.patch @@ -1,7 +1,7 @@ -From 2c2e60256f2cbb2fce50a6317f85b1500efd1a6c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 22:03:26 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Setup the Bluetooth UART pins +Subject: ARM: DTS: rk3288-tinker: Setup the Bluetooth UART pins The most essential being the RTS pin, which is clearly needed to upload the initial configuration into the Realtek Bluetooth @@ -44,12 +44,12 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index d4df13bed..b92e59c1e 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -73,3 +73,9 @@ - status = "okay"; - supports-sdio; +@@ -11,3 +11,9 @@ / { + model = "Rockchip RK3288 Asus Tinker Board"; + compatible = "asus,rk3288-tinker", "rockchip,rk3288"; }; + +&uart0 { @@ -58,5 +58,5 @@ index d4df13bed..b92e59c1e 100644 +}; + -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-hevc-rga.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-hevc-rga.patch index a5175c9e5..1c18b53b6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-hevc-rga.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-hevc-rga.patch @@ -1,18 +1,17 @@ -From 0bcc81848ec1fb34fee9d3c7eb1550495cc8efc9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 18 Sep 2021 12:31:19 +0000 -Subject: [PATCH 1/2] rockchip: enable hevc, hevc_mmu and rga nodes for - tinkerboard (both) +Subject: rockchip: enable hevc, hevc_mmu and rga nodes for tinkerboard (both) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 12 ++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 12 ++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index aa36aedf9..ff2c6de32 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -150,6 +150,14 @@ &hdmi { +@@ -148,6 +148,14 @@ &hdmi { status = "okay"; }; @@ -27,7 +26,7 @@ index aa36aedf9..ff2c6de32 100644 &i2c0 { clock-frequency = <400000>; status = "okay"; -@@ -449,6 +457,10 @@ &pwm0 { +@@ -447,6 +455,10 @@ &pwm0 { status = "okay"; }; @@ -39,5 +38,5 @@ index aa36aedf9..ff2c6de32 100644 vref-supply = <&vcc18_ldo1>; status = "okay"; -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdio-wifi.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdio-wifi.patch index 85974972b..c8e2314fa 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdio-wifi.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdio-wifi.patch @@ -1,7 +1,7 @@ -From d5d5c53173c484a13cda62a537cbf75a5df4b0e4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 21:58:56 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Enabling SDIO and Wifi +Subject: ARM: DTS: rk3288-tinker: Enabling SDIO and Wifi Adding the appropriate nodes in order to exploit the WiFi capabilities of the board. @@ -15,14 +15,14 @@ Split if necessary. Signed-off-by: Miouyouyou (Myy) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 62 +++++++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 62 ++++++++++ 1 file changed, 62 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index 1e43527aa..d4df13bed 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -6,8 +6,70 @@ +@@ -6,10 +6,72 @@ /dts-v1/; #include "rk3288-tinker.dtsi" @@ -93,6 +93,8 @@ index 1e43527aa..d4df13bed 100644 + status = "okay"; + supports-sdio; }; + + &uart0 { -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdmmc-properties.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdmmc-properties.patch index 5486d6018..c55153298 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdmmc-properties.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-sdmmc-properties.patch @@ -1,7 +1,7 @@ -From 487db7cefc9861fdaf30579c378a98f0360690ae Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 20:27:14 +0100 -Subject: [PATCH] ARM: DTSI: rk3288-tinker: Defining SDMMC properties +Subject: ARM: DTSI: rk3288-tinker: Defining SDMMC properties I never knew if these properties were required to fix the dreaded reboot issue... @@ -12,10 +12,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -index dd1090728..8edd6f681 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi -@@ -436,7 +436,12 @@ +@@ -472,7 +472,12 @@ &sdmmc { disable-wp; /* wp not hooked up */ pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; @@ -29,5 +29,5 @@ index dd1090728..8edd6f681 100644 vqmmc-supply = <&vccio_sd>; }; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-spi-interface.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-spi-interface.patch index db2b09b15..4592a28db 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-spi-interface.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-tinkerboard-spi-interface.patch @@ -1,7 +1,7 @@ -From b24b8f83e150811ad54ee2a4843e44cd1421fafa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Mon, 5 Nov 2018 22:15:14 +0100 -Subject: [PATCH] ARM: DTS: rk3288-tinker: Defining the SPI interface +Subject: ARM: DTS: rk3288-tinker: Defining the SPI interface Taken from, and tested by @TonyMac32 . @@ -12,14 +12,14 @@ Therefore that *might* break, along with a few other patches. Signed-off-by: Miouyouyou (Myy) --- - arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 19 +++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-tinker.dts | 19 ++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -index 96d05fc6b..17bfea298 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dts -@@ -99,6 +99,25 @@ +@@ -74,6 +74,25 @@ &sdio0 { supports-sdio; }; @@ -46,5 +46,5 @@ index 96d05fc6b..17bfea298 100644 pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-veyron-flag-cache-flush.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-veyron-flag-cache-flush.patch index 89cb36c0a..ae50fbc2a 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-veyron-flag-cache-flush.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/dts-veyron-flag-cache-flush.patch @@ -1,8 +1,7 @@ -From 9177b30ab083dbda2bede3b3d61ef71ad4b1ffe0 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Miouyouyou (Myy)" Date: Thu, 1 Nov 2018 21:31:26 +0100 -Subject: [PATCH 2/2] arm: dts: veyron: Added a flag to disable cache flush - during reset +Subject: arm: dts: veyron: Added a flag to disable cache flush during reset Flushing the MMC cache of ASUS Chromebooks during initialization or "recovery" generates 10 minutes hangup, according to @SolidHal. @@ -16,10 +15,10 @@ Signed-off-by: Miouyouyou (Myy) 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi -index 2075120cf..fa4951fd7 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi -@@ -123,6 +123,7 @@ +@@ -157,6 +157,7 @@ &emmc { mmc-hs200-1_8v; mmc-pwrseq = <&emmc_pwrseq>; non-removable; @@ -28,5 +27,5 @@ index 2075120cf..fa4951fd7 100644 pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; -- -2.16.4 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-overlay-configfs.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-overlay-configfs.patch index 0aa88542f..b52ecf180 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-overlay-configfs.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-overlay-configfs.patch @@ -1,3 +1,148 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Ayotte +Date: Wed, 20 Jul 2016 10:56:30 -0400 +Subject: [ARCHEOLOGY] Add ConfigFS for overlays support in v4.6.x + +> X-Git-Archeology: - Revision 7eb8428bb65aedbd9ef506d942a0a7420c8becd6: https://github.com/armbian/build/commit/7eb8428bb65aedbd9ef506d942a0a7420c8becd6 +> X-Git-Archeology: Date: Wed, 20 Jul 2016 10:56:30 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: Add ConfigFS for overlays support in v4.6.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision 12c0a8a81224224d3fd9b487bf2e178fcb0cb9bd: https://github.com/armbian/build/commit/12c0a8a81224224d3fd9b487bf2e178fcb0cb9bd +> X-Git-Archeology: Date: Wed, 20 Jul 2016 11:19:44 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: move the add_configfs_overlay_for_v4.6.x.patch into sun8i-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 536c9d795d9d5fe491795b4fff6bd1676b229688: https://github.com/armbian/build/commit/536c9d795d9d5fe491795b4fff6bd1676b229688 +> X-Git-Archeology: Date: Fri, 22 Jul 2016 17:24:12 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: fix Makefile in add_configfs_overlay_for_v4.6.x.patch +> X-Git-Archeology: +> X-Git-Archeology: - Revision 023b2e10a58d5090d6c1a6e1e34fdf2348900e0a: https://github.com/armbian/build/commit/023b2e10a58d5090d6c1a6e1e34fdf2348900e0a +> X-Git-Archeology: Date: Sun, 24 Jul 2016 16:50:16 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: remove debugging message +> X-Git-Archeology: +> X-Git-Archeology: - Revision a659f1769e5a08e780db9cb7a8aa35a49e90c917: https://github.com/armbian/build/commit/a659f1769e5a08e780db9cb7a8aa35a49e90c917 +> X-Git-Archeology: Date: Fri, 12 Aug 2016 15:13:23 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: add modified ConfigFS patches for kernel 4.8.x in sunxi-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2def4ca6d90a8bba0df71a395ea08d9811169c24: https://github.com/armbian/build/commit/2def4ca6d90a8bba0df71a395ea08d9811169c24 +> X-Git-Archeology: Date: Mon, 09 Jan 2017 10:54:22 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: remove useless part of the patch for 4.10.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision 43f9fe3debf8061be55dc51d0069973a61c707d4: https://github.com/armbian/build/commit/43f9fe3debf8061be55dc51d0069973a61c707d4 +> X-Git-Archeology: Date: Mon, 09 Jan 2017 10:55:14 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: rename patch for 4.10.x +> X-Git-Archeology: +> X-Git-Archeology: - Revision b0fcb64aaca589359338a500e7bc07eb7ca1cb71: https://github.com/armbian/build/commit/b0fcb64aaca589359338a500e7bc07eb7ca1cb71 +> X-Git-Archeology: Date: Thu, 07 Dec 2017 07:09:10 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Temporally disabling broken patches on sunxi DEV branch +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2c08ec8f5a210de35f9482f482ac01ea15381792: https://github.com/armbian/build/commit/2c08ec8f5a210de35f9482f482ac01ea15381792 +> X-Git-Archeology: Date: Thu, 24 May 2018 13:32:29 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Merge sunxi family into stable +> X-Git-Archeology: +> X-Git-Archeology: - Revision 8bc9d032a372ebd1b8f8126e439658a9879789d4: https://github.com/armbian/build/commit/8bc9d032a372ebd1b8f8126e439658a9879789d4 +> X-Git-Archeology: Date: Wed, 27 Jun 2018 11:24:34 -0400 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: fix pantoniou configfs using pelwell patch for new OF API +> X-Git-Archeology: +> X-Git-Archeology: - Revision 1a12994e79b6ef173dc58efe4df8919cb6cc7781: https://github.com/armbian/build/commit/1a12994e79b6ef173dc58efe4df8919cb6cc7781 +> X-Git-Archeology: Date: Tue, 17 Jul 2018 15:53:30 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Moving sunxi-next to 4.17.y (#1049) +> X-Git-Archeology: +> X-Git-Archeology: - Revision a57ce78b37f8dd2eb94a3836f4a7f6969f2ffd72: https://github.com/armbian/build/commit/a57ce78b37f8dd2eb94a3836f4a7f6969f2ffd72 +> X-Git-Archeology: Date: Tue, 21 Aug 2018 10:41:10 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Reverting sunxi/sunxi64 NEXT to 4.14. (#1087) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0aec4b058834e16d12ddff68c90ecbed946b19a3: https://github.com/armbian/build/commit/0aec4b058834e16d12ddff68c90ecbed946b19a3 +> X-Git-Archeology: Date: Tue, 04 Dec 2018 15:10:36 -0500 +> X-Git-Archeology: From: Martin Ayotte +> X-Git-Archeology: Subject: add configfs for overlay on meson64-dev +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 2c439b921988b4f5210866ed484304d804cca60f: https://github.com/armbian/build/commit/2c439b921988b4f5210866ed484304d804cca60f +> X-Git-Archeology: Date: Mon, 30 Dec 2019 21:25:03 +0100 +> X-Git-Archeology: From: Piotr Szczepanik +> X-Git-Archeology: Subject: Overlay configfs support for rockchip64-current (#1699) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 20d17a7c9556b6eb39c2557b4a17fa0181f763fc: https://github.com/armbian/build/commit/20d17a7c9556b6eb39c2557b4a17fa0181f763fc +> X-Git-Archeology: Date: Fri, 19 Jun 2020 09:47:44 +0200 +> X-Git-Archeology: From: m][sko +> X-Git-Archeology: Subject: Switch meson to linux 5.7 (#2024) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7: https://github.com/armbian/build/commit/23604e8a0dcdf81ec6c28ccd4b2a64b90816d8e7 +> X-Git-Archeology: Date: Fri, 19 Jun 2020 17:27:27 +0200 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Introducing Rockchip RK322X SoC support (#2032) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 1e37959e5381a0a1d1eaf0629cdc19658f30df9a: https://github.com/armbian/build/commit/1e37959e5381a0a1d1eaf0629cdc19658f30df9a +> X-Git-Archeology: Date: Thu, 10 Feb 2022 20:32:58 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bumping sunxi/64, xu4, rockchip and mvebu64 to 5.16.y (#3453) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + Documentation/devicetree/configfs-overlays.txt | 31 + + drivers/of/Kconfig | 7 + + drivers/of/Makefile | 1 + + drivers/of/configfs.c | 290 ++++++++++ + 4 files changed, 329 insertions(+) + +diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt +new file mode 100644 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/configfs-overlays.txt @@ -0,0 +1,31 @@ @@ -33,10 +178,10 @@ +intended to be used by hardware managers in the kernel, while the copy interface +make sense for developers (since it avoids problems with namespaces). diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index 37c2ccbefecdc..d3fc81a40c0e7 100644 +index 111111111111..222222222222 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig -@@ -103,4 +103,11 @@ config OF_OVERLAY +@@ -126,4 +126,11 @@ config OF_OVERLAY_KUNIT_TEST config OF_NUMA bool @@ -49,20 +194,20 @@ index 37c2ccbefecdc..d3fc81a40c0e7 100644 + endif # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index 663a4af0cccd5..b00a95adf5199 100644 +index 111111111111..222222222222 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 - obj-y = base.o device.o platform.o property.o + obj-y = base.o cpu.o device.o module.o platform.o property.o obj-$(CONFIG_OF_KOBJ) += kobj.o +obj-$(CONFIG_OF_CONFIGFS) += configfs.o obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c new file mode 100644 -index 000000000..5dd509e8f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/of/configfs.c @@ -0,0 +1,290 @@ @@ -356,3 +501,6 @@ index 000000000..5dd509e8f + return ret; +} +late_initcall(of_cfs_init); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-restart-handler-for-act8846.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-restart-handler-for-act8846.patch index 13bace124..d8c8cc7d3 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-restart-handler-for-act8846.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-add-restart-handler-for-act8846.patch @@ -1,14 +1,14 @@ -From 7f2d6a02498ce3fa7771893072e81b31f9bd64b2 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Fri, 24 Mar 2023 17:15:16 +0000 -Subject: [PATCH] register act8846 restart handler for SIPC function +Subject: register act8846 restart handler for SIPC function --- - drivers/regulator/act8865-regulator.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) + drivers/regulator/act8865-regulator.c | 38 ++++++++++ + 1 file changed, 38 insertions(+) diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c -index b2a6ddc6f56d..1a88cfb1ba07 100644 +index 111111111111..222222222222 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -20,6 +20,7 @@ @@ -78,5 +78,5 @@ index b2a6ddc6f56d..1a88cfb1ba07 100644 /* Finally register devices */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch index bc3a6f296..e906cfb77 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-rk3288-reset-on-wake-quirk.patch @@ -1,14 +1,14 @@ -From c046bcccf1ca331cff3b89f09eed080a5407aa5a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 4 Dec 2024 14:32:40 +0100 -Subject: [PATCH] rockchip: fix rk3288 reset-on-wake quirk +Subject: rockchip: fix rk3288 reset-on-wake quirk --- drivers/usb/dwc2/params.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c -index 4d73fae80b12..0109055a9a8e 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -130,7 +130,6 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) @@ -20,5 +20,5 @@ index 4d73fae80b12..0109055a9a8e 100644 static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg) -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-peripheral.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-peripheral.patch index 9a5c933fd..38eb32d68 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-peripheral.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-peripheral.patch @@ -1,17 +1,17 @@ -From e477f1546f2739e9ea053d677f421e01a9babff4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 2 Mar 2024 21:56:44 +0100 -Subject: [PATCH] dwc2: add fixes for rk322x peripheral mode +Subject: dwc2: add fixes for rk322x peripheral mode --- - drivers/usb/dwc2/core.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) + drivers/usb/dwc2/core.c | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 5635e4d7ec88..0a3d387a497a 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -532,6 +532,9 @@ void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) +@@ -538,6 +538,9 @@ void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) gusbcfg |= set; dwc2_writel(hsotg, gusbcfg, GUSBCFG); @@ -22,5 +22,5 @@ index 5635e4d7ec88..0a3d387a497a 100644 return; } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-time.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-time.patch index f8517ac54..9c8232bf5 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-time.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-fix-wait-time.patch @@ -1,7 +1,7 @@ -From ee7c3ab6b5a4d284a04f110792508a7f8decd7f7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Wu Date: Tue, 6 Dec 2022 14:45:54 +0800 -Subject: [PATCH] usb: dwc2: fix waiting time for host only mode +Subject: usb: dwc2: fix waiting time for host only mode The current code uses 50ms sleep to wait for host only mode, the delay time is not enough for some Rockchip @@ -20,14 +20,14 @@ mode and increases the maximum waiting time to 200ms. Signed-off-by: William Wu Change-Id: Ie28299934aba09907ea08f5fd3b34bf2fb35822e --- - drivers/usb/dwc2/core.c | 14 ++++++++++++-- + drivers/usb/dwc2/core.c | 14 ++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 15911ac7582b4..cbd5f1142f35e 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -656,14 +656,24 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) +@@ -579,14 +579,24 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) */ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg) { @@ -54,3 +54,6 @@ index 15911ac7582b4..cbd5f1142f35e 100644 break; case USB_DR_MODE_PERIPHERAL: +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-nak-gadget.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-nak-gadget.patch index 1162a96d9..fa57b5c67 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-nak-gadget.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-dwc2-nak-gadget.patch @@ -1,8 +1,7 @@ -From 15b317ff84dc09faa47995b1d973d96a6172fa4c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Wu Date: Thu, 15 Dec 2022 14:19:28 +0800 -Subject: [PATCH] usb: dwc2: gadget: Disable nak interrupt when get first isoc - in token +Subject: usb: dwc2: gadget: Disable nak interrupt when get first isoc in token The dwc2 driver use the nak interrupt for the starting point of isoc-in transfer. The first nak interrupt for isoc-in means @@ -21,14 +20,14 @@ the nak interrupt when get first isoc in token if the feature Signed-off-by: William Wu Change-Id: I99c71a5e0d7903346fd8f71619b6736c3181c0ec --- - drivers/usb/dwc2/gadget.c | 37 +++++++++++++++++++++++++++++++++++-- + drivers/usb/dwc2/gadget.c | 37 +++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c -index e1dc4735a99c..0e185ef474ac 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c -@@ -1402,6 +1402,8 @@ static int dwc2_gadget_set_ep0_desc_chain(struct dwc2_hsotg *hsotg, +@@ -1399,6 +1399,8 @@ static int dwc2_gadget_set_ep0_desc_chain(struct dwc2_hsotg *hsotg, return 0; } @@ -37,7 +36,7 @@ index e1dc4735a99c..0e185ef474ac 100644 static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { -@@ -1518,6 +1520,20 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, +@@ -1519,6 +1521,20 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, if (hs_ep->target_frame != TARGET_FRAME_INITIAL) dwc2_hsotg_start_req(hs, hs_ep, hs_req, false); @@ -58,7 +57,7 @@ index e1dc4735a99c..0e185ef474ac 100644 } return 0; } -@@ -2989,8 +3005,25 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) +@@ -2991,8 +3007,25 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) hs_ep->target_frame = hsotg->frame_number; if (hs_ep->interval > 1) { @@ -86,3 +85,6 @@ index e1dc4735a99c..0e185ef474ac 100644 if (hs_ep->target_frame & 0x1) ctrl |= DXEPCTL_SETODDFR; else +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-reboot-from-kwiboo.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-reboot-from-kwiboo.patch index 088b7ebe8..d24688842 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-reboot-from-kwiboo.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-reboot-from-kwiboo.patch @@ -1,10 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas McKahan +Date: Sun, 17 Feb 2019 23:28:02 -0500 +Subject: [ARCHEOLOGY] [ rockchip-dev ] Add simpler reboot code + +> X-Git-Archeology: > recovered message: > As seen here: https://patchwork.kernel.org/patch/10817217/ +> X-Git-Archeology: > recovered message: > for testing in Dev. @paolosabatino please check TV box. +> X-Git-Archeology: - Revision 2c8ee5a69d023d22c9e3ac99e9fc45ab30751f22: https://github.com/armbian/build/commit/2c8ee5a69d023d22c9e3ac99e9fc45ab30751f22 +> X-Git-Archeology: Date: Sun, 17 Feb 2019 23:28:02 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ rockchip-dev ] Add simpler reboot code +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/mmc/core/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index 5bd58b95d..48ebe081f 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c -@@ -1684,6 +1684,14 @@ void mmc_power_off(struct mmc_host *host) - if (host->ios.power_mode == MMC_POWER_OFF) - return; +@@ -1381,6 +1381,14 @@ void mmc_power_off(struct mmc_host *host) + */ + mmc_delay(host->ios.power_delay_ms); + mmc_set_initial_signal_voltage(host); + @@ -17,3 +78,6 @@ index 5bd58b95d..48ebe081f 100644 mmc_pwrseq_power_off(host); host->ios.clock = 0; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-vdpu38x-32bit-archs.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-vdpu38x-32bit-archs.patch index 53004d465..f917a3958 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-vdpu38x-32bit-archs.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-fix-vdpu38x-32bit-archs.patch @@ -1,7 +1,7 @@ -From 37b944b341c637749f1318366941f6e0e718a1cf Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 16 Sep 2025 14:21:22 +0200 -Subject: [PATCH] fix vdpu381/383 compilation on 32 bit archs +Subject: fix vdpu381/383 compilation on 32 bit archs --- drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c | 2 +- @@ -10,7 +10,7 @@ Subject: [PATCH] fix vdpu381/383 compilation on 32 bit archs 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c -index e65a56bc9c63..95e6a785eac2 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c @@ -439,7 +439,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) @@ -23,7 +23,7 @@ index e65a56bc9c63..95e6a785eac2 100644 watchdog_time = 2000; schedule_delayed_work(&rkvdec->watchdog_work, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c -index bb2c62d9c3d4..ffa0b35db8c0 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c @@ -550,7 +550,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) @@ -36,7 +36,7 @@ index bb2c62d9c3d4..ffa0b35db8c0 100644 watchdog_time = 2000; schedule_delayed_work(&rkvdec->watchdog_work, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c -index 7d53c28e954e..0297ff89fe5b 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c @@ -656,7 +656,7 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) @@ -49,5 +49,5 @@ index 7d53c28e954e..0297ff89fe5b 100644 watchdog_time = 2000; schedule_delayed_work(&rkvdec->watchdog_work, -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-increase-spdif-dma-burst.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-increase-spdif-dma-burst.patch index 9d3a91b4d..eb32f431f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-increase-spdif-dma-burst.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-increase-spdif-dma-burst.patch @@ -1,14 +1,14 @@ -From 379651eb82cf5966a40a5b931afc2fa91c6a311d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 12 Jan 2025 12:39:03 +0100 -Subject: [PATCH 2/2] rockchip: increase SPDIF max burst value to maximum +Subject: rockchip: increase SPDIF max burst value to maximum --- sound/soc/rockchip/rockchip_spdif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c -index d87c0e4f6f91..7a2cfecf6a94 100644 +index 111111111111..222222222222 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -329,7 +329,7 @@ static int rk_spdif_probe(struct platform_device *pdev) @@ -21,5 +21,5 @@ index d87c0e4f6f91..7a2cfecf6a94 100644 spdif->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, spdif); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-linux-export-mm-trace-rss-stats.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-linux-export-mm-trace-rss-stats.patch index 45c975a46..ea4c37f75 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-linux-export-mm-trace-rss-stats.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-linux-export-mm-trace-rss-stats.patch @@ -1,24 +1,24 @@ -From 6408e6688b18e5c712c711110d196a4e95f3f870 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 16:37:28 +0000 -Subject: [PATCH 2/4] 01-linux-1000-export-mm_trace_rss_stat +Subject: 01-linux-1000-export-mm_trace_rss_stat --- mm/memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/memory.c b/mm/memory.c -index 25fc46e87..7ef0adaa5 100644 +index 111111111111..222222222222 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -171,6 +171,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member, long count) +@@ -180,6 +180,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member) { - trace_rss_stat(mm, member, count); + trace_rss_stat(mm, member); } +EXPORT_SYMBOL(mm_trace_rss_stat); - #if defined(SPLIT_RSS_COUNTING) - + /* + * Note: this doesn't free the actual pages themselves. That -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-01-fix-periodic-transfers.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-01-fix-periodic-transfers.patch index 844286d43..3d6828ac6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-01-fix-periodic-transfers.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-01-fix-periodic-transfers.patch @@ -1,14 +1,14 @@ -From fc0d09bf651fcab0998da4d187a91f64df419188 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 12 Jan 2025 12:36:50 +0100 -Subject: [PATCH 1/2] pl330: fix dma engine periodic transfers +Subject: pl330: fix dma engine periodic transfers --- - drivers/dma/pl330.c | 277 +++++++++++++++++++++++++++++--------------- + drivers/dma/pl330.c | 277 +++++++--- 1 file changed, 186 insertions(+), 91 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 82a9fe88ad54..ef197c4cfed4 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -239,6 +239,7 @@ enum pl330_byteswap { @@ -417,5 +417,5 @@ index 82a9fe88ad54..ef197c4cfed4 100644 return &desc->txd; } -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch index 54f0dd913..4b9f8f78b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-02-add-support-for-interleaved-transfers.patch @@ -1,16 +1,16 @@ -From e691c5c3feede95b4e159344aaea070fc428c847 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 23 Jan 2025 20:23:50 +0100 -Subject: [PATCH 1/2] rockchip/64: pl330 - add support for interleaved - transfers +Subject: rockchip/64: pl330 - add support for interleaved transfers original source: https://patchwork.kernel.org/project/linux-rockchip/cover/1712150304-60832-1-git-send-email-sugar.zhang@rock-chips.com/ --- - drivers/dma/pl330.c | 168 ++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 162 insertions(+), 6 deletions(-) + drivers/dma/pl330.c | 168 +++++++++- + include/linux/dmaengine.h | 1 + + 2 files changed, 163 insertions(+), 6 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index ef197c4cfed4..b49a3a6c4686 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -543,6 +543,8 @@ struct dma_pl330_desc { @@ -245,7 +245,7 @@ index ef197c4cfed4..b49a3a6c4686 100644 pd->device_prep_slave_sg = pl330_prep_slave_sg; pd->device_config = pl330_config; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index b137fdb56093..63624c5836cf 100644 +index 111111111111..222222222222 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -156,6 +156,7 @@ struct dma_interleaved_template { @@ -257,5 +257,5 @@ index b137fdb56093..63624c5836cf 100644 struct data_chunk sgl[]; }; -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch index 15b348888..070fc2fb9 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-04-bigger-mcode-buffer.patch @@ -1,7 +1,7 @@ -From f695d6bfdd099ec6f59a73aa792b97df80c72d54 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 26 Jan 2025 14:49:18 +0100 -Subject: [PATCH] increase pl330 microcode buffer size +Subject: increase pl330 microcode buffer size suggestion comes from the scatter/gather functionality as proposed here: https://github.com/radxa/kernel/commit/ec0b65dbc59793426b6dc7af06ab6675f4a24940 @@ -10,10 +10,10 @@ proposed here: https://github.com/radxa/kernel/commit/ec0b65dbc59793426b6dc7af06 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 82a9fe88ad54..eb322c7ae5de 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c -@@ -246,7 +246,7 @@ enum pl330_byteswap { +@@ -247,7 +247,7 @@ enum pl330_byteswap { * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req * should be enough for P<->M and M<->M respectively. */ @@ -23,5 +23,5 @@ index 82a9fe88ad54..eb322c7ae5de 100644 /* Use this _only_ to wait on transient states */ #define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch index c9a44f75f..2b79e7bca 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-05-fix-unbalanced-power-down.patch @@ -1,7 +1,7 @@ -From 05cc2b4fba887e3da543952311b009bacc87cee8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Sat, 26 Mar 2022 18:01:21 +0800 -Subject: [PATCH] dmaengine: pl330: Fix unbalanced runtime PM +Subject: dmaengine: pl330: Fix unbalanced runtime PM This driver use runtime PM autosuspend mechanism to manager clk. @@ -64,10 +64,10 @@ Signed-off-by: Sugar Zhang 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 6dca548f4dab1..f87729ace4f5b 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c -@@ -2086,7 +2086,7 @@ static void pl330_tasklet(struct tasklet_struct *t) +@@ -2274,7 +2274,7 @@ static void pl330_tasklet(struct tasklet_struct *t) spin_lock(&pch->thread->dmac->lock); _stop(pch->thread); spin_unlock(&pch->thread->dmac->lock); @@ -76,3 +76,6 @@ index 6dca548f4dab1..f87729ace4f5b 100644 pch->active = false; } else { /* Make sure the PL330 Channel thread is active */ +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-06-fix-buffer-underruns.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-06-fix-buffer-underruns.patch index 1215a00c9..3755bf0a7 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-06-fix-buffer-underruns.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-pl330-06-fix-buffer-underruns.patch @@ -1,7 +1,7 @@ -From 4acf270a6310f5e2dbadac1d5f21d8e7477fade6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 16 Feb 2025 11:15:55 +0100 -Subject: [PATCH] pl330: fix buffer underrun with cyclic dma +Subject: pl330: fix buffer underrun with cyclic dma userspace applications (notably, pulseaudio) were suffering frequent buffer underruns when cyclic DMA @@ -10,11 +10,11 @@ the buffer underruns avoiding to juggle with the descriptor state, keeping it in BUSY state as long as it is actual transfer is progressing. --- - drivers/dma/pl330.c | 24 ++++++++++++------------ + drivers/dma/pl330.c | 24 +++++----- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 208e2a089a4d..6dac00995765 100644 +index 111111111111..222222222222 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1737,11 +1737,11 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err) @@ -34,7 +34,7 @@ index 208e2a089a4d..6dac00995765 100644 tasklet_schedule(&pch->task); } -@@ -2256,23 +2256,23 @@ static void pl330_tasklet(struct tasklet_struct *t) +@@ -2248,23 +2248,23 @@ static void pl330_tasklet(struct tasklet_struct *t) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) { @@ -66,5 +66,5 @@ index 208e2a089a4d..6dac00995765 100644 /* Try to submit a req imm. next to the last completed cookie */ -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rk322x-gpio-ir-driver.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rk322x-gpio-ir-driver.patch index 46fafb06c..0e6c181c9 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rk322x-gpio-ir-driver.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rk322x-gpio-ir-driver.patch @@ -1,20 +1,19 @@ -From 13498feb91614d59ebece61d0c278e31529bb8c8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 10 Oct 2023 21:54:51 +0200 -Subject: [PATCH] rockchip gpio IR driver +Subject: rockchip gpio IR driver --- - drivers/media/rc/Kconfig | 11 + + drivers/media/rc/Kconfig | 10 + drivers/media/rc/Makefile | 1 + - drivers/media/rc/rockchip-ir.c | 723 +++++++++++++++++++++++++++++++++ - 3 files changed, 735 insertions(+) - create mode 100644 drivers/media/rc/rockchip-ir.c + drivers/media/rc/rockchip-ir.c | 733 ++++++++++ + 3 files changed, 744 insertions(+) diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 2afe67ffa285..0fd671f5873c 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig -@@ -338,6 +338,16 @@ config IR_REDRAT3 +@@ -340,6 +340,16 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. @@ -32,7 +31,7 @@ index 2afe67ffa285..0fd671f5873c 100644 tristate "Homebrew Serial Port Receiver" depends on HAS_IOPORT diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index 2bca6f7f07bc..2ec037f8b939 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_IR_MTK) += mtk-cir.o @@ -45,7 +44,7 @@ index 2bca6f7f07bc..2ec037f8b939 100644 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o diff --git a/drivers/media/rc/rockchip-ir.c b/drivers/media/rc/rockchip-ir.c new file mode 100644 -index 000000000000..43ade8c4adce +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/rockchip-ir.c @@ -0,0 +1,733 @@ @@ -782,5 +781,6 @@ index 000000000000..43ade8c4adce + +MODULE_DESCRIPTION("Rockchip IR Receiver driver"); +MODULE_LICENSE("GPL v2"); - +-- +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rockchip-various-fixes.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rockchip-various-fixes.patch index 4eaa12cec..745bcb69f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rockchip-various-fixes.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/general-rockchip-various-fixes.patch @@ -1,21 +1,20 @@ -From 92a42b2df843c0f6c2937dc6bdbfe72332c9e557 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 9 Sep 2021 16:46:33 +0000 -Subject: [PATCH 3/4] 01-linux-1000-rockchip-wip +Subject: 01-linux-1000-rockchip-wip --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 101 +++++++++++++++++- - arch/arm/boot/dts/rockchip/rk3xxx.dtsi | 2 + - drivers/clk/rockchip/clk-rk3228.c | 61 ++++------- - drivers/net/ethernet/arc/emac.h | 14 +++ - drivers/net/ethernet/arc/emac_main.c | 81 ++++++++++++-- - drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++++- - drivers/pmdomain/rockchip/pm-domains.c | 23 ++++ - drivers/usb/dwc2/core.c | 2 +- - 8 files changed, 266 insertions(+), 56 deletions(-) + arch/arm/boot/dts/rockchip/rk322x.dtsi | 85 +++++++++- + arch/arm/boot/dts/rockchip/rk3xxx.dtsi | 2 + + drivers/clk/rockchip/clk-rk3228.c | 61 +++---- + drivers/net/ethernet/arc/emac.h | 14 ++ + drivers/net/ethernet/arc/emac_main.c | 61 +++++++ + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++- + drivers/pmdomain/rockchip/pm-domains.c | 23 +++ + 7 files changed, 239 insertions(+), 45 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 831561fc1814..24e963b01d87 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -19,6 +19,7 @@ aliases { @@ -26,7 +25,7 @@ index 831561fc1814..24e963b01d87 100644 serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; -@@ -132,6 +149,17 @@ display_subsystem: display-subsystem { +@@ -135,6 +136,17 @@ display_subsystem: display-subsystem { ports = <&vop_out>; }; @@ -44,7 +43,7 @@ index 831561fc1814..24e963b01d87 100644 i2s1: i2s1@100b0000 { compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100b0000 0x4000>; -@@ -142,6 +170,7 @@ i2s1: i2s1@100b0000 { +@@ -145,6 +157,7 @@ i2s1: i2s1@100b0000 { dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&i2s1_bus>; @@ -52,7 +51,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -153,6 +182,7 @@ i2s0: i2s0@100c0000 { +@@ -165,6 +178,7 @@ i2s0: i2s0@100c0000 { clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; dmas = <&pdma 11>, <&pdma 12>; dma-names = "tx", "rx"; @@ -60,7 +59,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -166,6 +196,7 @@ spdif: spdif@100d0000 { +@@ -178,6 +192,7 @@ spdif: spdif@100d0000 { dma-names = "tx"; pinctrl-names = "default"; pinctrl-0 = <&spdif_tx>; @@ -68,7 +67,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -337,7 +368,7 @@ uart2: serial@11030000 { +@@ -349,7 +364,7 @@ uart2: serial@11030000 { clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; @@ -77,7 +76,7 @@ index 831561fc1814..24e963b01d87 100644 reg-shift = <2>; reg-io-width = <4>; status = "disabled"; -@@ -358,6 +389,10 @@ efuse_id: id@7 { +@@ -370,6 +385,10 @@ efuse_id: id@7 { cpu_leakage: cpu_leakage@17 { reg = <0x17 0x1>; }; @@ -88,7 +87,7 @@ index 831561fc1814..24e963b01d87 100644 }; i2c0: i2c@11050000 { -@@ -554,6 +589,11 @@ map1 { +@@ -568,6 +587,11 @@ map1 { <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; @@ -100,7 +99,7 @@ index 831561fc1814..24e963b01d87 100644 }; }; }; -@@ -584,6 +624,8 @@ hdmi_phy: hdmi-phy@12030000 { +@@ -598,6 +622,8 @@ hdmi_phy: hdmi-phy@12030000 { clock-names = "sysclk", "refoclk", "refpclk"; #clock-cells = <0>; clock-output-names = "hdmiphy_phy"; @@ -109,7 +108,7 @@ index 831561fc1814..24e963b01d87 100644 #phy-cells = <0>; status = "disabled"; }; -@@ -607,7 +649,27 @@ gpu: gpu@20000000 { +@@ -621,7 +647,27 @@ gpu: gpu@20000000 { clock-names = "bus", "core"; power-domains = <&power RK3228_PD_GPU>; resets = <&cru SRST_GPU_A>; @@ -138,7 +137,7 @@ index 831561fc1814..24e963b01d87 100644 }; vpu: video-codec@20020000 { -@@ -727,6 +789,7 @@ hdmi: hdmi@200a0000 { +@@ -752,6 +798,7 @@ hdmi: hdmi@200a0000 { phys = <&hdmi_phy>; phy-names = "hdmi"; rockchip,grf = <&grf>; @@ -146,7 +145,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; ports { -@@ -748,9 +811,13 @@ sdmmc: mmc@30000000 { +@@ -779,9 +826,13 @@ sdmmc: mmc@30000000 { clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; @@ -161,7 +160,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -760,10 +827,14 @@ sdio: mmc@30010000 { +@@ -791,10 +842,14 @@ sdio: mmc@30010000 { interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; @@ -176,7 +175,7 @@ index 831561fc1814..24e963b01d87 100644 status = "disabled"; }; -@@ -771,14 +842,13 @@ emmc: mmc@30020000 { +@@ -802,14 +857,13 @@ emmc: mmc@30020000 { compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x30020000 0x4000>; interrupts = ; @@ -192,7 +191,7 @@ index 831561fc1814..24e963b01d87 100644 pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; resets = <&cru SRST_EMMC>; -@@ -1029,6 +1099,10 @@ sdmmc_bus4: sdmmc-bus4 { +@@ -1076,6 +1130,10 @@ sdmmc_bus4: sdmmc-bus4 { <1 RK_PC4 1 &pcfg_pull_none_drv_12ma>, <1 RK_PC5 1 &pcfg_pull_none_drv_12ma>; }; @@ -203,7 +202,7 @@ index 831561fc1814..24e963b01d87 100644 }; sdio { -@@ -1261,13 +1335,30 @@ uart1_xfer: uart1-xfer { +@@ -1367,13 +1425,30 @@ uart1_xfer: uart1-xfer { <1 RK_PB2 1 &pcfg_pull_none>; }; @@ -235,10 +234,10 @@ index 831561fc1814..24e963b01d87 100644 uart2 { diff --git a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi -index 616a828e0..f233b7a77 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3xxx.dtsi -@@ -64,6 +64,8 @@ L2: cache-controller@10138000 { +@@ -68,6 +68,8 @@ L2: cache-controller@10138000 { reg = <0x10138000 0x1000>; cache-unified; cache-level = <2>; @@ -248,10 +247,10 @@ index 616a828e0..f233b7a77 100644 scu@1013c000 { diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index aca1a483a..7250adc64 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -135,24 +135,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { +@@ -131,24 +131,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; @@ -278,7 +277,7 @@ index aca1a483a..7250adc64 100644 PNAME(mux_dclk_vop_p) = { "hdmiphy", "sclk_vop_pre" }; PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; -@@ -221,27 +219,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -217,27 +215,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), /* PD_DDR */ @@ -313,7 +312,7 @@ index aca1a483a..7250adc64 100644 COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 1, GFLAGS), -@@ -258,14 +252,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -254,14 +248,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_MISC_CON, 15, 1, MFLAGS), /* PD_BUS */ @@ -330,7 +329,7 @@ index aca1a483a..7250adc64 100644 GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, -@@ -338,14 +327,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -334,14 +323,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(3), 8, GFLAGS), /* PD_PERI */ @@ -347,7 +346,7 @@ index aca1a483a..7250adc64 100644 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK2928_CLKSEL_CON(10), 12, 3, DFLAGS, RK2928_CLKGATE_CON(5), 2, GFLAGS), -@@ -380,7 +364,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -376,7 +360,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(10), 12, GFLAGS), COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, @@ -356,7 +355,7 @@ index aca1a483a..7250adc64 100644 RK2928_CLKGATE_CON(2), 15, GFLAGS), COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, -@@ -403,12 +387,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -397,12 +381,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ @@ -371,7 +370,7 @@ index aca1a483a..7250adc64 100644 DIV(DCLK_HDMI_PHY, "dclk_hdmiphy", "sclk_vop_src", 0, RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, -@@ -640,13 +621,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -634,13 +615,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), @@ -388,7 +387,7 @@ index aca1a483a..7250adc64 100644 }; static const char *const rk3228_critical_clocks[] __initconst = { -@@ -661,6 +642,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -655,6 +636,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { "aclk_vop_noc", "aclk_hdcp_noc", "hclk_vio_ahb_arbi", @@ -396,7 +395,7 @@ index aca1a483a..7250adc64 100644 "hclk_vio_noc", "hclk_vop_noc", "hclk_host0_arb", -@@ -678,10 +660,13 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -672,10 +654,13 @@ static const char *const rk3228_critical_clocks[] __initconst = { "pclk_ddrphy", "pclk_acodecphy", "pclk_phy_noc", @@ -411,7 +410,7 @@ index aca1a483a..7250adc64 100644 static void __init rk3228_clk_init(struct device_node *np) diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h -index d820ae03a..0ac87288b 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/arc/emac.h +++ b/drivers/net/ethernet/arc/emac.h @@ -91,6 +91,20 @@ struct arc_emac_bd { @@ -436,10 +435,10 @@ index d820ae03a..0ac87288b 100644 * struct buffer_state - Stores Rx/Tx buffer state. * @sk_buff: Pointer to socket buffer. diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c -index 67b8113a2..40332a976 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c -@@ -850,6 +850,62 @@ static const struct net_device_ops arc_emac_netdev_ops = { +@@ -855,6 +855,62 @@ static const struct net_device_ops arc_emac_netdev_ops = { #endif }; @@ -502,7 +501,7 @@ index 67b8113a2..40332a976 100644 int arc_emac_probe(struct net_device *ndev, int interface) { struct device *dev = ndev->dev.parent; -@@ -970,6 +1026,11 @@ int arc_emac_probe(struct net_device *ndev, int interface) +@@ -975,6 +1031,11 @@ int arc_emac_probe(struct net_device *ndev, int interface) goto out_clken; } @@ -515,10 +514,10 @@ index 67b8113a2..40332a976 100644 interface); if (!phydev) { diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -index 1889e78e1..6209f51b3 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -237,6 +237,9 @@ struct inno_hdmi_phy { +@@ -236,6 +236,9 @@ struct inno_hdmi_phy { struct clk *refoclk; struct clk *refpclk; @@ -528,7 +527,7 @@ index 1889e78e1..6209f51b3 100644 /* platform data */ const struct inno_hdmi_phy_drv_data *plat_data; int chip_version; -@@ -471,6 +474,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { +@@ -470,6 +473,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { static const struct post_pll_config post_pll_cfg_table[] = { {33750000, 1, 40, 8, 1}, {33750000, 1, 80, 8, 2}, @@ -536,7 +535,7 @@ index 1889e78e1..6209f51b3 100644 {74250000, 1, 40, 8, 1}, {74250000, 18, 80, 8, 2}, {148500000, 2, 40, 4, 3}, -@@ -621,8 +625,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) +@@ -620,8 +624,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) return -EINVAL; for (; cfg->tmdsclock != 0; cfg++) @@ -550,7 +549,7 @@ index 1889e78e1..6209f51b3 100644 break; for (; phy_cfg->tmdsclock != 0; phy_cfg++) -@@ -1033,6 +1040,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) +@@ -1032,6 +1039,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) { @@ -561,7 +560,7 @@ index 1889e78e1..6209f51b3 100644 /* * Use phy internal register control * rxsense/poweron/pllpd/pdataen signal. -@@ -1047,7 +1058,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) +@@ -1046,7 +1057,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL, RK3228_POST_PLL_CTRL_MANUAL); @@ -590,7 +589,7 @@ index 1889e78e1..6209f51b3 100644 return 0; } -@@ -1147,6 +1179,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) +@@ -1146,6 +1178,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) /* try to read the chip-version */ inno->chip_version = 1; @@ -599,12 +598,11 @@ index 1889e78e1..6209f51b3 100644 cell = nvmem_cell_get(inno->dev, "cpu-version"); if (IS_ERR(cell)) { if (PTR_ERR(cell) == -EPROBE_DEFER) - diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index 03bcf79a461f..200047473d59 100644 +index 111111111111..222222222222 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -95,6 +95,7 @@ struct rockchip_pm_domain { +@@ -97,6 +97,7 @@ struct rockchip_pm_domain { struct regmap **qos_regmap; u32 *qos_save_regs[MAX_QOS_REGS_NUM]; int num_clks; @@ -612,7 +610,7 @@ index 03bcf79a461f..200047473d59 100644 struct clk_bulk_data *clks; struct device_node *node; struct regulator *supply; -@@ -664,6 +665,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) +@@ -686,6 +687,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) struct rockchip_pm_domain *pd = to_rockchip_pd(domain); int ret; @@ -622,7 +620,7 @@ index 03bcf79a461f..200047473d59 100644 ret = rockchip_pd_regulator_enable(pd); if (ret) { dev_err(pd->pmu->dev, "Failed to enable supply: %d\n", ret); -@@ -682,6 +686,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) +@@ -704,6 +708,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) struct rockchip_pm_domain *pd = to_rockchip_pd(domain); int ret; @@ -632,7 +630,7 @@ index 03bcf79a461f..200047473d59 100644 ret = rockchip_pd_power(pd, false); if (ret) return ret; -@@ -770,6 +777,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, +@@ -792,6 +799,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, pd->pmu = pmu; pd->node = node; @@ -642,7 +640,7 @@ index 03bcf79a461f..200047473d59 100644 pd->num_clks = of_clk_get_parent_count(node); if (pd->num_clks > 0) { pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, -@@ -915,6 +925,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, +@@ -937,6 +947,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, struct device_node *parent) { struct generic_pm_domain *child_domain, *parent_domain; @@ -650,7 +648,7 @@ index 03bcf79a461f..200047473d59 100644 int error; for_each_child_of_node_scoped(parent, np) { -@@ -955,6 +966,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, +@@ -977,6 +988,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, parent_domain->name, child_domain->name); } @@ -668,7 +666,7 @@ index 03bcf79a461f..200047473d59 100644 + rockchip_pm_add_subdomain(pmu, np); } - + -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-rk322x-box.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-rk322x-box.patch index c451a3648..198f93ee1 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-rk322x-box.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-rk322x-box.patch @@ -1,17 +1,16 @@ -From f14539f8d08328ae5aad165a4deea25c7d6b09bf Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Mon, 25 Apr 2022 13:25:09 +0000 -Subject: [PATCH] add generic rk322x tv box remote controller keymap +Subject: add generic rk322x tv box remote controller keymap --- drivers/media/rc/keymaps/Makefile | 1 + - drivers/media/rc/keymaps/rc-rk322x-tvbox.c | 74 ++++++++++++++++++++++ + drivers/media/rc/keymaps/rc-rk322x-tvbox.c | 74 ++++++++++ include/media/rc-map.h | 1 + - 3 files changed, 77 insertions(+) - create mode 100644 drivers/media/rc/keymaps/rc-rk322x-tvbox.c + 3 files changed, 76 insertions(+) diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index d04572627cdd..a543bb3ef864 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_RC_MAP) += \ @@ -24,7 +23,7 @@ index d04572627cdd..a543bb3ef864 100644 rc-streamzap.o \ diff --git a/drivers/media/rc/keymaps/rc-rk322x-tvbox.c b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c new file mode 100644 -index 00000000000..91e24ee52ee +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c @@ -0,0 +1,74 @@ @@ -103,7 +102,7 @@ index 00000000000..91e24ee52ee +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Paolo Sabatino"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index d90e4611b066..14d6a50defed 100644 +index 111111111111..222222222222 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -313,6 +313,7 @@ struct rc_map *rc_map_get(const char *name); @@ -115,5 +114,5 @@ index d90e4611b066..14d6a50defed 100644 #define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly" #define RC_MAP_STREAMZAP "rc-streamzap" -- -2.30.2 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-xt-q8l-v10.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-xt-q8l-v10.patch index eb4faa632..b0cda7668 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-xt-q8l-v10.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/ir-keymap-xt-q8l-v10.patch @@ -10,10 +10,10 @@ Subject: add xt-q8l-v10 keymap and makefile 3 files changed, 78 insertions(+) diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index f513ff5caf4e..198ef8bc2614 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile -@@ -136,4 +136,5 @@ obj-$(CONFIG_RC_MAP) += \ +@@ -141,4 +141,5 @@ obj-$(CONFIG_RC_MAP) += \ rc-x96max.o \ rc-xbox-360.o \ rc-xbox-dvd.o \ @@ -21,7 +21,7 @@ index f513ff5caf4e..198ef8bc2614 100644 rc-zx-irdec.o diff --git a/drivers/media/rc/keymaps/rc-xt-q8l-v10.c b/drivers/media/rc/keymaps/rc-xt-q8l-v10.c new file mode 100644 -index 000000000000..19c7d9ec8325 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-xt-q8l-v10.c @@ -0,0 +1,76 @@ @@ -102,10 +102,10 @@ index 000000000000..19c7d9ec8325 +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Paolo Sabatino"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index 793b54342dff..ef7f3710eafe 100644 +index 111111111111..222222222222 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h -@@ -343,6 +343,7 @@ struct rc_map *rc_map_get(const char *name); +@@ -348,6 +348,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_X96MAX "rc-x96max" #define RC_MAP_XBOX_360 "rc-xbox-360" #define RC_MAP_XBOX_DVD "rc-xbox-dvd" diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/misc-tinkerboard-spi-interface.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/misc-tinkerboard-spi-interface.patch index 27b54fe96..0ad2f3d0b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/misc-tinkerboard-spi-interface.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/misc-tinkerboard-spi-interface.patch @@ -1,8 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 27 Apr 2023 21:31:27 +0200 +Subject: [ARCHEOLOGY] rockchip: bump edge kernel to 6.3 + +> X-Git-Archeology: - Revision da0ab48b7939235608c8fc042c61ae997681e865: https://github.com/armbian/build/commit/da0ab48b7939235608c8fc042c61ae997681e865 +> X-Git-Archeology: Date: Thu, 27 Apr 2023 21:31:27 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.3 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/spi/spidev.c | 2 ++ + 1 file changed, 2 insertions(+) + diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 58ae4304fdab..52cb8872ffa4 100644 +index 111111111111..222222222222 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c -@@ -716,6 +716,7 @@ static const struct spi_device_id spidev_spi_ids[] = { +@@ -718,6 +718,7 @@ static const struct spi_device_id spidev_spi_ids[] = { { .name = /* semtech */ "sx1301" }, { .name = /* silabs */ "em3581" }, { .name = /* silabs */ "si3210" }, @@ -10,7 +59,7 @@ index 58ae4304fdab..52cb8872ffa4 100644 {}, }; MODULE_DEVICE_TABLE(spi, spidev_spi_ids); -@@ -747,6 +748,7 @@ static const struct of_device_id spidev_dt_ids[] = { +@@ -751,6 +752,7 @@ static const struct of_device_id spidev_dt_ids[] = { { .compatible = "semtech,sx1301", .data = &spidev_of_check }, { .compatible = "silabs,em3581", .data = &spidev_of_check }, { .compatible = "silabs,si3210", .data = &spidev_of_check }, @@ -18,3 +67,6 @@ index 58ae4304fdab..52cb8872ffa4 100644 {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch index 77385b14b..1283047c3 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/mmc-tinkerboard-sdmmc-reboot-fix.patch @@ -1,7 +1,7 @@ -From 302cd9b8a9f1f8a7735fabea3b9a7645dc40f9cc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Myy Miouyouyou Date: Sun, 7 Jan 2018 01:52:44 +0100 -Subject: [PATCH] drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot +Subject: drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot On ASUS Tinkerboard systems, if the SDMMC hardware is shutdown before rebooting, the system will be dead, as the SDMMC is the only way to @@ -17,14 +17,14 @@ similar effects with eMMC hardware. Signed-off-by: Myy Miouyouyou --- - drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++++++++++++++++++++++++++++++ + drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c -index a3f1c2b30..7eac1f221 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c -@@ -16,6 +16,11 @@ +@@ -12,6 +12,11 @@ #include #include @@ -36,7 +36,7 @@ index a3f1c2b30..7eac1f221 100644 #include "dw_mmc.h" #include "dw_mmc-pltfm.h" -@@ -334,6 +339,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = { +@@ -527,6 +532,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = { }; MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); @@ -103,7 +103,7 @@ index a3f1c2b30..7eac1f221 100644 static int dw_mci_rockchip_probe(struct platform_device *pdev) { const struct dw_mci_drv_data *drv_data; -@@ -361,6 +426,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) +@@ -554,6 +619,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) } pm_runtime_put_autosuspend(&pdev->dev); @@ -112,5 +112,5 @@ index a3f1c2b30..7eac1f221 100644 return 0; } -- -2.14.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch index ed7158039..679bb73f5 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-01-sipv2-calls.patch @@ -1,17 +1,17 @@ -From e039790fb29227f646e91e6d7ec7c3e89c584243 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 6 Jul 2021 14:21:52 +0000 -Subject: [PATCH 1/5] rk3228/rk3328: fix ddr clock gate, add SIP v2 calls +Subject: rk3228/rk3328: fix ddr clock gate, add SIP v2 calls --- - drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++++ - drivers/clk/rockchip/clk-rk3228.c | 14 ++-- + drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++ + drivers/clk/rockchip/clk-rk3228.c | 14 +- drivers/clk/rockchip/clk-rk3328.c | 7 +- drivers/clk/rockchip/clk.h | 3 +- 4 files changed, 143 insertions(+), 11 deletions(-) diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c -index 86718c54e..b16b3795f 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = { @@ -159,10 +159,10 @@ index 86718c54e..b16b3795f 100644 pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); kfree(ddrclk); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 1f9176a5c..96393aa16 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -218,9 +218,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -215,9 +215,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), /* PD_DDR */ @@ -175,7 +175,7 @@ index 1f9176a5c..96393aa16 100644 GATE(0, "ddrphy4x", "clk_ddrphy_src", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 1, GFLAGS), FACTOR_GATE(0, "ddrc", "clk_ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, -@@ -576,8 +576,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -571,8 +571,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), @@ -186,7 +186,7 @@ index 1f9176a5c..96393aa16 100644 GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), -@@ -652,8 +652,8 @@ static const char *const rk3228_critical_clocks[] __initconst = { +@@ -647,8 +647,8 @@ static const char *const rk3228_critical_clocks[] __initconst = { "sclk_initmem_mbist", "aclk_initmem", "hclk_rom", @@ -198,10 +198,10 @@ index 1f9176a5c..96393aa16 100644 "pclk_stimer", "pclk_ddrphy", diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c -index cc18dbc18..5fdd611bb 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-rk3328.c +++ b/drivers/clk/rockchip/clk-rk3328.c -@@ -317,9 +317,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { +@@ -315,9 +315,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { RK3328_CLKGATE_CON(14), 1, GFLAGS), /* PD_DDR */ @@ -216,10 +216,10 @@ index cc18dbc18..5fdd611bb 100644 RK3328_CLKGATE_CON(18), 6, GFLAGS), GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h -index ae059b774..fdaa81ebb 100644 +index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h -@@ -363,7 +363,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, +@@ -632,7 +632,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, * DDRCLK flags, including method of setting the rate * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. */ @@ -230,5 +230,5 @@ index ae059b774..fdaa81ebb 100644 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, const char *const *parent_names, -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch index efeaace36..00619741e 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-02-sip-constants.patch @@ -1,16 +1,15 @@ -From 95358ea4a4434ad4af5545b3f762508e4f015fc3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 6 Jul 2021 14:23:36 +0000 -Subject: [PATCH 2/5] rk3228/rk3328: add ddr clock and SIP related constants - and defines +Subject: rk3228/rk3328: add ddr clock and SIP related constants and defines --- include/dt-bindings/clock/rk3228-cru.h | 1 + - include/soc/rockchip/rockchip_sip.h | 24 ++++++++++++++++++++++++ + include/soc/rockchip/rockchip_sip.h | 24 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h -index de550ea56..911824731 100644 +index 111111111111..222222222222 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -15,6 +15,7 @@ @@ -22,18 +21,18 @@ index de550ea56..911824731 100644 #define SCLK_NANDC 67 #define SCLK_SDMMC 68 diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h -index c46a9ae2a..34e653751 100644 +index 111111111111..222222222222 100644 --- a/include/soc/rockchip/rockchip_sip.h +++ b/include/soc/rockchip/rockchip_sip.h -@@ -6,6 +6,7 @@ - #ifndef __SOC_ROCKCHIP_SIP_H - #define __SOC_ROCKCHIP_SIP_H +@@ -9,6 +9,7 @@ + #define ROCKCHIP_SIP_SUSPEND_MODE 0x82000003 + #define ROCKCHIP_SLEEP_PD_CONFIG 0xff +#define ROCKCHIP_SIP_ATF_VERSION 0x82000001 #define ROCKCHIP_SIP_DRAM_FREQ 0x82000008 #define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00 #define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01 -@@ -16,5 +17,28 @@ +@@ -19,5 +20,28 @@ #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 #define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08 @@ -63,5 +62,5 @@ index c46a9ae2a..34e653751 100644 #endif -- -2.25.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch index b1b3aa8a5..9a92530a2 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-03-dfi-driver.patch @@ -1,22 +1,20 @@ -From de9678fab28f23bdc3969cdea397f4057d42ba5a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Thu, 11 Jan 2024 20:42:48 +0100 -Subject: [PATCH] add rk3228/rk3328 to rockchip dfi driver +Subject: add rk3228/rk3328 to rockchip dfi driver --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 7 +++ - drivers/devfreq/event/rockchip-dfi.c | 77 +++++++++++++++++++++++--- - include/soc/rockchip/rk3228_grf.h | 14 +++++ - include/soc/rockchip/rk3328_grf.h | 14 +++++ + arch/arm/boot/dts/rockchip/rk322x.dtsi | 7 + + drivers/devfreq/event/rockchip-dfi.c | 77 +++++++++- + include/soc/rockchip/rk3228_grf.h | 14 ++ + include/soc/rockchip/rk3328_grf.h | 14 ++ 4 files changed, 105 insertions(+), 7 deletions(-) - create mode 100644 include/soc/rockchip/rk3228_grf.h - create mode 100644 include/soc/rockchip/rk3328_grf.h diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 571626d879f8..e87096b97610 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -208,6 +208,13 @@ xin24m: oscillator { +@@ -131,6 +131,13 @@ xin24m: oscillator { #clock-cells = <0>; }; @@ -31,7 +29,7 @@ index 571626d879f8..e87096b97610 100644 compatible = "rockchip,display-subsystem"; ports = <&vop_out>; diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c -index e2a1e4463b6f..fba3a958b352 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/event/rockchip-dfi.c +++ b/drivers/devfreq/event/rockchip-dfi.c @@ -24,6 +24,8 @@ @@ -51,7 +49,7 @@ index e2a1e4463b6f..fba3a958b352 100644 struct regmap *regmap_pmu; struct clk *clk; int usecount; -@@ -669,6 +672,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) +@@ -672,6 +675,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) } #endif @@ -98,7 +96,7 @@ index e2a1e4463b6f..fba3a958b352 100644 static int rk3399_dfi_init(struct rockchip_dfi *dfi) { struct regmap *regmap_pmu = dfi->regmap_pmu; -@@ -757,6 +800,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) +@@ -761,6 +804,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) }; static const struct of_device_id rockchip_dfi_id_match[] = { @@ -107,7 +105,7 @@ index e2a1e4463b6f..fba3a958b352 100644 { .compatible = "rockchip,rk3399-dfi", .data = rk3399_dfi_init }, { .compatible = "rockchip,rk3568-dfi", .data = rk3568_dfi_init }, { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init }, -@@ -786,14 +831,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -790,14 +835,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (IS_ERR(dfi->regs)) return PTR_ERR(dfi->regs); @@ -145,7 +143,7 @@ index e2a1e4463b6f..fba3a958b352 100644 dfi->dev = dev; mutex_init(&dfi->mutex); -@@ -818,6 +879,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -822,6 +883,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (ret) return ret; @@ -156,7 +154,7 @@ index e2a1e4463b6f..fba3a958b352 100644 return 0; diff --git a/include/soc/rockchip/rk3228_grf.h b/include/soc/rockchip/rk3228_grf.h new file mode 100644 -index 000000000000..e37406814fad +index 000000000000..111111111111 --- /dev/null +++ b/include/soc/rockchip/rk3228_grf.h @@ -0,0 +1,14 @@ @@ -176,7 +174,7 @@ index 000000000000..e37406814fad +#endif diff --git a/include/soc/rockchip/rk3328_grf.h b/include/soc/rockchip/rk3328_grf.h new file mode 100644 -index 000000000000..bf6d209be7e6 +index 000000000000..111111111111 --- /dev/null +++ b/include/soc/rockchip/rk3328_grf.h @@ -0,0 +1,14 @@ @@ -195,5 +193,5 @@ index 000000000000..bf6d209be7e6 + +#endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-04-driver.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-04-driver.patch index 3039f9291..7074ef023 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-04-driver.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dmc-driver-04-driver.patch @@ -1,22 +1,19 @@ -From 8529e1141bf84ff4e0120eeb42e45a59c8e666c7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 27 Dec 2023 15:29:29 +0100 -Subject: [PATCH] rockchip: add rk3228 dmc driver +Subject: rockchip: add rk3228 dmc driver --- arch/arm/boot/dts/rockchip/rk322x.dtsi | 70 +- drivers/devfreq/Kconfig | 12 + drivers/devfreq/Makefile | 1 + - drivers/devfreq/rk3228_dmc.c | 696 +++++++++++++++++++ - include/dt-bindings/clock/rockchip-ddr.h | 63 ++ - include/dt-bindings/memory/rockchip,rk322x.h | 90 +++ - 6 files changed, 929 insertions(+), 3 deletions(-) - create mode 100644 drivers/devfreq/rk3228_dmc.c - create mode 100644 include/dt-bindings/clock/rockchip-ddr.h - create mode 100644 include/dt-bindings/memory/rockchip,rk322x.h + drivers/devfreq/rk3228_dmc.c | 827 ++++++++++ + include/dt-bindings/clock/rockchip-ddr.h | 63 + + include/dt-bindings/memory/rockchip,rk322x.h | 90 + + 6 files changed, 1060 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 41374aff62c8..c9d71a776587 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -7,6 +7,8 @@ @@ -28,8 +25,8 @@ index 41374aff62c8..c9d71a776587 100644 / { #address-cells = <1>; -@@ -104,6 +106,68 @@ dfi: dfi@11210000 { - status = "okay"; +@@ -100,6 +102,68 @@ opp-1200000000 { + }; }; + dmc: dmc@11200000 { @@ -97,7 +94,7 @@ index 41374aff62c8..c9d71a776587 100644 arm-pmu { compatible = "arm,cortex-a7-pmu"; interrupts = , -@@ -676,17 +740,17 @@ gpu_opp_table: opp-table2 { +@@ -663,17 +727,17 @@ gpu_opp_table: opp-table2 { opp-200000000 { opp-hz = /bits/ 64 <200000000>; @@ -119,10 +116,10 @@ index 41374aff62c8..c9d71a776587 100644 }; diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig -index 3c4862a752b5..066be239a16a 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig -@@ -129,6 +129,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ +@@ -140,6 +140,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ buck voltages and update a proper CCI frequency. Use the notification to get the regulator status. @@ -142,10 +139,10 @@ index 3c4862a752b5..066be239a16a 100644 tristate "ARM RK3399 DMC DEVFREQ Driver" depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile -index bf40d04928d0..059712bfe5f5 100644 +index 111111111111..222222222222 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o +@@ -14,6 +14,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o @@ -153,174 +150,9 @@ index bf40d04928d0..059712bfe5f5 100644 obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-mbus.o obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o -diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h -new file mode 100644 -index 000000000000..b065432e7793 ---- /dev/null -+++ b/include/dt-bindings/clock/rockchip-ddr.h -@@ -0,0 +1,63 @@ -+/* -+ * -+ * Copyright (C) 2017 ROCKCHIP, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H -+#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H -+ -+#define DDR2_DEFAULT (0) -+ -+#define DDR3_800D (0) /* 5-5-5 */ -+#define DDR3_800E (1) /* 6-6-6 */ -+#define DDR3_1066E (2) /* 6-6-6 */ -+#define DDR3_1066F (3) /* 7-7-7 */ -+#define DDR3_1066G (4) /* 8-8-8 */ -+#define DDR3_1333F (5) /* 7-7-7 */ -+#define DDR3_1333G (6) /* 8-8-8 */ -+#define DDR3_1333H (7) /* 9-9-9 */ -+#define DDR3_1333J (8) /* 10-10-10 */ -+#define DDR3_1600G (9) /* 8-8-8 */ -+#define DDR3_1600H (10) /* 9-9-9 */ -+#define DDR3_1600J (11) /* 10-10-10 */ -+#define DDR3_1600K (12) /* 11-11-11 */ -+#define DDR3_1866J (13) /* 10-10-10 */ -+#define DDR3_1866K (14) /* 11-11-11 */ -+#define DDR3_1866L (15) /* 12-12-12 */ -+#define DDR3_1866M (16) /* 13-13-13 */ -+#define DDR3_2133K (17) /* 11-11-11 */ -+#define DDR3_2133L (18) /* 12-12-12 */ -+#define DDR3_2133M (19) /* 13-13-13 */ -+#define DDR3_2133N (20) /* 14-14-14 */ -+#define DDR3_DEFAULT (21) -+#define DDR_DDR2 (22) -+#define DDR_LPDDR (23) -+#define DDR_LPDDR2 (24) -+ -+#define DDR4_1600J (0) /* 10-10-10 */ -+#define DDR4_1600K (1) /* 11-11-11 */ -+#define DDR4_1600L (2) /* 12-12-12 */ -+#define DDR4_1866L (3) /* 12-12-12 */ -+#define DDR4_1866M (4) /* 13-13-13 */ -+#define DDR4_1866N (5) /* 14-14-14 */ -+#define DDR4_2133N (6) /* 14-14-14 */ -+#define DDR4_2133P (7) /* 15-15-15 */ -+#define DDR4_2133R (8) /* 16-16-16 */ -+#define DDR4_2400P (9) /* 15-15-15 */ -+#define DDR4_2400R (10) /* 16-16-16 */ -+#define DDR4_2400U (11) /* 18-18-18 */ -+#define DDR4_DEFAULT (12) -+ -+#define PAUSE_CPU_STACK_SIZE 16 -+ -+#endif -diff --git a/include/dt-bindings/memory/rockchip,rk322x.h b/include/dt-bindings/memory/rockchip,rk322x.h -new file mode 100644 -index 000000000000..1ab3317d700e ---- /dev/null -+++ b/include/dt-bindings/memory/rockchip,rk322x.h -@@ -0,0 +1,90 @@ -+/* -+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H -+#define _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H -+ -+#define DDR3_DS_34ohm (1 << 1) -+#define DDR3_DS_40ohm (0x0) -+ -+#define LP2_DS_34ohm (0x1) -+#define LP2_DS_40ohm (0x2) -+#define LP2_DS_48ohm (0x3) -+#define LP2_DS_60ohm (0x4) -+#define LP2_DS_68_6ohm (0x5)/* optional */ -+#define LP2_DS_80ohm (0x6) -+#define LP2_DS_120ohm (0x7)/* optional */ -+ -+#define LP3_DS_34ohm (0x1) -+#define LP3_DS_40ohm (0x2) -+#define LP3_DS_48ohm (0x3) -+#define LP3_DS_60ohm (0x4) -+#define LP3_DS_80ohm (0x6) -+#define LP3_DS_34D_40U (0x9) -+#define LP3_DS_40D_48U (0xa) -+#define LP3_DS_34D_48U (0xb) -+ -+#define DDR3_ODT_DIS (0) -+#define DDR3_ODT_40ohm ((1 << 2) | (1 << 6)) -+#define DDR3_ODT_60ohm (1 << 2) -+#define DDR3_ODT_120ohm (1 << 6) -+ -+#define LP3_ODT_DIS (0) -+#define LP3_ODT_60ohm (1) -+#define LP3_ODT_120ohm (2) -+#define LP3_ODT_240ohm (3) -+ -+#define PHY_DDR3_RON_RTT_DISABLE (0) -+#define PHY_DDR3_RON_RTT_451ohm (1) -+#define PHY_DDR3_RON_RTT_225ohm (2) -+#define PHY_DDR3_RON_RTT_150ohm (3) -+#define PHY_DDR3_RON_RTT_112ohm (4) -+#define PHY_DDR3_RON_RTT_90ohm (5) -+#define PHY_DDR3_RON_RTT_75ohm (6) -+#define PHY_DDR3_RON_RTT_64ohm (7) -+#define PHY_DDR3_RON_RTT_56ohm (16) -+#define PHY_DDR3_RON_RTT_50ohm (17) -+#define PHY_DDR3_RON_RTT_45ohm (18) -+#define PHY_DDR3_RON_RTT_41ohm (19) -+#define PHY_DDR3_RON_RTT_37ohm (20) -+#define PHY_DDR3_RON_RTT_34ohm (21) -+#define PHY_DDR3_RON_RTT_33ohm (22) -+#define PHY_DDR3_RON_RTT_30ohm (23) -+#define PHY_DDR3_RON_RTT_28ohm (24) -+#define PHY_DDR3_RON_RTT_26ohm (25) -+#define PHY_DDR3_RON_RTT_25ohm (26) -+#define PHY_DDR3_RON_RTT_23ohm (27) -+#define PHY_DDR3_RON_RTT_22ohm (28) -+#define PHY_DDR3_RON_RTT_21ohm (29) -+#define PHY_DDR3_RON_RTT_20ohm (30) -+#define PHY_DDR3_RON_RTT_19ohm (31) -+ -+#define PHY_LP23_RON_RTT_DISABLE (0) -+#define PHY_LP23_RON_RTT_480ohm (1) -+#define PHY_LP23_RON_RTT_240ohm (2) -+#define PHY_LP23_RON_RTT_160ohm (3) -+#define PHY_LP23_RON_RTT_120ohm (4) -+#define PHY_LP23_RON_RTT_96ohm (5) -+#define PHY_LP23_RON_RTT_80ohm (6) -+#define PHY_LP23_RON_RTT_68ohm (7) -+#define PHY_LP23_RON_RTT_60ohm (16) -+#define PHY_LP23_RON_RTT_53ohm (17) -+#define PHY_LP23_RON_RTT_48ohm (18) -+#define PHY_LP23_RON_RTT_43ohm (19) -+#define PHY_LP23_RON_RTT_40ohm (20) -+#define PHY_LP23_RON_RTT_37ohm (21) -+#define PHY_LP23_RON_RTT_34ohm (22) -+#define PHY_LP23_RON_RTT_32ohm (23) -+#define PHY_LP23_RON_RTT_30ohm (24) -+#define PHY_LP23_RON_RTT_28ohm (25) -+#define PHY_LP23_RON_RTT_26ohm (26) -+#define PHY_LP23_RON_RTT_25ohm (27) -+#define PHY_LP23_RON_RTT_24ohm (28) -+#define PHY_LP23_RON_RTT_22ohm (29) -+#define PHY_LP23_RON_RTT_21ohm (30) -+#define PHY_LP23_RON_RTT_20ohm (31) -+ -+#endif /* _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H */ diff --git a/drivers/devfreq/rk3228_dmc.c b/drivers/devfreq/rk3228_dmc.c new file mode 100644 -index 000000000000..1dbf53043f69 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/devfreq/rk3228_dmc.c @@ -0,0 +1,827 @@ @@ -1151,5 +983,171 @@ index 000000000000..1dbf53043f69 +MODULE_AUTHOR("Lin Huang "); +MODULE_AUTHOR("Paolo Sabatino "); +MODULE_DESCRIPTION("RK3228 dmcfreq driver with devfreq framework"); +diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/dt-bindings/clock/rockchip-ddr.h +@@ -0,0 +1,63 @@ ++/* ++ * ++ * Copyright (C) 2017 ROCKCHIP, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++ ++#define DDR2_DEFAULT (0) ++ ++#define DDR3_800D (0) /* 5-5-5 */ ++#define DDR3_800E (1) /* 6-6-6 */ ++#define DDR3_1066E (2) /* 6-6-6 */ ++#define DDR3_1066F (3) /* 7-7-7 */ ++#define DDR3_1066G (4) /* 8-8-8 */ ++#define DDR3_1333F (5) /* 7-7-7 */ ++#define DDR3_1333G (6) /* 8-8-8 */ ++#define DDR3_1333H (7) /* 9-9-9 */ ++#define DDR3_1333J (8) /* 10-10-10 */ ++#define DDR3_1600G (9) /* 8-8-8 */ ++#define DDR3_1600H (10) /* 9-9-9 */ ++#define DDR3_1600J (11) /* 10-10-10 */ ++#define DDR3_1600K (12) /* 11-11-11 */ ++#define DDR3_1866J (13) /* 10-10-10 */ ++#define DDR3_1866K (14) /* 11-11-11 */ ++#define DDR3_1866L (15) /* 12-12-12 */ ++#define DDR3_1866M (16) /* 13-13-13 */ ++#define DDR3_2133K (17) /* 11-11-11 */ ++#define DDR3_2133L (18) /* 12-12-12 */ ++#define DDR3_2133M (19) /* 13-13-13 */ ++#define DDR3_2133N (20) /* 14-14-14 */ ++#define DDR3_DEFAULT (21) ++#define DDR_DDR2 (22) ++#define DDR_LPDDR (23) ++#define DDR_LPDDR2 (24) ++ ++#define DDR4_1600J (0) /* 10-10-10 */ ++#define DDR4_1600K (1) /* 11-11-11 */ ++#define DDR4_1600L (2) /* 12-12-12 */ ++#define DDR4_1866L (3) /* 12-12-12 */ ++#define DDR4_1866M (4) /* 13-13-13 */ ++#define DDR4_1866N (5) /* 14-14-14 */ ++#define DDR4_2133N (6) /* 14-14-14 */ ++#define DDR4_2133P (7) /* 15-15-15 */ ++#define DDR4_2133R (8) /* 16-16-16 */ ++#define DDR4_2400P (9) /* 15-15-15 */ ++#define DDR4_2400R (10) /* 16-16-16 */ ++#define DDR4_2400U (11) /* 18-18-18 */ ++#define DDR4_DEFAULT (12) ++ ++#define PAUSE_CPU_STACK_SIZE 16 ++ ++#endif +diff --git a/include/dt-bindings/memory/rockchip,rk322x.h b/include/dt-bindings/memory/rockchip,rk322x.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/dt-bindings/memory/rockchip,rk322x.h +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H ++#define _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H ++ ++#define DDR3_DS_34ohm (1 << 1) ++#define DDR3_DS_40ohm (0x0) ++ ++#define LP2_DS_34ohm (0x1) ++#define LP2_DS_40ohm (0x2) ++#define LP2_DS_48ohm (0x3) ++#define LP2_DS_60ohm (0x4) ++#define LP2_DS_68_6ohm (0x5)/* optional */ ++#define LP2_DS_80ohm (0x6) ++#define LP2_DS_120ohm (0x7)/* optional */ ++ ++#define LP3_DS_34ohm (0x1) ++#define LP3_DS_40ohm (0x2) ++#define LP3_DS_48ohm (0x3) ++#define LP3_DS_60ohm (0x4) ++#define LP3_DS_80ohm (0x6) ++#define LP3_DS_34D_40U (0x9) ++#define LP3_DS_40D_48U (0xa) ++#define LP3_DS_34D_48U (0xb) ++ ++#define DDR3_ODT_DIS (0) ++#define DDR3_ODT_40ohm ((1 << 2) | (1 << 6)) ++#define DDR3_ODT_60ohm (1 << 2) ++#define DDR3_ODT_120ohm (1 << 6) ++ ++#define LP3_ODT_DIS (0) ++#define LP3_ODT_60ohm (1) ++#define LP3_ODT_120ohm (2) ++#define LP3_ODT_240ohm (3) ++ ++#define PHY_DDR3_RON_RTT_DISABLE (0) ++#define PHY_DDR3_RON_RTT_451ohm (1) ++#define PHY_DDR3_RON_RTT_225ohm (2) ++#define PHY_DDR3_RON_RTT_150ohm (3) ++#define PHY_DDR3_RON_RTT_112ohm (4) ++#define PHY_DDR3_RON_RTT_90ohm (5) ++#define PHY_DDR3_RON_RTT_75ohm (6) ++#define PHY_DDR3_RON_RTT_64ohm (7) ++#define PHY_DDR3_RON_RTT_56ohm (16) ++#define PHY_DDR3_RON_RTT_50ohm (17) ++#define PHY_DDR3_RON_RTT_45ohm (18) ++#define PHY_DDR3_RON_RTT_41ohm (19) ++#define PHY_DDR3_RON_RTT_37ohm (20) ++#define PHY_DDR3_RON_RTT_34ohm (21) ++#define PHY_DDR3_RON_RTT_33ohm (22) ++#define PHY_DDR3_RON_RTT_30ohm (23) ++#define PHY_DDR3_RON_RTT_28ohm (24) ++#define PHY_DDR3_RON_RTT_26ohm (25) ++#define PHY_DDR3_RON_RTT_25ohm (26) ++#define PHY_DDR3_RON_RTT_23ohm (27) ++#define PHY_DDR3_RON_RTT_22ohm (28) ++#define PHY_DDR3_RON_RTT_21ohm (29) ++#define PHY_DDR3_RON_RTT_20ohm (30) ++#define PHY_DDR3_RON_RTT_19ohm (31) ++ ++#define PHY_LP23_RON_RTT_DISABLE (0) ++#define PHY_LP23_RON_RTT_480ohm (1) ++#define PHY_LP23_RON_RTT_240ohm (2) ++#define PHY_LP23_RON_RTT_160ohm (3) ++#define PHY_LP23_RON_RTT_120ohm (4) ++#define PHY_LP23_RON_RTT_96ohm (5) ++#define PHY_LP23_RON_RTT_80ohm (6) ++#define PHY_LP23_RON_RTT_68ohm (7) ++#define PHY_LP23_RON_RTT_60ohm (16) ++#define PHY_LP23_RON_RTT_53ohm (17) ++#define PHY_LP23_RON_RTT_48ohm (18) ++#define PHY_LP23_RON_RTT_43ohm (19) ++#define PHY_LP23_RON_RTT_40ohm (20) ++#define PHY_LP23_RON_RTT_37ohm (21) ++#define PHY_LP23_RON_RTT_34ohm (22) ++#define PHY_LP23_RON_RTT_32ohm (23) ++#define PHY_LP23_RON_RTT_30ohm (24) ++#define PHY_LP23_RON_RTT_28ohm (25) ++#define PHY_LP23_RON_RTT_26ohm (26) ++#define PHY_LP23_RON_RTT_25ohm (27) ++#define PHY_LP23_RON_RTT_24ohm (28) ++#define PHY_LP23_RON_RTT_22ohm (29) ++#define PHY_LP23_RON_RTT_21ohm (30) ++#define PHY_LP23_RON_RTT_20ohm (31) ++ ++#endif /* _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H */ -- -2.34.1 +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dwc2-no-clock-gating.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dwc2-no-clock-gating.patch index c5c290d43..a736c7887 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dwc2-no-clock-gating.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-dwc2-no-clock-gating.patch @@ -1,9 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 5 Mar 2024 20:08:38 +0100 +Subject: [ARCHEOLOGY] rockchip: add patches to fix peripheral mode + +> X-Git-Archeology: > recovered message: > rk322x has peripheral mode that is not working +> X-Git-Archeology: > recovered message: > really well, add various non-upstream patches +> X-Git-Archeology: > recovered message: > and timing adjustments that makes things a bit +> X-Git-Archeology: > recovered message: > more usable (mass storage and ethernet works, +> X-Git-Archeology: > recovered message: > uac isn't) +> X-Git-Archeology: - Revision 55836c60740bbf6f602216360f5ea785675153d2: https://github.com/armbian/build/commit/55836c60740bbf6f602216360f5ea785675153d2 +> X-Git-Archeology: Date: Tue, 05 Mar 2024 20:08:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: add patches to fix peripheral mode +> X-Git-Archeology: +> X-Git-Archeology: - Revision 47d2e8287e34fed3e47f37ab076d0f34ed0ac399: https://github.com/armbian/build/commit/47d2e8287e34fed3e47f37ab076d0f34ed0ac399 +> X-Git-Archeology: Date: Mon, 25 Mar 2024 19:38:38 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.8 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 724573bf7a21e61b0b626f835031a4c3206bb8ba: https://github.com/armbian/build/commit/724573bf7a21e61b0b626f835031a4c3206bb8ba +> X-Git-Archeology: Date: Wed, 05 Jun 2024 22:18:51 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip family edge kernel to 6.9 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7da7bbf61cb776a054219e35926d391dad9a67a7: https://github.com/armbian/build/commit/7da7bbf61cb776a054219e35926d391dad9a67a7 +> X-Git-Archeology: Date: Mon, 22 Jul 2024 19:18:14 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.10 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 94ec783de0dad381b3e2e71d646d8428af4d5051: https://github.com/armbian/build/commit/94ec783de0dad381b3e2e71d646d8428af4d5051 +> X-Git-Archeology: Date: Wed, 18 Sep 2024 14:03:19 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.11 +> X-Git-Archeology: +> X-Git-Archeology: - Revision c90a0f7890bddc8e755847fc8227e15828950251: https://github.com/armbian/build/commit/c90a0f7890bddc8e755847fc8227e15828950251 +> X-Git-Archeology: Date: Sat, 30 Nov 2024 13:07:31 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.12 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/usb/dwc2/params.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c -index a937eadbc9b3..f1f6f6afe7fe 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c -@@ -133,6 +133,14 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) - p->no_clock_gating = true; +@@ -132,6 +132,14 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) + p->hird_threshold_en = false; } +static void dwc2_set_rk3228_params(struct dwc2_hsotg *hsotg) @@ -17,7 +86,7 @@ index a937eadbc9b3..f1f6f6afe7fe 100644 static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg) { struct dwc2_core_params *p = &hsotg->params; -@@ -314,6 +322,7 @@ const struct of_device_id dwc2_of_match_table[] = { +@@ -313,6 +321,7 @@ const struct of_device_id dwc2_of_match_table[] = { { .compatible = "ingenic,x1830-otg", .data = dwc2_set_x1600_params }, { .compatible = "ingenic,x2000-otg", .data = dwc2_set_x2000_params }, { .compatible = "rockchip,rk3066-usb", .data = dwc2_set_rk_params }, @@ -25,3 +94,6 @@ index a937eadbc9b3..f1f6f6afe7fe 100644 { .compatible = "lantiq,danube-usb", .data = &dwc2_set_ltq_danube_params }, { .compatible = "lantiq,ase-usb", .data = &dwc2_set_ltq_ase_params }, { .compatible = "lantiq,arx100-usb", .data = &dwc2_set_ltq_ase_params }, +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-usb-reset-props.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-usb-reset-props.patch index 81deaa758..1cacf0427 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-usb-reset-props.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/rk322x-usb-reset-props.patch @@ -1,7 +1,7 @@ -From 6668d12fd4a628299ffbf89794b6f7f67416e3fa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 4 May 2024 15:12:43 +0200 -Subject: [PATCH] add reset props to usb otg/ehci ports +Subject: add reset props to usb otg/ehci ports usb resets are needed in case u-boot does its own reset of the devices, otherwise ports are left in a @@ -18,10 +18,10 @@ always detected also in case of timeout) 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 03d9baddcbab..17c5f0a8fcf3 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi -@@ -807,6 +807,8 @@ usb_otg: usb@30040000 { +@@ -971,6 +971,8 @@ usb_otg: usb@30040000 { g-tx-fifo-size = <256 128 128 64 32 16>; phys = <&u2phy0_otg>; phy-names = "usb2-phy"; @@ -30,7 +30,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -817,6 +819,8 @@ usb_host0_ehci: usb@30080000 { +@@ -981,6 +983,8 @@ usb_host0_ehci: usb@30080000 { clocks = <&cru HCLK_HOST0>, <&u2phy0>; phys = <&u2phy0_host>; phy-names = "usb"; @@ -39,7 +39,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -837,6 +841,8 @@ usb_host1_ehci: usb@300c0000 { +@@ -1001,6 +1005,8 @@ usb_host1_ehci: usb@300c0000 { clocks = <&cru HCLK_HOST1>, <&u2phy1>; phys = <&u2phy1_otg>; phy-names = "usb"; @@ -48,7 +48,7 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 status = "disabled"; }; -@@ -857,6 +863,8 @@ usb_host2_ehci: usb@30100000 { +@@ -1021,6 +1027,8 @@ usb_host2_ehci: usb@30100000 { clocks = <&cru HCLK_HOST2>, <&u2phy1>; phys = <&u2phy1_host>; phy-names = "usb"; @@ -58,10 +58,10 @@ index 03d9baddcbab..17c5f0a8fcf3 100644 }; diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c -index 5635e4d7ec88..1e20aabc2033 100644 +index 111111111111..222222222222 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c -@@ -413,7 +413,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) +@@ -419,7 +419,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) if (!(gotgctl & GOTGCTL_CONID_B) || (gusbcfg & GUSBCFG_FORCEHOSTMODE)) { @@ -71,5 +71,5 @@ index 5635e4d7ec88..1e20aabc2033 100644 } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch index 17b44a5f3..ba5becfd4 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-ath9k-no-bulk-EP3-EP4.patch @@ -1,21 +1,93 @@ -FROM: Solidhal - -This patch reverses commit 2b721118b7821107757eb1d37af4b60e877b27e7, as can bee seen here: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b721118b7821107757eb1d37af4b60e877b27e7 - -This commit caused issues on veyron speedy with ath9k and dwc2 drivers. Any ath9k device (ar9271) -would intermittently work, most of the time ending in errors as can bee seen here: -https://github.com/SolidHal/PrawnOS/issues/38 -This commit fixes that issue. -This is only a temporary work around while a permenant fix is found, as this commit seems to only cause issues -with dwc2 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas McKahan +Date: Fri, 25 Jan 2019 00:21:49 -0500 +Subject: [ARCHEOLOGY] [ rockchip-dev ] update patchset, target 5.0 RC +> X-Git-Archeology: > recovered message: > Includes experimental video decoder driver. Thanks as always to @miouyouyou for the base patches +> X-Git-Archeology: - Revision 5a0d83a316e19a3df6a6fd1f8bb536a88ca8e924: https://github.com/armbian/build/commit/5a0d83a316e19a3df6a6fd1f8bb536a88ca8e924 +> X-Git-Archeology: Date: Fri, 25 Jan 2019 00:21:49 -0500 +> X-Git-Archeology: From: Thomas McKahan +> X-Git-Archeology: Subject: [ rockchip-dev ] update patchset, target 5.0 RC +> X-Git-Archeology: +> X-Git-Archeology: - Revision 9afdc70340c4492ad0c1db9ace45e094d0c56df5: https://github.com/armbian/build/commit/9afdc70340c4492ad0c1db9ace45e094d0c56df5 +> X-Git-Archeology: Date: Wed, 08 May 2019 09:42:55 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: [ rockchip dev ] move to 5.1.y and adjust patches false permissions, add new patch to remove broken boards +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 9020803f1d17314db0931c50ef25d2bd15542817: https://github.com/armbian/build/commit/9020803f1d17314db0931c50ef25d2bd15542817 +> X-Git-Archeology: Date: Sun, 28 Jun 2020 17:13:32 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Update kernel configs due to logo support, adjust patches +> X-Git-Archeology: +> X-Git-Archeology: - Revision f86c6b313828b356a41afa6f5ef92dbcace0bb5c: https://github.com/armbian/build/commit/f86c6b313828b356a41afa6f5ef92dbcace0bb5c +> X-Git-Archeology: Date: Thu, 03 Sep 2020 21:37:23 +0200 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Moving Rockchip 32bit to 5.8.y (#2183) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision c0001d566b3770dae722c47180dcb942bed7006a: https://github.com/armbian/build/commit/c0001d566b3770dae722c47180dcb942bed7006a +> X-Git-Archeology: Date: Wed, 14 Dec 2022 01:43:31 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump bcm, imx, mvebu64 and xu4 EDGE to 6.1.y (#4560) +> X-Git-Archeology: +> X-Git-Archeology: - Revision cb3226dfa320e6359a1c11c3744e67ec50a6e69f: https://github.com/armbian/build/commit/cb3226dfa320e6359a1c11c3744e67ec50a6e69f +> X-Git-Archeology: Date: Tue, 24 Jan 2023 20:56:00 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit to kernel 6.1 +> X-Git-Archeology: +> X-Git-Archeology: - Revision f08dcd48677d2a34f349bf571c979cd422bffcc3: https://github.com/armbian/build/commit/f08dcd48677d2a34f349bf571c979cd422bffcc3 +> X-Git-Archeology: Date: Tue, 31 Oct 2023 08:13:23 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: rockchip,rk322x: bump edge kernel to 6.6 (#5875) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 38 +++++++--- + 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c -index 3f563e02d..903851481 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c -@@ -118,10 +118,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, +@@ -116,10 +116,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, cmd->skb = skb; cmd->hif_dev = hif_dev; @@ -29,7 +101,7 @@ index 3f563e02d..903851481 100644 usb_anchor_urb(urb, &hif_dev->regout_submitted); ret = usb_submit_urb(urb, GFP_KERNEL); -@@ -735,11 +735,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) +@@ -778,11 +778,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) rx_buf->skb = skb; @@ -44,7 +116,7 @@ index 3f563e02d..903851481 100644 } resubmit: -@@ -944,11 +944,11 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) +@@ -995,11 +995,11 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) rx_buf->hif_dev = hif_dev; rx_buf->skb = skb; @@ -59,7 +131,7 @@ index 3f563e02d..903851481 100644 /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->reg_in_submitted); -@@ -1069,7 +1069,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) +@@ -1120,7 +1120,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { @@ -70,7 +142,7 @@ index 3f563e02d..903851481 100644 ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { -@@ -1079,6 +1081,20 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) +@@ -1130,6 +1132,20 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) return ret; } @@ -91,7 +163,7 @@ index 3f563e02d..903851481 100644 /* Alloc URBs */ ret = ath9k_hif_usb_alloc_urbs(hif_dev); if (ret) { -@@ -1353,7 +1369,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) +@@ -1418,7 +1434,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) if (!buf) return; @@ -100,3 +172,6 @@ index 3f563e02d..903851481 100644 buf, 4, NULL, USB_MSG_TIMEOUT); if (ret) dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-add-bcm43342.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-add-bcm43342.patch index e0307dc9c..9b91b3f14 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-add-bcm43342.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-add-bcm43342.patch @@ -9,7 +9,7 @@ Subject: add broadcom bcm43342 chip id 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -index 6b38d9de71af..6a603d045103 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -609,6 +609,7 @@ BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); @@ -29,7 +29,7 @@ index 6b38d9de71af..6a603d045103 100644 BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -index 44684bf1b9ac..bcf48de78d53 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h @@ -27,6 +27,7 @@ diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch index affb86e4e..b77095768 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-brcmfmac-ap6330-firmware.patch @@ -1,10 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo +Date: Thu, 22 Nov 2018 07:04:19 +0100 +Subject: [ARCHEOLOGY] Add rk3288 xt-q8l-v10 CSC board (#1158) + +> X-Git-Archeology: > recovered message: > This merge request contains various files which add support for xt-q8l-v10 boards (TVBox) equipped with Rockchip RK3288 SoC, AP6330 WiSoC (BCM4330 WiFi + Bluetooth), 2 GB DRAM (LPDDR2 or DDR3), 8 Gb eMMC, Gigabit Ethernet, 3 USB (1 OTG), 1 microSD slot, SPDIF optical output, 1 HDMI. +> X-Git-Archeology: > recovered message: > Kernel patches: +> X-Git-Archeology: > recovered message: > This thouches all three linux-rockchip-* kernelconfigs, just adds brcmfmac and brcmutil modules and remote controller support. default flavor activates rockchip own remote controller driver, next and dev use the mainline GPIO CIR driver (dev has lirc userland support activated too). +> X-Git-Archeology: > recovered message: > About the remote controller, an additional kernel module is added to the existing keymaps which is activated via device tree. +> X-Git-Archeology: > recovered message: > About possibly clashing patches assert-phy-reset-when-waking-up-in-rk3288-platform.patch should be checked against other rk3288 boards because it addresses an errata in rk3288 which causes the USB Host ports to stop responding when exiting from autosleep. On my device if I connect the first USB device when the system is already running, the USB Host gets stuck without this patch. Probably to work correctly on other platforms the device tree should include the proper reset lines of the USB PHYs (for reference, check patch/kernel/rockchip-dev/xt-q8l-v10-add-device-tree.patch starting from line 869). +> X-Git-Archeology: > recovered message: > Patch 1-2-regulator-act8865-add-restart-handler-for-act8846.patch adds a restart handler which allows reboot using SIPC bit on act8846 power regulator. Possibly MiQi board is affected (is reboot working there?), others (tinkerboard) should not care. +> X-Git-Archeology: > recovered message: > Patch brcmfmac-add-ap6330-firmware.patch adds firmware file names for ap6330 , should be harmless in other cases. +> X-Git-Archeology: > recovered message: > Patch 0010-GPU-Mali-Midgard-remove-rcu_read_lock-references.patch is from Miouyouyou. It should be harmless, it was suggested by him to do some tests with devfreq +> X-Git-Archeology: > recovered message: > Other patches just add the proper device trees, Kconfig and bits for supporting the board as a regular kernel supported board and should not interfere with anything else +> X-Git-Archeology: > recovered message: > U-Boot patches: +> X-Git-Archeology: > recovered message: > All the patches for u-boot are per-board, so nothing is added which may interfere with other existing boards here. They include the device tree and u-boot config and also a couple of patches to support the silergy power regulators driving current to CPU and GPU +> X-Git-Archeology: > recovered message: > * Initial commit to provide kernel and u-boot configuration and device trees for xt-q8-v10 as patches +> X-Git-Archeology: > recovered message: > Modification to rockchip config to add initialization bits for xt-q8-v10 +> X-Git-Archeology: > recovered message: > * Committing correct path for rk3288_ddr_400Mhz... rockchip blob, moved assembling into another section to produce +> X-Git-Archeology: > recovered message: > immediately an u-boot working binary +> X-Git-Archeology: > recovered message: > * Enabled broadcom fmac driver in rockchip-next config +> X-Git-Archeology: > recovered message: > * Changed name definition of rk3288-xt-q8-v10 board to "TVBox" +> X-Git-Archeology: > recovered message: > Added bits to include support AP6330 and binary firmwares into the final image +> X-Git-Archeology: > recovered message: > * Fixed device tree file name in related patch, added patching of Makefile to produce the device tree binary accordingly +> X-Git-Archeology: > recovered message: > * Fixed xt-q8-v10 device tree patch +> X-Git-Archeology: > recovered message: > Added brcmfmac driver to rockchip dev and default kernel configs +> X-Git-Archeology: > recovered message: > * Syncing with upstream +> X-Git-Archeology: > recovered message: > * Splitted add-xt-q8... kernel patches into two separate patches +> X-Git-Archeology: > recovered message: > * Fixed bad extension while adding dtb in makefile for rockchip-default configuration +> X-Git-Archeology: > recovered message: > Updated device tree patches for all rockchip confs +> X-Git-Archeology: > recovered message: > * Enable mmc0 and usb in u-boot config +> X-Git-Archeology: > recovered message: > Fixed again makefile patch for kernel next +> X-Git-Archeology: > recovered message: > * Adding patches to reset the USB phy when kernel requires a reset, fixes autosuspend issue +> X-Git-Archeology: > recovered message: > * Changed xt-q8-v10 to proper xt-q8l-v10 in every string and every filename +> X-Git-Archeology: > recovered message: > Added power hold to u-boot, so now the device will boot and stay turned on without the need for the OTG cable anymore +> X-Git-Archeology: > recovered message: > * Changed names from 'Q8' to proper 'XT-Q8L-V10' in device tree patch files +> X-Git-Archeology: > recovered message: > * Legacy kernel device tree: +> X-Git-Archeology: > recovered message: > Fixed bluetooth gpio pin clashing +> X-Git-Archeology: > recovered message: > Fixed HDMI gpio pin clashing +> X-Git-Archeology: > recovered message: > Added support for PWM-based IR-Receiver, added driver in kernel default config too +> X-Git-Archeology: > recovered message: > Various other fixes to avoid some complaints from the kernel +> X-Git-Archeology: > recovered message: > * Added booting bluetooth systemd service for AP6330 (xt-q8l-v10) that loads patchram and invokes hciattach +> X-Git-Archeology: > recovered message: > Minor fixes to -next and -dev device trees for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > * Disabled OTG USB port in u-boot due to long timeout during initialization +> X-Git-Archeology: > recovered message: > Fixed warning during u-boot dts compilation +> X-Git-Archeology: > recovered message: > Added emmc as second boot device in dts +> X-Git-Archeology: > recovered message: > * Adding myself to licensing +> X-Git-Archeology: > recovered message: > * Committing modifications to device trees +> X-Git-Archeology: > recovered message: > * Fixed dmac_bus_s explicitly set to unused dmac, restored right dmac in xt-q8l-v10 dts only +> X-Git-Archeology: > recovered message: > Change PLL_CPLL frequency in device tree to 408 Mhz to avoid fractional divisor warnings +> X-Git-Archeology: > recovered message: > * Added proper xt-q8l-v10_rk3288 configuration to u-boot, now appearing in config menu and +> X-Git-Archeology: > recovered message: > correctly selectable as a real target +> X-Git-Archeology: > recovered message: > Fixed typo in device tree from rockchip +> X-Git-Archeology: > recovered message: > * Fixed missing semicolon in device tree for default configuration +> X-Git-Archeology: > recovered message: > Fixed patch files for u-boot appending themselves to files on each compilation +> X-Git-Archeology: > recovered message: > * Added bits to enable power to USB ports in u-boot, thus enabling booting from USB devices (only USB host port for now) +> X-Git-Archeology: > recovered message: > * Changed u-boot binary creation using the rockchip SPL properly +> X-Git-Archeology: > recovered message: > * Added boot order for xt-q8l-v10: sdcard, usb0, eMMC, network +> X-Git-Archeology: > recovered message: > * Added bionic:next in beta config for xt-q8l-v10 board +> X-Git-Archeology: > recovered message: > * Changed some minor bits in xt-q8l-v10 device tree files, added missing bits to dev flavour +> X-Git-Archeology: > recovered message: > Added patches to introduce fairchild fan53555/silergy82x regulators to u-boot and enabled in xt-q8l-v10 device tree +> X-Git-Archeology: > recovered message: > * Updated u-boot to version v2018.03 for xt-q8l-v10. Other rk3288 boards will gain v2018.05 from main armbian fork +> X-Git-Archeology: > recovered message: > Removed pre-reloc labels in u-boot device tree because they are not necessary since we don't use u-boot SPL for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > Removed vmmc-supply and vqmmc-supply in u-boot device tree to avoid hang on boot +> X-Git-Archeology: > recovered message: > * Tidied up a bit device trees, in particular some modifications are made to power regulator properties comparing them against the original q8l device tree +> X-Git-Archeology: > recovered message: > Removed unnecessary dummy regulator, removed unnecessary capacities to embedded eMMC +> X-Git-Archeology: > recovered message: > Disabled unused USB host +> X-Git-Archeology: > recovered message: > Removed vmmc-supply and vqmmc-supply from emmc section because it causes hang in u-boot v2018.03 and newer +> X-Git-Archeology: > recovered message: > * Restored previous regulator in u-boot dts +> X-Git-Archeology: > recovered message: > removed assert phy reset USB patch from rockchip-dev because of some upstream incompatible changes +> X-Git-Archeology: > recovered message: > * Added patch to enable IRQ for Midgard drivers which caused massive slowdown on dev kernel +> X-Git-Archeology: > recovered message: > Changed u-boot if-code for xt-q8l-v10 in rockchip.conf +> X-Git-Archeology: > recovered message: > Removed references to rk3288-linux.dtsi in xt-q8l-v10 device tree for default kernel +> X-Git-Archeology: > recovered message: > * Committing effective removal of USB reset assert for dev kernel +> X-Git-Archeology: > recovered message: > Committing changes to u-boot device tree +> X-Git-Archeology: > recovered message: > * Added patch to disable USB power down for rockchip devices broken on latest kernel +> X-Git-Archeology: > recovered message: > * Removed usb dwc2 patch to reinject it from specific branch +> X-Git-Archeology: > recovered message: > * Reverting some voltage changes for xt-q8l-v10 device in rockchip-dev +> X-Git-Archeology: > recovered message: > * Reverting some voltage changes for xt-q8l-v10 in u-boot section +> X-Git-Archeology: > recovered message: > * Added patch to make USB ports working again on rockchip devices with mainline +> X-Git-Archeology: > recovered message: > kernel >= 4.18 +> X-Git-Archeology: > recovered message: > * Changed the 0 into false +> X-Git-Archeology: > recovered message: > * Moved xt-q8l-v10 u-boot patches into board_xt-q8l-v10 directory +> X-Git-Archeology: > recovered message: > * Changed some minor things in rockchip-dev dts for xt-q8l-v10, added mali midgard driver to dev kernel config +> X-Git-Archeology: > recovered message: > * Added devfreq support for Mali in rockchip-next flavour +> X-Git-Archeology: > recovered message: > * Remove manually applied patch (0007-drivers-drm...) because it has been +> X-Git-Archeology: > recovered message: > added to armbian main repo +> X-Git-Archeology: > recovered message: > * Removed duplicate patch which has added to main armbian repository +> X-Git-Archeology: > recovered message: > * Tidied up regulators for default/next/dev rockchip flavours for xt-q8l-v10, disabling those regulators which are not tied to anything +> X-Git-Archeology: > recovered message: > Enabled voltage regulator to make SPDIF connector work (thus not tested because I have no DAC) +> X-Git-Archeology: > recovered message: > Changed rockchip-dev and rockchip-next config files to enable gpio-ir-receiver module to enable bundled remote IR controller, including kernel patch for keymap +> X-Git-Archeology: > recovered message: > * Enabled back regulator REG7 to allow propert bluetooth functionaly +> X-Git-Archeology: > recovered message: > * Minor changes to u-boot device tree for xt-q8l-v10 +> X-Git-Archeology: > recovered message: > Added patch to set act8846 SIPC to correctly reboot the device (thus require some power-hold at reboot to make reboot fully working) +> X-Git-Archeology: > recovered message: > * Fixed u-boot device tree +> X-Git-Archeology: > recovered message: > * Added configuration bits to support TPL in u-boot for xt-q8l-v10 (TPL is thrown away though) to allow faster reboot times and achieve a working reset feature activating power hold gpio pin as soon as possible. gpio pin is hardwired into spl_board_init() u-boot code because it is not possible to let it work via device tree +> X-Git-Archeology: > recovered message: > Fixed OTG USB port in u-boot, allowing devices detection and booting +> X-Git-Archeology: > recovered message: > Added proper vbus-supply properties for USB controllers in u-boot dts, so u-boot activates USB vbus itself +> X-Git-Archeology: > recovered message: > * Fixed dts makefile patching for next and dev rockchip kernel +> X-Git-Archeology: > recovered message: > * Fixed fdt_file renamed to fdtfile in armbianEnv.txt +> X-Git-Archeology: > recovered message: > * Changed xt-q8l-v10 board config as per recomendations +> X-Git-Archeology: > recovered message: > * Moved xt-q8l-v10 configuration to CSC +> X-Git-Archeology: > recovered message: > Restored linux-rockchip-* configurations, enabled brcmfmac driver, GPIO remote controller driver and lirc kernel compatibility interface +> X-Git-Archeology: > recovered message: > Polished a bit rockchip.conf +> X-Git-Archeology: > recovered message: > * Add patch to brcmfmac driver to search for ap6330 firmware +> X-Git-Archeology: > recovered message: > Removed copy-work from rockchip.conf about ap6330 firmware for xt-q8l-v10 and tidied up +> X-Git-Archeology: > recovered message: > Avoid using brcm_patchram_plus in ap6330-bluetooth-service putting proper firmware file in /etc/firmware for hciattach do firmware uploading itself +> X-Git-Archeology: > recovered message: > * Fixed bcm4330 bluetooth firmware linking for hciattach used by ap6330-bluetooth.service +> X-Git-Archeology: > recovered message: > * Removed foreign test patches from xt-q8l-v10 u-boot directory +> X-Git-Archeology: - Revision 60b4166a8a9efe74c76bf75246cd297ccf4cf7ca: https://github.com/armbian/build/commit/60b4166a8a9efe74c76bf75246cd297ccf4cf7ca +> X-Git-Archeology: Date: Thu, 22 Nov 2018 07:04:19 +0100 +> X-Git-Archeology: From: Paolo +> X-Git-Archeology: Subject: Add rk3288 xt-q8l-v10 CSC board (#1158) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 150ac0c2afa147d9e3b036c8ecd8238fe5648cf3: https://github.com/armbian/build/commit/150ac0c2afa147d9e3b036c8ecd8238fe5648cf3 +> X-Git-Archeology: Date: Tue, 19 Nov 2019 23:25:39 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Remove K<4, change branches, new features (#1586) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 0cdffb29b07305209efb12cf3b5ac6032d3a1153: https://github.com/armbian/build/commit/0cdffb29b07305209efb12cf3b5ac6032d3a1153 +> X-Git-Archeology: Date: Wed, 24 Mar 2021 19:01:53 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Renaming DEV branch to EDGE (#2704) +> X-Git-Archeology: +> X-Git-Archeology: - Revision c0001d566b3770dae722c47180dcb942bed7006a: https://github.com/armbian/build/commit/c0001d566b3770dae722c47180dcb942bed7006a +> X-Git-Archeology: Date: Wed, 14 Dec 2022 01:43:31 +0100 +> X-Git-Archeology: From: Igor Pecovnik +> X-Git-Archeology: Subject: Bump bcm, imx, mvebu64 and xu4 EDGE to 6.1.y (#4560) +> X-Git-Archeology: +> X-Git-Archeology: - Revision 562d96128ba6a511a8a06c0f4d29946ab80b8969: https://github.com/armbian/build/commit/562d96128ba6a511a8a06c0f4d29946ab80b8969 +> X-Git-Archeology: Date: Tue, 26 Dec 2023 16:45:30 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: consolidate rk322x and rockchip 32 bit families +> X-Git-Archeology: +> X-Git-Archeology: - Revision 54628d7d3e11824e560b77e905f69d52feb0fbd0: https://github.com/armbian/build/commit/54628d7d3e11824e560b77e905f69d52feb0fbd0 +> X-Git-Archeology: Date: Wed, 01 Jan 2025 19:38:55 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: rockchip: bump edge kernel to 6.13-rc5 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 7c55b4fce91f38383398a7498dde1c6d69a70495: https://github.com/armbian/build/commit/7c55b4fce91f38383398a7498dde1c6d69a70495 +> X-Git-Archeology: Date: Wed, 26 Mar 2025 22:23:29 +0100 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32bit edge kernel to v6.14 +> X-Git-Archeology: +> X-Git-Archeology: - Revision cc4cb72d4069147ea1b5e6936de3b49aace21967: https://github.com/armbian/build/commit/cc4cb72d4069147ea1b5e6936de3b49aace21967 +> X-Git-Archeology: Date: Tue, 03 Jun 2025 09:53:37 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip 32 bit edge kernel to 6.15 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 96fe7dee19eaec6d9c5159a5cc50e33ca9c96096: https://github.com/armbian/build/commit/96fe7dee19eaec6d9c5159a5cc50e33ca9c96096 +> X-Git-Archeology: Date: Mon, 28 Jul 2025 20:45:52 +0800 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: bump rockchip edge to kernel 6.16 +> X-Git-Archeology: +> X-Git-Archeology: - Revision 29317c6f7e33f2cc509acc0da23b615a7d9d8c31: https://github.com/armbian/build/commit/29317c6f7e33f2cc509acc0da23b615a7d9d8c31 +> X-Git-Archeology: Date: Thu, 18 Sep 2025 22:48:06 +0200 +> X-Git-Archeology: From: Paolo Sabatino +> X-Git-Archeology: Subject: update rockchip 32 bit edge kernel to 6.17 +> X-Git-Archeology: +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -index a907d7b06..ec71996c7 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -619,13 +619,17 @@ BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); - BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); - BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); +@@ -633,13 +633,17 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt"); + /* per-board firmware binaries */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin"); +/* AMPAK */ +BRCMF_FW_DEF(AP6330, "brcmfmac-ap6330-sdio"); @@ -21,3 +184,6 @@ index a907d7b06..ec71996c7 100644 BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), +-- +Armbian + diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-esp8089.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-esp8089.patch index 27e25f514..910fc5622 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-esp8089.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-esp8089.patch @@ -1,106 +1,73 @@ -From 2d6165af6e9d5ed5026cdf250536c0a00d84fd75 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 1 Oct 2022 12:43:53 +0000 -Subject: [PATCH] add esp8089 kernel driver +Subject: add esp8089 kernel driver --- - drivers/net/wireless/Kconfig | 1 + - drivers/net/wireless/Makefile | 1 + - drivers/net/wireless/esp8089/.gitignore | 7 + - drivers/net/wireless/esp8089/Kconfig | 13 + - drivers/net/wireless/esp8089/LICENSE | 340 +++ - drivers/net/wireless/esp8089/Makefile | 7 + - drivers/net/wireless/esp8089/Makefile.old | 99 + - drivers/net/wireless/esp8089/README.md | 31 + - drivers/net/wireless/esp8089/esp_ctrl.c | 801 ++++++ - drivers/net/wireless/esp8089/esp_ctrl.h | 58 + - drivers/net/wireless/esp8089/esp_debug.c | 297 ++ - drivers/net/wireless/esp8089/esp_debug.h | 101 + - drivers/net/wireless/esp8089/esp_ext.c | 542 ++++ - drivers/net/wireless/esp8089/esp_ext.h | 100 + - drivers/net/wireless/esp8089/esp_file.c | 258 ++ - drivers/net/wireless/esp8089/esp_file.h | 43 + - drivers/net/wireless/esp8089/esp_init_data.h | 7 + - drivers/net/wireless/esp8089/esp_io.c | 639 +++++ - drivers/net/wireless/esp8089/esp_mac80211.c | 1727 ++++++++++++ - drivers/net/wireless/esp8089/esp_mac80211.h | 38 + - drivers/net/wireless/esp8089/esp_main.c | 263 ++ - drivers/net/wireless/esp8089/esp_path.h | 6 + - drivers/net/wireless/esp8089/esp_pub.h | 222 ++ - drivers/net/wireless/esp8089/esp_sif.h | 207 ++ - drivers/net/wireless/esp8089/esp_sip.c | 2418 +++++++++++++++++ - drivers/net/wireless/esp8089/esp_sip.h | 171 ++ - drivers/net/wireless/esp8089/esp_utils.c | 262 ++ - drivers/net/wireless/esp8089/esp_utils.h | 41 + - drivers/net/wireless/esp8089/esp_version.h | 1 + - drivers/net/wireless/esp8089/esp_wl.h | 63 + - drivers/net/wireless/esp8089/esp_wmac.h | 92 + - .../wireless/esp8089/firmware/LICENSE-2.0.txt | 203 ++ - drivers/net/wireless/esp8089/sdio_sif_esp.c | 811 ++++++ - drivers/net/wireless/esp8089/sip2_common.h | 475 ++++ - .../net/wireless/esp8089/slc_host_register.h | 271 ++ - 35 files changed, 10616 insertions(+) - create mode 100644 drivers/net/wireless/esp8089/.gitignore - create mode 100644 drivers/net/wireless/esp8089/Kconfig - create mode 100644 drivers/net/wireless/esp8089/LICENSE - create mode 100644 drivers/net/wireless/esp8089/Makefile - create mode 100644 drivers/net/wireless/esp8089/Makefile.old - create mode 100644 drivers/net/wireless/esp8089/README.md - create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.c - create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.h - create mode 100644 drivers/net/wireless/esp8089/esp_debug.c - create mode 100644 drivers/net/wireless/esp8089/esp_debug.h - create mode 100644 drivers/net/wireless/esp8089/esp_ext.c - create mode 100644 drivers/net/wireless/esp8089/esp_ext.h - create mode 100644 drivers/net/wireless/esp8089/esp_file.c - create mode 100644 drivers/net/wireless/esp8089/esp_file.h - create mode 100644 drivers/net/wireless/esp8089/esp_init_data.h - create mode 100644 drivers/net/wireless/esp8089/esp_io.c - create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.c - create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.h - create mode 100644 drivers/net/wireless/esp8089/esp_main.c - create mode 100644 drivers/net/wireless/esp8089/esp_path.h - create mode 100644 drivers/net/wireless/esp8089/esp_pub.h - create mode 100644 drivers/net/wireless/esp8089/esp_sif.h - create mode 100644 drivers/net/wireless/esp8089/esp_sip.c - create mode 100644 drivers/net/wireless/esp8089/esp_sip.h - create mode 100644 drivers/net/wireless/esp8089/esp_utils.c - create mode 100644 drivers/net/wireless/esp8089/esp_utils.h - create mode 100644 drivers/net/wireless/esp8089/esp_version.h - create mode 100644 drivers/net/wireless/esp8089/esp_wl.h - create mode 100644 drivers/net/wireless/esp8089/esp_wmac.h - create mode 100644 drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt - create mode 100644 drivers/net/wireless/esp8089/sdio_sif_esp.c - create mode 100644 drivers/net/wireless/esp8089/sip2_common.h - create mode 100644 drivers/net/wireless/esp8089/slc_host_register.h + drivers/net/wireless/Kconfig | 1 + + drivers/net/wireless/Makefile | 1 + + drivers/net/wireless/esp8089/.gitignore | 7 + + drivers/net/wireless/esp8089/Kconfig | 13 + + drivers/net/wireless/esp8089/LICENSE | 340 ++ + drivers/net/wireless/esp8089/Makefile | 7 + + drivers/net/wireless/esp8089/Makefile.old | 99 + + drivers/net/wireless/esp8089/README.md | 31 + + drivers/net/wireless/esp8089/esp_ctrl.c | 801 +++ + drivers/net/wireless/esp8089/esp_ctrl.h | 58 + + drivers/net/wireless/esp8089/esp_debug.c | 297 ++ + drivers/net/wireless/esp8089/esp_debug.h | 101 + + drivers/net/wireless/esp8089/esp_ext.c | 542 +++ + drivers/net/wireless/esp8089/esp_ext.h | 100 + + drivers/net/wireless/esp8089/esp_file.c | 258 + + drivers/net/wireless/esp8089/esp_file.h | 43 + + drivers/net/wireless/esp8089/esp_init_data.h | 7 + + drivers/net/wireless/esp8089/esp_io.c | 639 +++ + drivers/net/wireless/esp8089/esp_mac80211.c | 1731 +++++++ + drivers/net/wireless/esp8089/esp_mac80211.h | 38 + + drivers/net/wireless/esp8089/esp_main.c | 263 + + drivers/net/wireless/esp8089/esp_path.h | 6 + + drivers/net/wireless/esp8089/esp_pub.h | 222 + + drivers/net/wireless/esp8089/esp_sif.h | 207 + + drivers/net/wireless/esp8089/esp_sip.c | 2420 ++++++++++ + drivers/net/wireless/esp8089/esp_sip.h | 171 + + drivers/net/wireless/esp8089/esp_utils.c | 262 + + drivers/net/wireless/esp8089/esp_utils.h | 41 + + drivers/net/wireless/esp8089/esp_version.h | 1 + + drivers/net/wireless/esp8089/esp_wl.h | 63 + + drivers/net/wireless/esp8089/esp_wmac.h | 92 + + drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt | 203 + + drivers/net/wireless/esp8089/sdio_sif_esp.c | 824 ++++ + drivers/net/wireless/esp8089/sip2_common.h | 475 ++ + drivers/net/wireless/esp8089/slc_host_register.h | 271 ++ + 35 files changed, 10635 insertions(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig -index cb1c15012dd0..de5e37846397 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig -@@ -37,6 +37,7 @@ source "drivers/net/wireless/st/Kconfig" - source "drivers/net/wireless/ti/Kconfig" +@@ -40,6 +40,7 @@ source "drivers/net/wireless/rtl8189fs/Kconfig" + source "drivers/net/wireless/rtl8189es/Kconfig" source "drivers/net/wireless/zydas/Kconfig" source "drivers/net/wireless/quantenna/Kconfig" +source "drivers/net/wireless/esp8089/Kconfig" - config PCMCIA_RAYCS - tristate "Aviator/Raytheon 2.4GHz wireless support" + source "drivers/net/wireless/virtual/Kconfig" + diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile -index a61cf6c90343..92ffd2cef51c 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile -@@ -22,6 +22,7 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ +@@ -21,6 +21,7 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ obj-$(CONFIG_WLAN_VENDOR_ST) += st/ obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ +obj-$(CONFIG_ESP8089) += esp8089/ - # 16-bit wireless PCMCIA client drivers - obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o + obj-$(CONFIG_WLAN) += virtual/ + obj-$(CONFIG_RTL8189ES) += rtl8189es/ diff --git a/drivers/net/wireless/esp8089/.gitignore b/drivers/net/wireless/esp8089/.gitignore new file mode 100644 -index 000000000000..eae6529085d0 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/.gitignore @@ -0,0 +1,7 @@ @@ -113,7 +80,7 @@ index 000000000000..eae6529085d0 +*.mod.c diff --git a/drivers/net/wireless/esp8089/Kconfig b/drivers/net/wireless/esp8089/Kconfig new file mode 100644 -index 000000000000..8db1fc54712d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Kconfig @@ -0,0 +1,13 @@ @@ -132,7 +99,7 @@ index 000000000000..8db1fc54712d + DebugFS support for ESP8089 diff --git a/drivers/net/wireless/esp8089/LICENSE b/drivers/net/wireless/esp8089/LICENSE new file mode 100644 -index 000000000000..d6a93266f748 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/LICENSE @@ -0,0 +1,340 @@ @@ -478,7 +445,7 @@ index 000000000000..d6a93266f748 + diff --git a/drivers/net/wireless/esp8089/Makefile b/drivers/net/wireless/esp8089/Makefile new file mode 100644 -index 000000000000..36decfd20ecd +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Makefile @@ -0,0 +1,7 @@ @@ -491,7 +458,7 @@ index 000000000000..36decfd20ecd +obj-$(CONFIG_ESP8089) := esp8089.o diff --git a/drivers/net/wireless/esp8089/Makefile.old b/drivers/net/wireless/esp8089/Makefile.old new file mode 100644 -index 000000000000..b7b1a47b159c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/Makefile.old @@ -0,0 +1,99 @@ @@ -596,7 +563,7 @@ index 000000000000..b7b1a47b159c +.PHONY: all modules clean install config_check diff --git a/drivers/net/wireless/esp8089/README.md b/drivers/net/wireless/esp8089/README.md new file mode 100644 -index 000000000000..56b40db272f3 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/README.md @@ -0,0 +1,31 @@ @@ -633,7 +600,7 @@ index 000000000000..56b40db272f3 +To load the module. diff --git a/drivers/net/wireless/esp8089/esp_ctrl.c b/drivers/net/wireless/esp8089/esp_ctrl.c new file mode 100644 -index 000000000000..a19d2437dd82 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ctrl.c @@ -0,0 +1,801 @@ @@ -1440,7 +1407,7 @@ index 000000000000..a19d2437dd82 +} diff --git a/drivers/net/wireless/esp8089/esp_ctrl.h b/drivers/net/wireless/esp8089/esp_ctrl.h new file mode 100644 -index 000000000000..29c18caa9ede +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ctrl.h @@ -0,0 +1,58 @@ @@ -1504,7 +1471,7 @@ index 000000000000..29c18caa9ede +#endif /* _ESP_CTRL_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_debug.c b/drivers/net/wireless/esp8089/esp_debug.c new file mode 100644 -index 000000000000..5ce8fd2ebd6b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_debug.c @@ -0,0 +1,297 @@ @@ -1807,7 +1774,7 @@ index 000000000000..5ce8fd2ebd6b +#endif /* HOST_RC */ diff --git a/drivers/net/wireless/esp8089/esp_debug.h b/drivers/net/wireless/esp8089/esp_debug.h new file mode 100644 -index 000000000000..bab695d34bfb +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_debug.h @@ -0,0 +1,101 @@ @@ -1914,7 +1881,7 @@ index 000000000000..bab695d34bfb +#endif /* _DEBUG_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_ext.c b/drivers/net/wireless/esp8089/esp_ext.c new file mode 100644 -index 000000000000..541f27a6853f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ext.c @@ -0,0 +1,542 @@ @@ -2462,7 +2429,7 @@ index 000000000000..541f27a6853f +#endif /* USE_EXT_GPIO */ diff --git a/drivers/net/wireless/esp8089/esp_ext.h b/drivers/net/wireless/esp8089/esp_ext.h new file mode 100644 -index 000000000000..0eeba4d22111 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_ext.h @@ -0,0 +1,100 @@ @@ -2568,7 +2535,7 @@ index 000000000000..0eeba4d22111 +#endif /* USE_EXT_GPIO */ diff --git a/drivers/net/wireless/esp8089/esp_file.c b/drivers/net/wireless/esp8089/esp_file.c new file mode 100644 -index 000000000000..ea702f010eec +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_file.c @@ -0,0 +1,258 @@ @@ -2832,7 +2799,7 @@ index 000000000000..ea702f010eec +} diff --git a/drivers/net/wireless/esp8089/esp_file.h b/drivers/net/wireless/esp8089/esp_file.h new file mode 100644 -index 000000000000..5ba39c626baa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_file.h @@ -0,0 +1,43 @@ @@ -2881,7 +2848,7 @@ index 000000000000..5ba39c626baa +#endif /* _ESP_FILE_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_init_data.h b/drivers/net/wireless/esp8089/esp_init_data.h new file mode 100644 -index 000000000000..16f451affd1e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_init_data.h @@ -0,0 +1,7 @@ @@ -2894,7 +2861,7 @@ index 000000000000..16f451affd1e +0 }; diff --git a/drivers/net/wireless/esp8089/esp_io.c b/drivers/net/wireless/esp8089/esp_io.c new file mode 100644 -index 000000000000..6c5c01aad4e5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_io.c @@ -0,0 +1,639 @@ @@ -3539,7 +3506,7 @@ index 000000000000..6c5c01aad4e5 +} diff --git a/drivers/net/wireless/esp8089/esp_mac80211.c b/drivers/net/wireless/esp8089/esp_mac80211.c new file mode 100644 -index 000000000000..14186365fdd4 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_mac80211.c @@ -0,0 +1,1731 @@ @@ -5276,7 +5243,7 @@ index 000000000000..14186365fdd4 +} diff --git a/drivers/net/wireless/esp8089/esp_mac80211.h b/drivers/net/wireless/esp8089/esp_mac80211.h new file mode 100644 -index 000000000000..699b27dcadd1 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_mac80211.h @@ -0,0 +1,38 @@ @@ -5320,7 +5287,7 @@ index 000000000000..699b27dcadd1 +#endif /* _ESP_MAC80211_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_main.c b/drivers/net/wireless/esp8089/esp_main.c new file mode 100644 -index 000000000000..404e0d7a6f54 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_main.c @@ -0,0 +1,263 @@ @@ -5589,7 +5556,7 @@ index 000000000000..404e0d7a6f54 +#endif /* !FPGA_DEBUG */ diff --git a/drivers/net/wireless/esp8089/esp_path.h b/drivers/net/wireless/esp8089/esp_path.h new file mode 100644 -index 000000000000..1ceb14bc3b15 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_path.h @@ -0,0 +1,6 @@ @@ -5601,7 +5568,7 @@ index 000000000000..1ceb14bc3b15 +#endif /* _ESP_PATH_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_pub.h b/drivers/net/wireless/esp8089/esp_pub.h new file mode 100644 -index 000000000000..0d3ad3655cf4 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_pub.h @@ -0,0 +1,222 @@ @@ -5829,7 +5796,7 @@ index 000000000000..0d3ad3655cf4 +#endif /* _ESP_PUB_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_sif.h b/drivers/net/wireless/esp8089/esp_sif.h new file mode 100644 -index 000000000000..2d49f2bc8035 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sif.h @@ -0,0 +1,207 @@ @@ -6042,7 +6009,7 @@ index 000000000000..2d49f2bc8035 +#endif /* _ESP_SIF_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_sip.c b/drivers/net/wireless/esp8089/esp_sip.c new file mode 100644 -index 000000000000..6602a1e22ab1 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sip.c @@ -0,0 +1,2420 @@ @@ -8468,7 +8435,7 @@ index 000000000000..6602a1e22ab1 +#endif /* FPGA_TXDATA */ diff --git a/drivers/net/wireless/esp8089/esp_sip.h b/drivers/net/wireless/esp8089/esp_sip.h new file mode 100644 -index 000000000000..95cc42989b2c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_sip.h @@ -0,0 +1,171 @@ @@ -8645,7 +8612,7 @@ index 000000000000..95cc42989b2c +#endif diff --git a/drivers/net/wireless/esp8089/esp_utils.c b/drivers/net/wireless/esp8089/esp_utils.c new file mode 100644 -index 000000000000..8b188de79b2c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_utils.c @@ -0,0 +1,262 @@ @@ -8913,7 +8880,7 @@ index 000000000000..8b188de79b2c +} diff --git a/drivers/net/wireless/esp8089/esp_utils.h b/drivers/net/wireless/esp8089/esp_utils.h new file mode 100644 -index 000000000000..ed16d9ca0a65 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_utils.h @@ -0,0 +1,41 @@ @@ -8960,14 +8927,14 @@ index 000000000000..ed16d9ca0a65 +#endif diff --git a/drivers/net/wireless/esp8089/esp_version.h b/drivers/net/wireless/esp8089/esp_version.h new file mode 100644 -index 000000000000..481d98841fc2 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_version.h @@ -0,0 +1 @@ +#define DRIVER_VER 0xbdf5087c3debll diff --git a/drivers/net/wireless/esp8089/esp_wl.h b/drivers/net/wireless/esp8089/esp_wl.h new file mode 100644 -index 000000000000..e3e62a83d505 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_wl.h @@ -0,0 +1,63 @@ @@ -9036,7 +9003,7 @@ index 000000000000..e3e62a83d505 +#endif /* _ESP_WL_H_ */ diff --git a/drivers/net/wireless/esp8089/esp_wmac.h b/drivers/net/wireless/esp8089/esp_wmac.h new file mode 100644 -index 000000000000..72d13cbfc0e5 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/esp_wmac.h @@ -0,0 +1,92 @@ @@ -9134,7 +9101,7 @@ index 000000000000..72d13cbfc0e5 +#endif /* _ESP_WMAC_H_ */ diff --git a/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt new file mode 100644 -index 000000000000..0dd35c82a001 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt @@ -0,0 +1,203 @@ @@ -9343,7 +9310,7 @@ index 000000000000..0dd35c82a001 + limitations under the License. diff --git a/drivers/net/wireless/esp8089/sdio_sif_esp.c b/drivers/net/wireless/esp8089/sdio_sif_esp.c new file mode 100644 -index 000000000000..2bd2c63f5388 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/sdio_sif_esp.c @@ -0,0 +1,824 @@ @@ -10173,7 +10140,7 @@ index 000000000000..2bd2c63f5388 +module_exit(esp_sdio_exit); diff --git a/drivers/net/wireless/esp8089/sip2_common.h b/drivers/net/wireless/esp8089/sip2_common.h new file mode 100644 -index 000000000000..d46e87589b0b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/sip2_common.h @@ -0,0 +1,475 @@ @@ -10654,7 +10621,7 @@ index 000000000000..d46e87589b0b +#endif /* _SIP_COMMON_H_ */ diff --git a/drivers/net/wireless/esp8089/slc_host_register.h b/drivers/net/wireless/esp8089/slc_host_register.h new file mode 100644 -index 000000000000..2cdb2c856d15 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/net/wireless/esp8089/slc_host_register.h @@ -0,0 +1,271 @@ @@ -10930,5 +10897,5 @@ index 000000000000..2cdb2c856d15 + +#endif // SLC_HOST_REGISTER_H_INCLUDED -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-ssv6051.patch b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-ssv6051.patch index 954791d52..ae25f2465 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-ssv6051.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.armbian/wifi-driver-ssv6051.patch @@ -32,7 +32,7 @@ Subject: add ssv6xxx wifi driver drivers/net/wireless/ssv6051/smac/ampdu.h | 215 + drivers/net/wireless/ssv6051/smac/ap.c | 598 + drivers/net/wireless/ssv6051/smac/ap.h | 41 + - drivers/net/wireless/ssv6051/smac/dev.c | 3881 ++ + drivers/net/wireless/ssv6051/smac/dev.c | 3884 ++ drivers/net/wireless/ssv6051/smac/dev.h | 445 + drivers/net/wireless/ssv6051/smac/dev_tbl.h | 141 + drivers/net/wireless/ssv6051/smac/drv_comm.h | 61 + @@ -64,7 +64,7 @@ Subject: add ssv6xxx wifi driver drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.c | 1765 + drivers/net/wireless/ssv6051/ssvdevice/ssv_cmd.h | 50 + drivers/net/wireless/ssv6051/ssvdevice/ssvdevice.c | 256 + - 60 files changed, 48982 insertions(+) + 60 files changed, 48985 insertions(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 111111111111..222222222222 100644 diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0001-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0001-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch index ab1531808..e5c39348b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0001-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0001-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch @@ -1,7 +1,7 @@ -From 1efb0ab46aeddce29687b942b118a5338d249c61 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Sat, 13 Apr 2019 05:45:18 +0000 -Subject: [PATCH 001/108] LOCAL: arm64: fix Kodi sysinfo CPU information +Subject: LOCAL: arm64: fix Kodi sysinfo CPU information This allows the CPU information to show in the Kodi sysinfo screen, e.g. @@ -13,7 +13,7 @@ Signed-off-by: Christian Hewitt 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c -index ba834909a28b..4384c894bb0f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -223,9 +223,8 @@ static int c_show(struct seq_file *m, void *v) @@ -29,5 +29,5 @@ index ba834909a28b..4384c894bb0f 100644 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000UL/HZ), -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0002-LOCAL-arm64-dts-rockchip-rock5b-disable-sdio-node.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0002-LOCAL-arm64-dts-rockchip-rock5b-disable-sdio-node.patch index 1331f7a37..29126c1fd 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0002-LOCAL-arm64-dts-rockchip-rock5b-disable-sdio-node.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0002-LOCAL-arm64-dts-rockchip-rock5b-disable-sdio-node.patch @@ -1,8 +1,7 @@ -From 9f9d1e1535f8004247aca088d83f964c66a81155 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Wed, 16 Jul 2025 11:03:09 +0000 -Subject: [PATCH 002/108] LOCAL: arm64: dts: rockchip: rock5b: disable sdio - node +Subject: LOCAL: arm64: dts: rockchip: rock5b: disable sdio node Radxa ships an M2 compatible WiFi module with PCIe wired RTL8852BE chip, so leave the SDIO node described in device-tree, but disable @@ -26,7 +25,7 @@ Signed-off-by: Christian Hewitt 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index 9407a7c9910a..ba82c89201ea 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts @@ -27,7 +27,7 @@ &sdio { @@ -39,5 +38,5 @@ index 9407a7c9910a..ba82c89201ea 100644 &uart6 { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0003-LOCAL-drm-rockchip-vop2-rk3588-change-Esmart-Cluster.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0003-LOCAL-drm-rockchip-vop2-rk3588-change-Esmart-Cluster.patch index 4730e8690..005868a66 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0003-LOCAL-drm-rockchip-vop2-rk3588-change-Esmart-Cluster.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0003-LOCAL-drm-rockchip-vop2-rk3588-change-Esmart-Cluster.patch @@ -1,8 +1,7 @@ -From 5f3225643ae70aa456d1cc3ea4b42a2a1556ad0d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Wed, 16 Jul 2025 05:09:07 +0000 -Subject: [PATCH 003/108] LOCAL: drm/rockchip: vop2: rk3588: change - Esmart/Cluster ordering +Subject: LOCAL: drm/rockchip: vop2: rk3588: change Esmart/Cluster ordering Order Esmart planes before Cluster planes so Kodi (which currently lacks the ability to dymanically order planes using zpos) can show @@ -11,11 +10,11 @@ the OSD on-top of Video rather then behind. Suggested-by: Jonas Karlman Signed-off-by: Christian Hewitt --- - drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 136 +++++++++---------- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 136 +++++----- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c -index 45c5e3987813..42a4833a90a3 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -1119,6 +1119,74 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = { @@ -169,5 +168,5 @@ index 45c5e3987813..42a4833a90a3 100644 }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0004-FROMGIT-6.18-media-uapi-HEVC-Add-v4l2_ctrl_hevc_ext_.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0004-FROMGIT-6.18-media-uapi-HEVC-Add-v4l2_ctrl_hevc_ext_.patch index 7bf384081..929adddca 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0004-FROMGIT-6.18-media-uapi-HEVC-Add-v4l2_ctrl_hevc_ext_.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0004-FROMGIT-6.18-media-uapi-HEVC-Add-v4l2_ctrl_hevc_ext_.patch @@ -1,7 +1,7 @@ -From ba2f7791641e70ab3a6ad8605622a46a99f4b667 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Thu, 24 Jul 2025 14:10:18 -0400 -Subject: [PATCH 004/108] FROMGIT(6.18): media: uapi: HEVC: Add +Subject: FROMGIT(6.18): media: uapi: HEVC: Add v4l2_ctrl_hevc_ext_sps_[ls]t_rps controls Some hardware (e.g.: Rockchip's rk3588 hevc decoder) need the @@ -11,13 +11,13 @@ Add controls to provide it as the raw data form the stream. Signed-off-by: Detlev Casanova --- - .../media/v4l/ext-ctrls-codec-stateless.rst | 114 ++++++++++++++++++ - .../media/v4l/vidioc-queryctrl.rst | 12 ++ - .../media/videodev2.h.rst.exceptions | 2 + + Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst | 114 ++++++++++ + Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst | 12 + + Documentation/userspace-api/media/videodev2.h.rst.exceptions | 2 + 3 files changed, 128 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst -index 0da635691fdc..bb6772cf3cee 100644 +index 111111111111..222222222222 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -2958,6 +2958,120 @@ This structure contains all loop filter related parameters. See sections @@ -142,7 +142,7 @@ index 0da635691fdc..bb6772cf3cee 100644 ``V4L2_CID_STATELESS_AV1_SEQUENCE (struct)`` diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst -index 3549417c7feb..128c044d2e3c 100644 +index 111111111111..222222222222 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -523,6 +523,18 @@ See also the examples in :ref:`control`. @@ -165,7 +165,7 @@ index 3549417c7feb..128c044d2e3c 100644 - n/a - n/a diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions -index 35d3456cc812..1663fdf8444c 100644 +index 111111111111..222222222222 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type` @@ -178,5 +178,5 @@ index 35d3456cc812..1663fdf8444c 100644 replace symbol V4L2_CTRL_TYPE_RECT :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type` -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0005-FROMGIT-6.18-media-v4l2-ctrls-Add-hevc_ext_sps_-ls-t.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0005-FROMGIT-6.18-media-v4l2-ctrls-Add-hevc_ext_sps_-ls-t.patch index 4f62ed9f5..d6ce83b9f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0005-FROMGIT-6.18-media-v4l2-ctrls-Add-hevc_ext_sps_-ls-t.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0005-FROMGIT-6.18-media-v4l2-ctrls-Add-hevc_ext_sps_-ls-t.patch @@ -1,8 +1,7 @@ -From 09f7bf034d1a5608cd1992db1e582c1352a10dbf Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Thu, 24 Jul 2025 14:10:19 -0400 -Subject: [PATCH 005/108] FROMGIT(6.18): media: v4l2-ctrls: Add - hevc_ext_sps_[ls]t_rps controls +Subject: FROMGIT(6.18): media: v4l2-ctrls: Add hevc_ext_sps_[ls]t_rps controls The vdpu381 decoder found on newer Rockchip SoC need the information from the long term and short term ref pic sets from the SPS. @@ -18,14 +17,14 @@ It is the role of the drivers to calculate the reference sets values. Signed-off-by: Detlev Casanova --- - drivers/media/v4l2-core/v4l2-ctrls-core.c | 18 +++++++ - drivers/media/v4l2-core/v4l2-ctrls-defs.c | 10 ++++ - include/uapi/linux/v4l2-controls.h | 61 +++++++++++++++++++++++ + drivers/media/v4l2-core/v4l2-ctrls-core.c | 18 +++ + drivers/media/v4l2-core/v4l2-ctrls-defs.c | 10 ++ + include/uapi/linux/v4l2-controls.h | 61 ++++++++++ include/uapi/linux/videodev2.h | 2 + 4 files changed, 91 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c -index 98b960775e87..142e26134ef0 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -418,6 +418,12 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl) @@ -68,7 +67,7 @@ index 98b960775e87..142e26134ef0 100644 elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); break; diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c -index 1ea52011247a..86c7ee224b66 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -1233,6 +1233,8 @@ const char *v4l2_ctrl_get_name(u32 id) @@ -96,7 +95,7 @@ index 1ea52011247a..86c7ee224b66 100644 *type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR; break; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h -index f836512e9deb..08f869124474 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -2094,6 +2094,8 @@ struct v4l2_ctrl_mpeg2_quantisation { @@ -175,7 +174,7 @@ index f836512e9deb..08f869124474 100644 #define V4L2_CID_COLORIMETRY_CLASS (V4L2_CTRL_CLASS_COLORIMETRY | 1) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h -index 3dd9fa45dde1..a3aa1f8c3894 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1981,6 +1981,8 @@ enum v4l2_ctrl_type { @@ -188,5 +187,5 @@ index 3dd9fa45dde1..a3aa1f8c3894 100644 V4L2_CTRL_TYPE_AV1_SEQUENCE = 0x280, V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY = 0x281, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0006-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu381-Vide.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0006-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu381-Vide.patch index 506e0ada6..d0d87c200 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0006-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu381-Vide.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0006-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu381-Vide.patch @@ -1,8 +1,8 @@ -From fab7fe918af46b99bdd05a9a32c16d488ac8050b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Mon, 23 Jun 2025 12:07:17 -0400 -Subject: [PATCH 006/108] FROMGIT(6.18): arm64: dts: rockchip: Add the vdpu381 - Video Decoders on RK3588 +Subject: FROMGIT(6.18): arm64: dts: rockchip: Add the vdpu381 Video Decoders + on RK3588 Add the vdpu381 Video Decoders to the rk3588-base devicetree. @@ -11,11 +11,11 @@ This also adds the dedicated IOMMU controllers. Signed-off-by: Detlev Casanova --- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 74 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 74 ++++++++++ 1 file changed, 74 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 70f03e68ba55..c1eaff86d5b7 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -1252,6 +1252,70 @@ vepu121_3_mmu: iommu@fdbac800 { @@ -107,5 +107,5 @@ index 70f03e68ba55..c1eaff86d5b7 100644 pinctrl: pinctrl { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0007-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu383-Vide.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0007-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu383-Vide.patch index 1a7620a26..76a8f041f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0007-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu383-Vide.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0007-FROMGIT-6.18-arm64-dts-rockchip-Add-the-vdpu383-Vide.patch @@ -1,8 +1,8 @@ -From f2641077e6f20acb152e9cdb439a0475662538fa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Mon, 23 Jun 2025 12:07:18 -0400 -Subject: [PATCH 007/108] FROMGIT(6.18): arm64: dts: rockchip: Add the vdpu383 - Video Decoder on rk3576 +Subject: FROMGIT(6.18): arm64: dts: rockchip: Add the vdpu383 Video Decoder on + rk3576 Add the vdpu383 Video Decoder variant to the RK3576 device tree. @@ -10,11 +10,11 @@ Also allow using the dedicated SRAM as a pool. Signed-off-by: Detlev Casanova --- - arch/arm64/boot/dts/rockchip/rk3576.dtsi | 36 ++++++++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3576.dtsi | 36 ++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi -index c3cdae8a5494..b99f4bd4c9d9 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -1139,6 +1139,41 @@ gpu: gpu@27800000 { @@ -68,5 +68,5 @@ index c3cdae8a5494..b99f4bd4c9d9 100644 }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0008-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-audio-ou.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0008-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-audio-ou.patch index 46d049ae0..e633dda76 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0008-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-audio-ou.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0008-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-audio-ou.patch @@ -1,8 +1,8 @@ -From ea91dcbaa188e57990e25d381aa855d59ff9f1e9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Anton Kirilov Date: Thu, 7 Aug 2025 18:00:11 +0100 -Subject: [PATCH 008/108] FROMGIT(6.18): arm64: dts: rockchip: Enable HDMI - audio output for NanoPi R6C/R6S +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable HDMI audio output for + NanoPi R6C/R6S Enable HDMI audio output for FriendlyElec NanoPi R6C/R6S boards. @@ -12,7 +12,7 @@ Signed-off-by: Anton Kirilov 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi -index fbf062ec3bf1..2e9d5143476d 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi @@ -251,6 +251,10 @@ hdmi0_out_con: endpoint { @@ -38,5 +38,5 @@ index fbf062ec3bf1..2e9d5143476d 100644 rgmii_phy1: ethernet-phy@1 { compatible = "ethernet-phy-id001c.c916"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0009-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-Na.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0009-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-Na.patch index 7ba18a949..61e2c0e86 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0009-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-Na.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0009-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-Na.patch @@ -1,18 +1,17 @@ -From 4105b87fae397b898acc67b05019c7e8801bc582 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Anton Kirilov Date: Wed, 27 Aug 2025 15:22:10 +0100 -Subject: [PATCH 009/108] FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU - on NanoPi R6C/R6S +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU on NanoPi R6C/R6S Enable the NPU on FriendlyElec NanoPi R6C/R6S boards. Signed-off-by: Anton Kirilov --- - .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 34 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 34 ++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi -index 2e9d5143476d..1b6a59f7cabc 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi @@ -371,6 +371,10 @@ &pd_gpu { @@ -64,5 +63,5 @@ index 2e9d5143476d..1b6a59f7cabc 100644 vref-supply = <&avcc_1v8_s0>; status = "okay"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0010-FROMGIT-6.18-accel-rocket-Add-registers-header.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0010-FROMGIT-6.18-accel-rocket-Add-registers-header.patch index f734350a3..223365c87 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0010-FROMGIT-6.18-accel-rocket-Add-registers-header.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0010-FROMGIT-6.18-accel-rocket-Add-registers-header.patch @@ -1,7 +1,7 @@ -From 2be686c1eaab81a13aa66752adbc2cc939d4ebb0 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:28 +0200 -Subject: [PATCH 010/108] FROMGIT(6.18): accel/rocket: Add registers header +Subject: FROMGIT(6.18): accel/rocket: Add registers header A XML file was generated with the data from the TRM, and then this header was generated from it. @@ -13,13 +13,12 @@ Tested-by: Heiko Stuebner Reviewed-by: Jeff Hugo Signed-off-by: Tomeu Vizoso --- - drivers/accel/rocket/rocket_registers.h | 4404 +++++++++++++++++++++++ + drivers/accel/rocket/rocket_registers.h | 4404 ++++++++++ 1 file changed, 4404 insertions(+) - create mode 100644 drivers/accel/rocket/rocket_registers.h diff --git a/drivers/accel/rocket/rocket_registers.h b/drivers/accel/rocket/rocket_registers.h new file mode 100644 -index 000000000000..9aef614c3470 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_registers.h @@ -0,0 +1,4404 @@ @@ -4428,5 +4427,5 @@ index 000000000000..9aef614c3470 + +#endif /* __ROCKET_REGISTERS_XML__ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0011-FROMGIT-6.18-accel-rocket-Add-a-new-driver-for-Rockc.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0011-FROMGIT-6.18-accel-rocket-Add-a-new-driver-for-Rockc.patch index 8b8813028..7fcf48414 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0011-FROMGIT-6.18-accel-rocket-Add-a-new-driver-for-Rockc.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0011-FROMGIT-6.18-accel-rocket-Add-a-new-driver-for-Rockc.patch @@ -1,8 +1,7 @@ -From c588f2f877ff0081119607f5fbfca3b130d6af66 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:29 +0200 -Subject: [PATCH 011/108] FROMGIT(6.18): accel/rocket: Add a new driver for - Rockchip's NPU +Subject: FROMGIT(6.18): accel/rocket: Add a new driver for Rockchip's NPU This initial version supports the NPU as shipped in the RK3588 SoC and described in the first part of its TRM, in Chapter 36. @@ -18,31 +17,21 @@ Reviewed-by: Jeff Hugo Signed-off-by: Tomeu Vizoso --- Documentation/accel/index.rst | 1 + - Documentation/accel/rocket/index.rst | 19 ++ - MAINTAINERS | 10 + + Documentation/accel/rocket/index.rst | 19 + drivers/accel/Kconfig | 1 + drivers/accel/Makefile | 1 + - drivers/accel/rocket/Kconfig | 24 +++ + drivers/accel/rocket/Kconfig | 24 + drivers/accel/rocket/Makefile | 8 + - drivers/accel/rocket/rocket_core.c | 100 ++++++++++ - drivers/accel/rocket/rocket_core.h | 49 +++++ - drivers/accel/rocket/rocket_device.c | 56 ++++++ - drivers/accel/rocket/rocket_device.h | 28 +++ - drivers/accel/rocket/rocket_drv.c | 261 +++++++++++++++++++++++++++ - drivers/accel/rocket/rocket_drv.h | 23 +++ - 13 files changed, 581 insertions(+) - create mode 100644 Documentation/accel/rocket/index.rst - create mode 100644 drivers/accel/rocket/Kconfig - create mode 100644 drivers/accel/rocket/Makefile - create mode 100644 drivers/accel/rocket/rocket_core.c - create mode 100644 drivers/accel/rocket/rocket_core.h - create mode 100644 drivers/accel/rocket/rocket_device.c - create mode 100644 drivers/accel/rocket/rocket_device.h - create mode 100644 drivers/accel/rocket/rocket_drv.c - create mode 100644 drivers/accel/rocket/rocket_drv.h + drivers/accel/rocket/rocket_core.c | 100 ++++ + drivers/accel/rocket/rocket_core.h | 49 ++ + drivers/accel/rocket/rocket_device.c | 56 ++ + drivers/accel/rocket/rocket_device.h | 28 + + drivers/accel/rocket/rocket_drv.c | 261 ++++++++++ + drivers/accel/rocket/rocket_drv.h | 23 + + 12 files changed, 571 insertions(+) diff --git a/Documentation/accel/index.rst b/Documentation/accel/index.rst -index bc85f26533d8..d8fa332d60a8 100644 +index 111111111111..222222222222 100644 --- a/Documentation/accel/index.rst +++ b/Documentation/accel/index.rst @@ -10,6 +10,7 @@ Compute Accelerators @@ -55,7 +44,7 @@ index bc85f26533d8..d8fa332d60a8 100644 diff --git a/Documentation/accel/rocket/index.rst b/Documentation/accel/rocket/index.rst new file mode 100644 -index 000000000000..70f97bccf100 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/accel/rocket/index.rst @@ -0,0 +1,19 @@ @@ -78,29 +67,8 @@ index 000000000000..70f97bccf100 +Hardware currently supported: + +* RK3588 -diff --git a/MAINTAINERS b/MAINTAINERS -index cd7ff55b5d32..a19231134b01 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -7499,6 +7499,16 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git - F: drivers/accel/ivpu/ - F: include/uapi/drm/ivpu_accel.h - -+DRM ACCEL DRIVER FOR ROCKCHIP NPU -+M: Tomeu Vizoso -+L: dri-devel@lists.freedesktop.org -+S: Supported -+T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -+F: Documentation/accel/rocket/ -+F: Documentation/devicetree/bindings/npu/rockchip,rknn-core.yaml -+F: drivers/accel/rocket/ -+F: include/uapi/drm/rocket_accel.h -+ - DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK - M: Oded Gabbay - L: dri-devel@lists.freedesktop.org diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig -index 5b9490367a39..bb01cebc42bf 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/Kconfig +++ b/drivers/accel/Kconfig @@ -28,5 +28,6 @@ source "drivers/accel/amdxdna/Kconfig" @@ -111,7 +79,7 @@ index 5b9490367a39..bb01cebc42bf 100644 endif diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile -index a301fb6089d4..ffc3fa588666 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/Makefile +++ b/drivers/accel/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_ACCEL_AMDXDNA) += amdxdna/ @@ -122,7 +90,7 @@ index a301fb6089d4..ffc3fa588666 100644 \ No newline at end of file diff --git a/drivers/accel/rocket/Kconfig b/drivers/accel/rocket/Kconfig new file mode 100644 -index 000000000000..43d6cd98ec8e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/Kconfig @@ -0,0 +1,24 @@ @@ -152,7 +120,7 @@ index 000000000000..43d6cd98ec8e + module will be called rocket. diff --git a/drivers/accel/rocket/Makefile b/drivers/accel/rocket/Makefile new file mode 100644 -index 000000000000..abdd75f2492e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/Makefile @@ -0,0 +1,8 @@ @@ -166,7 +134,7 @@ index 000000000000..abdd75f2492e + rocket_drv.o diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c new file mode 100644 -index 000000000000..9be964b5fbae +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_core.c @@ -0,0 +1,100 @@ @@ -272,7 +240,7 @@ index 000000000000..9be964b5fbae +} diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h new file mode 100644 -index 000000000000..660de2d70f7d +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_core.h @@ -0,0 +1,49 @@ @@ -327,7 +295,7 @@ index 000000000000..660de2d70f7d +#endif diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c new file mode 100644 -index 000000000000..b05a0df91d48 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_device.c @@ -0,0 +1,56 @@ @@ -389,7 +357,7 @@ index 000000000000..b05a0df91d48 +} diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h new file mode 100644 -index 000000000000..a5a5857bb199 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_device.h @@ -0,0 +1,28 @@ @@ -423,7 +391,7 @@ index 000000000000..a5a5857bb199 +#endif /* __ROCKET_DEVICE_H__ */ diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c new file mode 100644 -index 000000000000..a5df94f6b125 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_drv.c @@ -0,0 +1,261 @@ @@ -690,7 +658,7 @@ index 000000000000..a5df94f6b125 +MODULE_AUTHOR("Tomeu Vizoso"); diff --git a/drivers/accel/rocket/rocket_drv.h b/drivers/accel/rocket/rocket_drv.h new file mode 100644 -index 000000000000..36b1291b0ead +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_drv.h @@ -0,0 +1,23 @@ @@ -718,5 +686,5 @@ index 000000000000..36b1291b0ead + +#endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0012-FROMGIT-6.18-accel-rocket-Add-IOCTL-for-BO-creation.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0012-FROMGIT-6.18-accel-rocket-Add-IOCTL-for-BO-creation.patch index 43563709e..a99f51652 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0012-FROMGIT-6.18-accel-rocket-Add-IOCTL-for-BO-creation.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0012-FROMGIT-6.18-accel-rocket-Add-IOCTL-for-BO-creation.patch @@ -1,8 +1,7 @@ -From 020bd1d28e4774d8beccc90bbfdad391d535cedc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:30 +0200 -Subject: [PATCH 012/108] FROMGIT(6.18): accel/rocket: Add IOCTL for BO - creation +Subject: FROMGIT(6.18): accel/rocket: Add IOCTL for BO creation This uses the SHMEM DRM helpers and we map right away to the CPU and NPU sides, as all buffers are expected to be accessed from both. @@ -12,18 +11,15 @@ Tested-by: Heiko Stuebner Signed-off-by: Tomeu Vizoso --- drivers/accel/rocket/Makefile | 3 +- - drivers/accel/rocket/rocket_drv.c | 15 +++- + drivers/accel/rocket/rocket_drv.c | 15 +- drivers/accel/rocket/rocket_drv.h | 4 + - drivers/accel/rocket/rocket_gem.c | 125 ++++++++++++++++++++++++++++++ - drivers/accel/rocket/rocket_gem.h | 30 +++++++ - include/uapi/drm/rocket_accel.h | 44 +++++++++++ + drivers/accel/rocket/rocket_gem.c | 125 ++++++++++ + drivers/accel/rocket/rocket_gem.h | 30 +++ + include/uapi/drm/rocket_accel.h | 44 ++++ 6 files changed, 219 insertions(+), 2 deletions(-) - create mode 100644 drivers/accel/rocket/rocket_gem.c - create mode 100644 drivers/accel/rocket/rocket_gem.h - create mode 100644 include/uapi/drm/rocket_accel.h diff --git a/drivers/accel/rocket/Makefile b/drivers/accel/rocket/Makefile -index abdd75f2492e..4deef267f9e1 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/Makefile +++ b/drivers/accel/rocket/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_ACCEL_ROCKET) := rocket.o @@ -34,7 +30,7 @@ index abdd75f2492e..4deef267f9e1 100644 + rocket_drv.o \ + rocket_gem.o diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c -index a5df94f6b125..8b7fbe9226f4 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -5,6 +5,7 @@ @@ -104,7 +100,7 @@ index a5df94f6b125..8b7fbe9226f4 100644 .num_ioctls = ARRAY_SIZE(rocket_drm_driver_ioctls), .fops = &rocket_accel_driver_fops, diff --git a/drivers/accel/rocket/rocket_drv.h b/drivers/accel/rocket/rocket_drv.h -index 36b1291b0ead..2944e0136ab9 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_drv.h +++ b/drivers/accel/rocket/rocket_drv.h @@ -4,6 +4,8 @@ @@ -127,7 +123,7 @@ index 36b1291b0ead..2944e0136ab9 100644 struct rocket_iommu_domain *rocket_iommu_domain_get(struct rocket_file_priv *rocket_priv); diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c new file mode 100644 -index 000000000000..05cf46040865 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_gem.c @@ -0,0 +1,125 @@ @@ -258,7 +254,7 @@ index 000000000000..05cf46040865 +} diff --git a/drivers/accel/rocket/rocket_gem.h b/drivers/accel/rocket/rocket_gem.h new file mode 100644 -index 000000000000..91a1fc09c56c +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_gem.h @@ -0,0 +1,30 @@ @@ -294,7 +290,7 @@ index 000000000000..91a1fc09c56c +#endif diff --git a/include/uapi/drm/rocket_accel.h b/include/uapi/drm/rocket_accel.h new file mode 100644 -index 000000000000..95720702b7c4 +index 000000000000..111111111111 --- /dev/null +++ b/include/uapi/drm/rocket_accel.h @@ -0,0 +1,44 @@ @@ -343,5 +339,5 @@ index 000000000000..95720702b7c4 + +#endif /* __DRM_UAPI_ROCKET_ACCEL_H__ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0013-FROMGIT-6.18-accel-rocket-Add-job-submission-IOCTL.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0013-FROMGIT-6.18-accel-rocket-Add-job-submission-IOCTL.patch index 89cc887ba..d16f2d0ff 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0013-FROMGIT-6.18-accel-rocket-Add-job-submission-IOCTL.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0013-FROMGIT-6.18-accel-rocket-Add-job-submission-IOCTL.patch @@ -1,7 +1,7 @@ -From 2bf294ce12cd8982a7d47137c5fa699cd0c7436c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:31 +0200 -Subject: [PATCH 013/108] FROMGIT(6.18): accel/rocket: Add job submission IOCTL +Subject: FROMGIT(6.18): accel/rocket: Add job submission IOCTL Using the DRM GPU scheduler infrastructure, with a scheduler for each core. @@ -22,15 +22,13 @@ Signed-off-by: Tomeu Vizoso drivers/accel/rocket/rocket_device.h | 2 + drivers/accel/rocket/rocket_drv.c | 14 + drivers/accel/rocket/rocket_drv.h | 3 + - drivers/accel/rocket/rocket_job.c | 636 +++++++++++++++++++++++++++ - drivers/accel/rocket/rocket_job.h | 52 +++ - include/uapi/drm/rocket_accel.h | 64 +++ + drivers/accel/rocket/rocket_job.c | 636 ++++++++++ + drivers/accel/rocket/rocket_job.h | 52 + + include/uapi/drm/rocket_accel.h | 64 + 10 files changed, 802 insertions(+), 1 deletion(-) - create mode 100644 drivers/accel/rocket/rocket_job.c - create mode 100644 drivers/accel/rocket/rocket_job.h diff --git a/drivers/accel/rocket/Makefile b/drivers/accel/rocket/Makefile -index 4deef267f9e1..3713dfe223d6 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/Makefile +++ b/drivers/accel/rocket/Makefile @@ -6,4 +6,5 @@ rocket-y := \ @@ -41,7 +39,7 @@ index 4deef267f9e1..3713dfe223d6 100644 + rocket_gem.o \ + rocket_job.o diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c -index 9be964b5fbae..72fb5e5798fa 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_core.c +++ b/drivers/accel/rocket/rocket_core.c @@ -12,6 +12,7 @@ @@ -83,7 +81,7 @@ index 9be964b5fbae..72fb5e5798fa 100644 void rocket_core_reset(struct rocket_core *core) diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h -index 660de2d70f7d..f6d7382854ca 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_core.h +++ b/drivers/accel/rocket/rocket_core.h @@ -40,6 +40,21 @@ struct rocket_core { @@ -109,7 +107,7 @@ index 660de2d70f7d..f6d7382854ca 100644 int rocket_core_init(struct rocket_core *core); diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c -index b05a0df91d48..46e6ee1e72c5 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_device.c +++ b/drivers/accel/rocket/rocket_device.c @@ -41,6 +41,10 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev, @@ -124,7 +122,7 @@ index b05a0df91d48..46e6ee1e72c5 100644 if (err) return ERR_PTR(err); diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h -index a5a5857bb199..ce662abc01d3 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_device.h +++ b/drivers/accel/rocket/rocket_device.h @@ -15,6 +15,8 @@ @@ -137,7 +135,7 @@ index a5a5857bb199..ce662abc01d3 100644 unsigned int num_cores; }; diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c -index 8b7fbe9226f4..a21aa9aa189b 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -15,6 +15,7 @@ @@ -192,7 +190,7 @@ index 8b7fbe9226f4..a21aa9aa189b 100644 return 0; diff --git a/drivers/accel/rocket/rocket_drv.h b/drivers/accel/rocket/rocket_drv.h -index 2944e0136ab9..f50634935b60 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_drv.h +++ b/drivers/accel/rocket/rocket_drv.h @@ -5,6 +5,7 @@ @@ -214,7 +212,7 @@ index 2944e0136ab9..f50634935b60 100644 struct rocket_iommu_domain *rocket_iommu_domain_get(struct rocket_file_priv *rocket_priv); diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c new file mode 100644 -index 000000000000..e731da15ebff +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_job.c @@ -0,0 +1,636 @@ @@ -856,7 +854,7 @@ index 000000000000..e731da15ebff +} diff --git a/drivers/accel/rocket/rocket_job.h b/drivers/accel/rocket/rocket_job.h new file mode 100644 -index 000000000000..4ae00feec3b9 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/accel/rocket/rocket_job.h @@ -0,0 +1,52 @@ @@ -913,7 +911,7 @@ index 000000000000..4ae00feec3b9 + +#endif diff --git a/include/uapi/drm/rocket_accel.h b/include/uapi/drm/rocket_accel.h -index 95720702b7c4..374f8370ac9d 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/drm/rocket_accel.h +++ b/include/uapi/drm/rocket_accel.h @@ -12,8 +12,10 @@ extern "C" { @@ -997,5 +995,5 @@ index 95720702b7c4..374f8370ac9d 100644 } #endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0014-FROMGIT-6.18-accel-rocket-Add-IOCTLs-for-synchronizi.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0014-FROMGIT-6.18-accel-rocket-Add-IOCTLs-for-synchronizi.patch index 3c2623d4f..acf0a9074 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0014-FROMGIT-6.18-accel-rocket-Add-IOCTLs-for-synchronizi.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0014-FROMGIT-6.18-accel-rocket-Add-IOCTLs-for-synchronizi.patch @@ -1,8 +1,8 @@ -From 2be26c65a61588e349d57fa84461aa7d0e9ce96e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:32 +0200 -Subject: [PATCH 014/108] FROMGIT(6.18): accel/rocket: Add IOCTLs for - synchronizing memory accesses +Subject: FROMGIT(6.18): accel/rocket: Add IOCTLs for synchronizing memory + accesses The NPU cores have their own access to the memory bus, and this isn't cache coherent with the CPUs. @@ -17,14 +17,14 @@ Reviewed-by: Jeff Hugo Tested-by: Heiko Stuebner Signed-off-by: Tomeu Vizoso --- - drivers/accel/rocket/rocket_drv.c | 2 ++ - drivers/accel/rocket/rocket_gem.c | 56 +++++++++++++++++++++++++++++++ - drivers/accel/rocket/rocket_gem.h | 4 +++ - include/uapi/drm/rocket_accel.h | 34 +++++++++++++++++++ + drivers/accel/rocket/rocket_drv.c | 2 + + drivers/accel/rocket/rocket_gem.c | 56 ++++++++++ + drivers/accel/rocket/rocket_gem.h | 4 + + include/uapi/drm/rocket_accel.h | 34 ++++++ 4 files changed, 96 insertions(+) diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c -index a21aa9aa189b..5c0b63f0a8f0 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -134,6 +134,8 @@ static const struct drm_ioctl_desc rocket_drm_driver_ioctls[] = { @@ -37,7 +37,7 @@ index a21aa9aa189b..5c0b63f0a8f0 100644 DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops); diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c -index 05cf46040865..0551e11cc184 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -123,3 +123,59 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * @@ -101,7 +101,7 @@ index 05cf46040865..0551e11cc184 100644 + return 0; +} diff --git a/drivers/accel/rocket/rocket_gem.h b/drivers/accel/rocket/rocket_gem.h -index 91a1fc09c56c..240430334509 100644 +index 111111111111..222222222222 100644 --- a/drivers/accel/rocket/rocket_gem.h +++ b/drivers/accel/rocket/rocket_gem.h @@ -21,6 +21,10 @@ struct drm_gem_object *rocket_gem_create_object(struct drm_device *dev, size_t s @@ -116,7 +116,7 @@ index 91a1fc09c56c..240430334509 100644 struct rocket_gem_object *to_rocket_bo(struct drm_gem_object *obj) { diff --git a/include/uapi/drm/rocket_accel.h b/include/uapi/drm/rocket_accel.h -index 374f8370ac9d..14b2e12b7c49 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/drm/rocket_accel.h +++ b/include/uapi/drm/rocket_accel.h @@ -13,9 +13,13 @@ extern "C" { @@ -171,5 +171,5 @@ index 374f8370ac9d..14b2e12b7c49 100644 * struct drm_rocket_task - A task to be run on the NPU * -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0015-FROMGIT-6.18-dt-bindings-npu-rockchip-rknn-Add-bindi.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0015-FROMGIT-6.18-dt-bindings-npu-rockchip-rknn-Add-bindi.patch index 756878eb9..0fba08700 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0015-FROMGIT-6.18-dt-bindings-npu-rockchip-rknn-Add-bindi.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0015-FROMGIT-6.18-dt-bindings-npu-rockchip-rknn-Add-bindi.patch @@ -1,8 +1,7 @@ -From 2a4747ba6fab4596a99366cea799aa992e262ce6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:33 +0200 -Subject: [PATCH 015/108] FROMGIT(6.18): dt-bindings: npu: rockchip,rknn: Add - bindings +Subject: FROMGIT(6.18): dt-bindings: npu: rockchip,rknn: Add bindings Add the bindings for the Neural Processing Unit IP from Rockchip. @@ -12,13 +11,12 @@ Tested-by: Heiko Stuebner Signed-off-by: Tomeu Vizoso Reviewed-by: Rob Herring (Arm) --- - .../npu/rockchip,rk3588-rknn-core.yaml | 112 ++++++++++++++++++ + Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml | 112 ++++++++++ 1 file changed, 112 insertions(+) - create mode 100644 Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml diff --git a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml new file mode 100644 -index 000000000000..caca2a4903cd +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml @@ -0,0 +1,112 @@ @@ -135,5 +133,5 @@ index 000000000000..caca2a4903cd + }; +... -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0016-FROMGIT-6.18-arm64-dts-rockchip-add-pd_npu-label-for.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0016-FROMGIT-6.18-arm64-dts-rockchip-add-pd_npu-label-for.patch index c14d80296..79ea3a3c3 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0016-FROMGIT-6.18-arm64-dts-rockchip-add-pd_npu-label-for.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0016-FROMGIT-6.18-arm64-dts-rockchip-add-pd_npu-label-for.patch @@ -1,8 +1,8 @@ -From 960534f564d80801fead4231c1e528e8e437ed87 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 21 Jul 2025 11:17:34 +0200 -Subject: [PATCH 016/108] FROMGIT(6.18): arm64: dts: rockchip: add pd_npu label - for RK3588 power domains +Subject: FROMGIT(6.18): arm64: dts: rockchip: add pd_npu label for RK3588 + power domains The NPU of the RK3588 has an external supply. This supply also affects the power domain of the NPU, not just the NPU device nodes themselves. @@ -18,7 +18,7 @@ Signed-off-by: Tomeu Vizoso 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index c1eaff86d5b7..3707aa1af785 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -841,7 +841,7 @@ power: power-controller { @@ -31,5 +31,5 @@ index c1eaff86d5b7..3707aa1af785 100644 #power-domain-cells = <0>; #address-cells = <1>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0017-FROMGIT-6.18-arm64-dts-rockchip-Add-nodes-for-NPU-an.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0017-FROMGIT-6.18-arm64-dts-rockchip-Add-nodes-for-NPU-an.patch index c815e3db8..39df6e59b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0017-FROMGIT-6.18-arm64-dts-rockchip-Add-nodes-for-NPU-an.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0017-FROMGIT-6.18-arm64-dts-rockchip-Add-nodes-for-NPU-an.patch @@ -1,8 +1,8 @@ -From 2f38aadba79e366bfbbb4e98bdf01b2fa0b4667d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:35 +0200 -Subject: [PATCH 017/108] FROMGIT(6.18): arm64: dts: rockchip: Add nodes for - NPU and its MMU to rk3588-base +Subject: FROMGIT(6.18): arm64: dts: rockchip: Add nodes for NPU and its MMU to + rk3588-base See Chapter 36 "RKNN" from the RK3588 TRM (Part 1). @@ -15,11 +15,11 @@ The IOMMU of the first core is also special in that it has two subunits Tested-by: Heiko Stuebner Signed-off-by: Tomeu Vizoso --- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 91 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 91 ++++++++++ 1 file changed, 91 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 3707aa1af785..56bf903eb04f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -1140,6 +1140,97 @@ power-domain@RK3588_PD_SDMMC { @@ -121,5 +121,5 @@ index 3707aa1af785..56bf903eb04f 100644 compatible = "rockchip,rk3588-vpu121", "rockchip,rk3568-vpu"; reg = <0x0 0xfdb50000 0x0 0x800>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0018-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-qu.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0018-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-qu.patch index 4b99fd518..ea8ed026c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0018-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-qu.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0018-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-qu.patch @@ -1,19 +1,18 @@ -From 96fa1545d6e230d6253eb3f74b0eeb20b43cfa56 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 21 Jul 2025 11:17:36 +0200 -Subject: [PATCH 018/108] FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU - on quartzpro64 +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU on quartzpro64 Enable the nodes added in a previous commit to the rk3588s device tree. Tested-by: Heiko Stuebner Signed-off-by: Tomeu Vizoso --- - .../boot/dts/rockchip/rk3588-quartzpro64.dts | 30 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 30 ++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts -index 78aaa6635b5d..b2336c36da01 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts @@ -415,6 +415,36 @@ &pcie3x4 { @@ -54,5 +53,5 @@ index 78aaa6635b5d..b2336c36da01 100644 vref-supply = <&vcc_1v8_s0>; status = "okay"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0019-FROMGIT-6.18-arm64-dts-rockchip-enable-NPU-on-ROCK-5.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0019-FROMGIT-6.18-arm64-dts-rockchip-enable-NPU-on-ROCK-5.patch index c73004f43..a515aaf50 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0019-FROMGIT-6.18-arm64-dts-rockchip-enable-NPU-on-ROCK-5.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0019-FROMGIT-6.18-arm64-dts-rockchip-enable-NPU-on-ROCK-5.patch @@ -1,8 +1,7 @@ -From 317cce80eb431cd7d4aaf4dc30b319b2b3d5ef92 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 21 Jul 2025 09:17:00 +0000 -Subject: [PATCH 019/108] FROMGIT(6.18): arm64: dts: rockchip: enable NPU on - ROCK 5B/5B+/5T +Subject: FROMGIT(6.18): arm64: dts: rockchip: enable NPU on ROCK 5B/5B+/5T The NPU on the ROCK5B uses the same regulator for both the sram-supply and the npu's supply. Add this regulator, and enable all the NPU bits. @@ -14,11 +13,11 @@ Signed-off-by: Tomeu Vizoso [ relocate patch to rk3588-rock-5b-5bp-5t.dtsi ] Signed-off-by: Christian Hewitt --- - .../dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 57 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 57 ++++++++++ 1 file changed, 57 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi -index 973d39a7e0e0..612808d2b4c5 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi @@ -268,6 +268,29 @@ regulator-state-mem { @@ -100,5 +99,5 @@ index 973d39a7e0e0..612808d2b4c5 100644 vref-supply = <&avcc_1v8_s0>; status = "okay"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0020-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-receiver.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0020-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-receiver.patch index 7312799e3..8760b20a0 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0020-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-receiver.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0020-FROMGIT-6.18-arm64-dts-rockchip-Enable-HDMI-receiver.patch @@ -1,22 +1,19 @@ -From 29b7330ef561ae7007792b9282c05d4ca5a32cd4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Maud Spierings Date: Sat, 23 Aug 2025 14:43:51 +0200 -Subject: [PATCH 020/108] FROMGIT(6.18): arm64: dts: rockchip: Enable HDMI - receiver on orangepi 5 plus -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable HDMI receiver on orangepi + 5 plus Enable support for the HDMI input port found on the orangepi 5 plus. Signed-off-by: Maud Spierings -Reviewed-by: Ondřej Jirman +Reviewed-by: Ondrej Jirman --- - .../dts/rockchip/rk3588-orangepi-5-plus.dts | 17 +++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 17 ++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts -index 8222f1fae8fa..9950d1147e12 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts @@ -160,6 +160,17 @@ &hdmi1_sound { @@ -51,5 +48,5 @@ index 8222f1fae8fa..9950d1147e12 100644 ir_receiver_pin: ir-receiver-pin { rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0021-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-th.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0021-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-th.patch index 0eb7654b0..9faff39a5 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0021-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-th.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0021-FROMGIT-6.18-arm64-dts-rockchip-Enable-the-NPU-on-th.patch @@ -1,22 +1,19 @@ -From 17bad86ba250bb1a93bcc42333f0dc1bdee3ea9b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Maud Spierings Date: Sat, 23 Aug 2025 14:43:52 +0200 -Subject: [PATCH 021/108] FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU - on the orangepi 5 boards -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable the NPU on the orangepi 5 + boards Enable the NPU and the PMIC that powers it. Signed-off-by: Maud Spierings -Reviewed-by: Ondřej Jirman +Reviewed-by: Ondrej Jirman --- - .../boot/dts/rockchip/rk3588-orangepi-5.dtsi | 56 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-orangepi-5.dtsi | 56 ++++++++++ 1 file changed, 56 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5.dtsi -index 8a8f3b26754d..3bceee948458 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5.dtsi @@ -258,6 +258,28 @@ regulator-state-mem { @@ -90,5 +87,5 @@ index 8a8f3b26754d..3bceee948458 100644 vref-supply = <&vcc_1v8_s0>; status = "okay"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0022-FROMGIT-6.18-arm64-dts-rockchip-rk3588s-rock-5a-Add-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0022-FROMGIT-6.18-arm64-dts-rockchip-rk3588s-rock-5a-Add-.patch index d789c4488..41c06b3ee 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0022-FROMGIT-6.18-arm64-dts-rockchip-rk3588s-rock-5a-Add-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0022-FROMGIT-6.18-arm64-dts-rockchip-rk3588s-rock-5a-Add-.patch @@ -1,8 +1,8 @@ -From ee2f59492e51379da3fb11760c8b2d1bec7ebe48 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "kylepzak@projectinitiative.io" Date: Tue, 19 Aug 2025 21:30:12 -0500 -Subject: [PATCH 022/108] FROMGIT(6.18): arm64: dts: rockchip: rk3588s-rock-5a: - Add green power LED +Subject: FROMGIT(6.18): arm64: dts: rockchip: rk3588s-rock-5a: Add green power + LED The Radxa ROCK 5A board includes a green power LED that is defined in the vendor device tree but is missing from the upstream kernel DTS file. @@ -19,7 +19,7 @@ Signed-off-by: Kyle Petryszak 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -index f894742b1ebe..f70b49d9361a 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts @@ -52,6 +52,13 @@ leds { @@ -37,5 +37,5 @@ index f894742b1ebe..f70b49d9361a 100644 color = ; function = LED_FUNCTION_STATUS; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0023-FROMGIT-6.18-arm64-dts-rockchip-Enable-RK3576-watchd.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0023-FROMGIT-6.18-arm64-dts-rockchip-Enable-RK3576-watchd.patch index b66d7c6ab..dd095ed63 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0023-FROMGIT-6.18-arm64-dts-rockchip-Enable-RK3576-watchd.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0023-FROMGIT-6.18-arm64-dts-rockchip-Enable-RK3576-watchd.patch @@ -1,8 +1,7 @@ -From be887c8e5e8938d694e75f8ceb3aa90f2e3aa769 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 18 Aug 2025 19:18:40 +0200 -Subject: [PATCH 023/108] FROMGIT(6.18): arm64: dts: rockchip: Enable RK3576 - watchdog +Subject: FROMGIT(6.18): arm64: dts: rockchip: Enable RK3576 watchdog The RK3576 watchdog does not need any board specific resources, so let's enable it by default just like we do for RK3588. @@ -13,7 +12,7 @@ Signed-off-by: Sebastian Reichel 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi -index b99f4bd4c9d9..552e825a96d3 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -2108,7 +2108,6 @@ wdt: watchdog@2ace0000 { @@ -25,5 +24,5 @@ index b99f4bd4c9d9..552e825a96d3 100644 spi0: spi@2acf0000 { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0024-FROMGIT-6.18-arm64-dts-rockchip-add-SPDIF-audio-to-B.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0024-FROMGIT-6.18-arm64-dts-rockchip-add-SPDIF-audio-to-B.patch index b1958f596..3b3fb2dad 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0024-FROMGIT-6.18-arm64-dts-rockchip-add-SPDIF-audio-to-B.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0024-FROMGIT-6.18-arm64-dts-rockchip-add-SPDIF-audio-to-B.patch @@ -1,8 +1,7 @@ -From cfcdbeea880365e4217fede204f3516ef1869618 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 27 Feb 2021 17:52:02 +0100 -Subject: [PATCH 024/108] FROMGIT(6.18): arm64: dts: rockchip: add SPDIF audio - to Beelink A1 +Subject: FROMGIT(6.18): arm64: dts: rockchip: add SPDIF audio to Beelink A1 Add the required nodes to enable SPDIF audio output on the Beelink A1 set-top-box. @@ -10,11 +9,11 @@ the Beelink A1 set-top-box. Signed-off-by: Alex Bee Signed-off-by: Christian Hewitt --- - arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 23 ++++++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 23 ++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -index f7c4578865c5..b276a29bdd85 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts @@ -58,6 +58,24 @@ ir-receiver { @@ -55,5 +54,5 @@ index f7c4578865c5..b276a29bdd85 100644 rockchip,hw-tshut-mode = <0>; rockchip,hw-tshut-polarity = <0>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0025-FROMGIT-6.18-arm64-dts-rockchip-add-USB3-on-Beelink-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0025-FROMGIT-6.18-arm64-dts-rockchip-add-USB3-on-Beelink-.patch index 4552e7617..907abbf2c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0025-FROMGIT-6.18-arm64-dts-rockchip-add-USB3-on-Beelink-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0025-FROMGIT-6.18-arm64-dts-rockchip-add-USB3-on-Beelink-.patch @@ -1,8 +1,7 @@ -From ea34273c334899f0a36894ec66eaebe1ab8ab4e3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 21 Aug 2021 17:04:46 +0200 -Subject: [PATCH 025/108] FROMGIT(6.18): arm64: dts: rockchip: add USB3 on - Beelink A1 +Subject: FROMGIT(6.18): arm64: dts: rockchip: add USB3 on Beelink A1 Enable USB3 for the Beelink A1 set-top box. @@ -13,7 +12,7 @@ Signed-off-by: Christian Hewitt 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts -index b276a29bdd85..632b0b22c52f 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts @@ -381,6 +381,11 @@ &usb_host0_ehci { @@ -29,5 +28,5 @@ index b276a29bdd85..632b0b22c52f 100644 status = "okay"; }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0026-FROMGIT-6.18-arm64-dts-rockchip-add-IR-receiver-to-r.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0026-FROMGIT-6.18-arm64-dts-rockchip-add-IR-receiver-to-r.patch index 5124d04ae..642f1bada 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0026-FROMGIT-6.18-arm64-dts-rockchip-add-IR-receiver-to-r.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0026-FROMGIT-6.18-arm64-dts-rockchip-add-IR-receiver-to-r.patch @@ -1,8 +1,7 @@ -From 23521dedf7b946179c07ecd34eebc8d34f6f6409 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 27 Feb 2021 18:01:13 +0100 -Subject: [PATCH 026/108] FROMGIT(6.18): arm64: dts: rockchip: add IR receiver - to rk3328-roc +Subject: FROMGIT(6.18): arm64: dts: rockchip: add IR receiver to rk3328-roc Add the ir-receiver and ir pinctrl nodes to enable the IR receiver on the ROC-RK3328-CC board. @@ -10,11 +9,11 @@ on the ROC-RK3328-CC board. Signed-off-by: Alex Bee Signed-off-by: Christian Hewitt --- - arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 14 ++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 14 ++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi -index b5bd5e7d5748..aa1d5a6d7fd5 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi @@ -84,6 +84,13 @@ vcc_phy: regulator-vcc-phy { @@ -46,5 +45,5 @@ index b5bd5e7d5748..aa1d5a6d7fd5 100644 pmic_int_l: pmic-int-l { rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0027-FROMGIT-6.18-arm64-dts-rockchip-add-GPU-powerdomain-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0027-FROMGIT-6.18-arm64-dts-rockchip-add-GPU-powerdomain-.patch index 0f46271d0..66def385a 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0027-FROMGIT-6.18-arm64-dts-rockchip-add-GPU-powerdomain-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0027-FROMGIT-6.18-arm64-dts-rockchip-add-GPU-powerdomain-.patch @@ -1,8 +1,8 @@ -From 5eb285a0a2db04a425b7198bf4ccad266646b7b0 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 2 Sep 2020 19:52:02 +0200 -Subject: [PATCH 027/108] FROMGIT(6.18): arm64: dts: rockchip: add GPU - powerdomain, opps, and cooling to rk3328 +Subject: FROMGIT(6.18): arm64: dts: rockchip: add GPU powerdomain, opps, and + cooling to rk3328 Add GPU powerdomain, opp-table, and cooling map nodes for the Mali GPU on the RK3328 SoC. Opp-table frequencies are sourced from the @@ -13,11 +13,11 @@ and disabling the 500MHz opp-point avoids instability and crashes. Signed-off-by: Alex Bee Signed-off-by: Christian Hewitt --- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 +++++++++++++++++++++++- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 +++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 6438c969f9d7..cc93136422c1 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -331,6 +331,11 @@ power: power-controller { @@ -84,5 +84,5 @@ index 6438c969f9d7..cc93136422c1 100644 h265e_mmu: iommu@ff330200 { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0028-FROMGIT-6.18-arm64-dts-rockchip-enable-the-Mali-GPU-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0028-FROMGIT-6.18-arm64-dts-rockchip-enable-the-Mali-GPU-.patch index 361465b9c..37362ac02 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0028-FROMGIT-6.18-arm64-dts-rockchip-enable-the-Mali-GPU-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0028-FROMGIT-6.18-arm64-dts-rockchip-enable-the-Mali-GPU-.patch @@ -1,8 +1,8 @@ -From 4d3154e1151a869b20cca421792ed2237c75ff9f Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 2 Sep 2020 19:52:02 +0200 -Subject: [PATCH 028/108] FROMGIT(6.18): arm64: dts: rockchip: enable the Mali - GPU on RK3328 boards +Subject: FROMGIT(6.18): arm64: dts: rockchip: enable the Mali GPU on RK3328 + boards Add a gpu node to the rock64 board to enable the Mali GPU and move the existing node from roc-pc to the shared roc dtsi to @@ -17,7 +17,7 @@ Signed-off-by: Christian Hewitt 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts -index 329d03172433..c0b7b98ff788 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts @@ -44,10 +44,6 @@ &codec { @@ -32,7 +32,7 @@ index 329d03172433..c0b7b98ff788 100644 ir { ir_int: ir-int { diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi -index aa1d5a6d7fd5..3fe0c17fd2b1 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi @@ -167,6 +167,10 @@ &gmac2io { @@ -47,7 +47,7 @@ index aa1d5a6d7fd5..3fe0c17fd2b1 100644 status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -index 5367e5fa9232..592fd8ca21df 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -152,6 +152,10 @@ &gmac2io { @@ -62,5 +62,5 @@ index 5367e5fa9232..592fd8ca21df 100644 avdd-0v9-supply = <&vdd_10>; avdd-1v8-supply = <&vcc_18>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0029-FROMGIT-6.18-ARM-dts-rockchip-add-HDMI-audio-to-rk32.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0029-FROMGIT-6.18-ARM-dts-rockchip-add-HDMI-audio-to-rk32.patch index 8facb4c5b..34cbb6687 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0029-FROMGIT-6.18-ARM-dts-rockchip-add-HDMI-audio-to-rk32.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0029-FROMGIT-6.18-ARM-dts-rockchip-add-HDMI-audio-to-rk32.patch @@ -1,8 +1,7 @@ -From 4898362d8fb614e726a5ae7df1d31b7ce3fb3119 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 2 Feb 2021 17:22:21 +0200 -Subject: [PATCH 029/108] FROMGIT(6.18): ARM: dts: rockchip: add HDMI audio to - rk3288-miqi +Subject: FROMGIT(6.18): ARM: dts: rockchip: add HDMI audio to rk3288-miqi Add the sound and i2s nodes to enable HDMI audio output on the MiQi board. @@ -10,11 +9,11 @@ the MiQi board. Signed-off-by: Alex Bee Signed-off-by: Christian Hewitt --- - arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 20 ++++++++++++++++++++ + arch/arm/boot/dts/rockchip/rk3288-miqi.dts | 20 ++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index dd42f8d31f70..20df626547bd 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts @@ -78,6 +78,21 @@ vcc_sys: regulator-vsys { @@ -52,5 +51,5 @@ index dd42f8d31f70..20df626547bd 100644 status = "okay"; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0030-FROMGIT-6.18-ARM-dts-rockchip-add-CEC-pinctrl-to-rk3.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0030-FROMGIT-6.18-ARM-dts-rockchip-add-CEC-pinctrl-to-rk3.patch index b16d13c82..c9dd452d6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0030-FROMGIT-6.18-ARM-dts-rockchip-add-CEC-pinctrl-to-rk3.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0030-FROMGIT-6.18-ARM-dts-rockchip-add-CEC-pinctrl-to-rk3.patch @@ -1,8 +1,7 @@ -From c0ab4f0e15e2e981996e4014196505b214f074cc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 1 Mar 2021 21:24:15 +0100 -Subject: [PATCH 030/108] FROMGIT(6.18): ARM: dts: rockchip: add CEC pinctrl to - rk3288-miqi +Subject: FROMGIT(6.18): ARM: dts: rockchip: add CEC pinctrl to rk3288-miqi Enable CEC control on the HDMI port for MiQi. @@ -13,7 +12,7 @@ Signed-off-by: Christian Hewitt 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts -index 20df626547bd..a5f5c6d38f80 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rockchip/rk3288-miqi.dts @@ -145,6 +145,8 @@ &gpu { @@ -26,5 +25,5 @@ index 20df626547bd..a5f5c6d38f80 100644 }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0031-FROMLIST-v1-mmc-core-set-initial-signal-voltage-on-p.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0031-FROMLIST-v1-mmc-core-set-initial-signal-voltage-on-p.patch index 573c99abe..d940531be 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0031-FROMLIST-v1-mmc-core-set-initial-signal-voltage-on-p.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0031-FROMLIST-v1-mmc-core-set-initial-signal-voltage-on-p.patch @@ -1,8 +1,7 @@ -From 9a3ffa8a3b4c8755d57a5b18ad3e664e9cf0cd24 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 17 Feb 2019 22:14:38 +0000 -Subject: [PATCH 031/108] FROMLIST(v1): mmc: core: set initial signal voltage - on power off +Subject: mmc: core: set initial signal voltage on power off Some boards have SD card connectors where the power rail cannot be switched off by the driver. If the card has not been power cycled, it may still be @@ -24,7 +23,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index 874c6fe92855..7a8bede74cdd 100644 +index 111111111111..222222222222 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1373,6 +1373,14 @@ void mmc_power_off(struct mmc_host *host) @@ -43,5 +42,5 @@ index 874c6fe92855..7a8bede74cdd 100644 host->ios.clock = 0; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0032-FROMLIST-v7-dt-bindings-vendor-prefixes-Add-Verisili.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0032-FROMLIST-v7-dt-bindings-vendor-prefixes-Add-Verisili.patch index 281933eb5..213473fa6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0032-FROMLIST-v7-dt-bindings-vendor-prefixes-Add-Verisili.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0032-FROMLIST-v7-dt-bindings-vendor-prefixes-Add-Verisili.patch @@ -1,8 +1,7 @@ -From 2fe8271be434668d1da551357cd7a934d035e9ba Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 25 Aug 2025 17:34:40 +0200 -Subject: [PATCH 032/108] FROMLIST(v7): dt-bindings: vendor-prefixes: Add - Verisilicon +Subject: FROMLIST(v7): dt-bindings: vendor-prefixes: Add Verisilicon Verisilicon Microelectronics is a company based in Shanghai, China, developping hardware blocks for SoC. @@ -18,10 +17,10 @@ Acked-by: Conor Dooley 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml -index 9ec8947dfcad..52b3495ff4db 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml -@@ -1656,6 +1656,8 @@ patternProperties: +@@ -1704,6 +1704,8 @@ patternProperties: description: Variscite Ltd. "^vdl,.*": description: Van der Laan b.v. @@ -31,5 +30,5 @@ index 9ec8947dfcad..52b3495ff4db 100644 description: Vertexcom Technologies, Inc. "^via,.*": -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0033-FROMLIST-v7-dt-bindings-iommu-verisilicon-Add-bindin.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0033-FROMLIST-v7-dt-bindings-iommu-verisilicon-Add-bindin.patch index d4ae42e67..f6648ac02 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0033-FROMLIST-v7-dt-bindings-iommu-verisilicon-Add-bindin.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0033-FROMLIST-v7-dt-bindings-iommu-verisilicon-Add-bindin.patch @@ -1,8 +1,8 @@ -From 64fbd58f282af1be1ffdd94df94651baaf0b4f8e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 25 Aug 2025 17:34:41 +0200 -Subject: [PATCH 033/108] FROMLIST(v7): dt-bindings: iommu: verisilicon: Add - binding for VSI IOMMU +Subject: FROMLIST(v7): dt-bindings: iommu: verisilicon: Add binding for VSI + IOMMU Add a device tree binding for the Verisilicon (VSI) IOMMU. This IOMMU sits in front of hardware encoder and decoder @@ -11,13 +11,12 @@ blocks on SoCs using Verisilicon IP, such as the Rockchip RK3588. Signed-off-by: Benjamin Gaignard Reviewed-by: Conor Dooley --- - .../bindings/iommu/verisilicon,iommu.yaml | 71 +++++++++++++++++++ + Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml | 71 ++++++++++ 1 file changed, 71 insertions(+) - create mode 100644 Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml diff --git a/Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml b/Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml new file mode 100644 -index 000000000000..d3ce9e603b61 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml @@ -0,0 +1,71 @@ @@ -93,5 +92,5 @@ index 000000000000..d3ce9e603b61 + }; + }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0034-FROMLIST-v7-iommu-Add-verisilicon-IOMMU-driver.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0034-FROMLIST-v7-iommu-Add-verisilicon-IOMMU-driver.patch index f41a59582..316a1e5ef 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0034-FROMLIST-v7-iommu-Add-verisilicon-IOMMU-driver.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0034-FROMLIST-v7-iommu-Add-verisilicon-IOMMU-driver.patch @@ -1,7 +1,7 @@ -From 1f06807df186c80abf4ec533df74c6ab07e030c6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 25 Aug 2025 17:34:42 +0200 -Subject: [PATCH 034/108] FROMLIST(v7): iommu: Add verisilicon IOMMU driver +Subject: FROMLIST(v7): iommu: Add verisilicon IOMMU driver The Verisilicon IOMMU hardware block can be found in combination with Verisilicon hardware video codecs (encoders or decoders) on @@ -13,12 +13,11 @@ Signed-off-by: Benjamin Gaignard --- drivers/iommu/Kconfig | 11 + drivers/iommu/Makefile | 1 + - drivers/iommu/vsi-iommu.c | 779 ++++++++++++++++++++++++++++++++++++++ + drivers/iommu/vsi-iommu.c | 779 ++++++++++ 3 files changed, 791 insertions(+) - create mode 100644 drivers/iommu/vsi-iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig -index 70d29b14d851..d3731be630a2 100644 +index 111111111111..222222222222 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -383,4 +383,15 @@ config SPRD_IOMMU @@ -38,7 +37,7 @@ index 70d29b14d851..d3731be630a2 100644 + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile -index 355294fa9033..68aeff31af8b 100644 +index 111111111111..222222222222 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o @@ -48,7 +47,7 @@ index 355294fa9033..68aeff31af8b 100644 +obj-$(CONFIG_VSI_IOMMU) += vsi-iommu.o diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c new file mode 100644 -index 000000000000..69b5fcb910ef +index 000000000000..111111111111 --- /dev/null +++ b/drivers/iommu/vsi-iommu.c @@ -0,0 +1,779 @@ @@ -832,5 +831,5 @@ index 000000000000..69b5fcb910ef +MODULE_AUTHOR("Benjamin Gaignard "); +MODULE_DESCRIPTION("Verisilicon IOMMU driver"); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0035-FROMLIST-v7-media-verisilicon-AV1-Restore-IOMMU-cont.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0035-FROMLIST-v7-media-verisilicon-AV1-Restore-IOMMU-cont.patch index e41789f00..c2e8bc820 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0035-FROMLIST-v7-media-verisilicon-AV1-Restore-IOMMU-cont.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0035-FROMLIST-v7-media-verisilicon-AV1-Restore-IOMMU-cont.patch @@ -1,8 +1,8 @@ -From 8ba4af5d9c0c85163e6f6b076e22dfc16311d2be Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 25 Aug 2025 17:34:43 +0200 -Subject: [PATCH 035/108] FROMLIST(v7): media: verisilicon: AV1: Restore IOMMU - context before decoding a frame +Subject: FROMLIST(v7): media: verisilicon: AV1: Restore IOMMU context before + decoding a frame AV1 is a stateless decoder and multiple AV1 bitstreams could be decoded at the same time. Each decoding context got it own iommu domain which @@ -11,13 +11,13 @@ correctly set AV1 driver detach and attach before decoding the frame. Signed-off-by: Benjamin Gaignard --- - drivers/media/platform/verisilicon/hantro.h | 5 +++++ - drivers/media/platform/verisilicon/hantro_drv.c | 11 +++++++++++ - .../platform/verisilicon/rockchip_vpu981_hw_av1_dec.c | 10 ++++++++++ + drivers/media/platform/verisilicon/hantro.h | 5 +++++ + drivers/media/platform/verisilicon/hantro_drv.c | 11 ++++++++++ + drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c | 10 +++++++++ 3 files changed, 26 insertions(+) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h -index 81328c63b796..a28a181013b9 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -12,6 +12,9 @@ @@ -40,7 +40,7 @@ index 81328c63b796..a28a181013b9 100644 union { struct hantro_h264_dec_hw_ctx h264_dec; diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c -index fa972effd4a2..c31fd75902d4 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -674,6 +674,13 @@ static int hantro_open(struct file *filp) @@ -69,7 +69,7 @@ index fa972effd4a2..c31fd75902d4 100644 return 0; diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c -index e4703bb6be7c..b3e52387234f 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c @@ -2095,12 +2095,22 @@ rockchip_vpu981_av1_dec_set_output_buffer(struct hantro_ctx *ctx) @@ -96,5 +96,5 @@ index e4703bb6be7c..b3e52387234f 100644 ret = rockchip_vpu981_av1_dec_prepare_run(ctx); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0036-FROMLIST-v7-arm64-dts-rockchip-Add-verisilicon-IOMMU.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0036-FROMLIST-v7-arm64-dts-rockchip-Add-verisilicon-IOMMU.patch index e59eed766..bd69f07e5 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0036-FROMLIST-v7-arm64-dts-rockchip-Add-verisilicon-IOMMU.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0036-FROMLIST-v7-arm64-dts-rockchip-Add-verisilicon-IOMMU.patch @@ -1,8 +1,8 @@ -From 8937d64d478bd515e07147a5cfe6fbc54afb251a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 25 Aug 2025 17:34:44 +0200 -Subject: [PATCH 036/108] FROMLIST(v7): arm64: dts: rockchip: Add verisilicon - IOMMU node on RK3588 +Subject: FROMLIST(v7): arm64: dts: rockchip: Add verisilicon IOMMU node on + RK3588 Add the device tree node for the Verisilicon IOMMU present in the RK3588 SoC. @@ -10,11 +10,11 @@ This IOMMU handles address translation for the VPU hardware blocks. Signed-off-by: Benjamin Gaignard --- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 11 +++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 56bf903eb04f..3bd1b5e3b101 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -1418,6 +1418,17 @@ av1d: video-codec@fdc70000 { @@ -36,5 +36,5 @@ index 56bf903eb04f..3bd1b5e3b101 100644 vop: vop@fdd90000 { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0037-FROMLIST-v1-drm-bridge-dw-hdmi-qp-Return-0-in-audio-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0037-FROMLIST-v1-drm-bridge-dw-hdmi-qp-Return-0-in-audio-.patch index 68a0ef7c6..14a206e16 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0037-FROMLIST-v1-drm-bridge-dw-hdmi-qp-Return-0-in-audio-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0037-FROMLIST-v1-drm-bridge-dw-hdmi-qp-Return-0-in-audio-.patch @@ -1,8 +1,7 @@ -From 48c7a17a11c519e59a7b3e2d53268ff0ace54c51 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Thu, 17 Jul 2025 17:56:18 -0400 -Subject: [PATCH 037/108] FROMLIST(v1): drm/bridge: dw-hdmi-qp: Return 0 in - audio prepare when disconnected +Subject: drm/bridge: dw-hdmi-qp: Return 0 in audio prepare when disconnected To configure audio registers, the clock of the video port in use must be enabled. @@ -36,7 +35,7 @@ Signed-off-by: Detlev Casanova 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 39332c57f2c5..3d290f7b015f 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -460,7 +460,7 @@ static int dw_hdmi_qp_audio_prepare(struct drm_bridge *bridge, @@ -49,5 +48,5 @@ index 39332c57f2c5..3d290f7b015f 100644 if (fmt->bit_clk_provider | fmt->frame_clk_provider) { dev_err(hdmi->dev, "unsupported clock settings\n"); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0038-FROMLIST-v1-drm-bridge-synopsys-Do-not-warn-about-au.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0038-FROMLIST-v1-drm-bridge-synopsys-Do-not-warn-about-au.patch index b8734461a..61a8a1d48 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0038-FROMLIST-v1-drm-bridge-synopsys-Do-not-warn-about-au.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0038-FROMLIST-v1-drm-bridge-synopsys-Do-not-warn-about-au.patch @@ -1,8 +1,7 @@ -From b78e78578111f26f5ae1fd83fbd0a41658449f46 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Thu, 26 Jun 2025 08:53:07 -0400 -Subject: [PATCH 038/108] FROMLIST(v1): drm/bridge: synopsys: Do not warn about - audio params computation +Subject: drm/bridge: synopsys: Do not warn about audio params computation There is no need to warn about non pre-computed values, just change it to dbg. @@ -13,7 +12,7 @@ Signed-off-by: Detlev Casanova 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 3d290f7b015f..8f5059edb582 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -277,8 +277,7 @@ static unsigned int dw_hdmi_qp_find_n(struct dw_hdmi_qp *hdmi, unsigned long pix @@ -27,5 +26,5 @@ index 3d290f7b015f..8f5059edb582 100644 return dw_hdmi_qp_compute_n(hdmi, pixel_clk, sample_rate); } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0039-FROMLIST-v1-arm64-dts-rockchip-use-MAC-TX-delay-for-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0039-FROMLIST-v1-arm64-dts-rockchip-use-MAC-TX-delay-for-.patch index 863653700..8d921177b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0039-FROMLIST-v1-arm64-dts-rockchip-use-MAC-TX-delay-for-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0039-FROMLIST-v1-arm64-dts-rockchip-use-MAC-TX-delay-for-.patch @@ -1,8 +1,7 @@ -From c1674bdd8306651c0fd258fcc32473e562ec078a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Thu, 24 Jul 2025 16:31:25 +0200 -Subject: [PATCH 039/108] FROMLIST(v1): arm64: dts: rockchip: use MAC TX delay - for ROCK 4D +Subject: arm64: dts: rockchip: use MAC TX delay for ROCK 4D According to the Ethernet controller device tree binding "rgmii-id" means, that the PCB does not have extra long lines to add the required @@ -34,7 +33,7 @@ Signed-off-by: Sebastian Reichel 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts -index 9bc33422ced5..b607afb09635 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts @@ -272,7 +272,7 @@ &cpu_l3 { @@ -56,5 +55,5 @@ index 9bc33422ced5..b607afb09635 100644 &gpu { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0040-FROMLIST-v2-arm64-dts-rockchip-Fix-sound-output-from.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0040-FROMLIST-v2-arm64-dts-rockchip-Fix-sound-output-from.patch index 8e144abcc..f77998f26 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0040-FROMLIST-v2-arm64-dts-rockchip-Fix-sound-output-from.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0040-FROMLIST-v2-arm64-dts-rockchip-Fix-sound-output-from.patch @@ -1,8 +1,8 @@ -From 1522430dfc988a0f13ceb046c97436b751042e88 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Hide Hako Date: Tue, 26 Aug 2025 01:44:00 +0000 -Subject: [PATCH 040/108] FROMLIST(v2): arm64: dts: rockchip: Fix sound output - from the audio jack on OrangePI5 Plus +Subject: FROMLIST(v2): arm64: dts: rockchip: Fix sound output from the audio + jack on OrangePI5 Plus Currently, analog sound is not output from the audio jack. This patch allows you to select analog headphones in alsamixer. @@ -14,7 +14,7 @@ Signed-off-by: Hide Hako 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts -index 9950d1147e12..2acadcfe52e4 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts @@ -78,6 +78,7 @@ &analog_sound { @@ -26,5 +26,5 @@ index 9950d1147e12..2acadcfe52e4 100644 "Microphone", "Onboard Microphone", "Microphone", "Microphone Jack", -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0041-FROMLIST-v2-thermal-rockchip-unify-struct-rockchip_t.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0041-FROMLIST-v2-thermal-rockchip-unify-struct-rockchip_t.patch index 8700bc6e5..7a63b0595 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0041-FROMLIST-v2-thermal-rockchip-unify-struct-rockchip_t.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0041-FROMLIST-v2-thermal-rockchip-unify-struct-rockchip_t.patch @@ -1,8 +1,8 @@ -From 9ee5120322779e070d0c3b38866f21e962d11fcc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 20 Aug 2025 19:40:47 +0200 -Subject: [PATCH 041/108] FROMLIST(v2): thermal: rockchip: unify struct - rockchip_tsadc_chip format +Subject: FROMLIST(v2): thermal: rockchip: unify struct rockchip_tsadc_chip + format Unify all chip descriptions to the version without any empty lines. @@ -12,11 +12,11 @@ Signed-off-by: Sebastian Reichel Reviewed-by: Heiko Stuebner Reviewed-by: Dragan Simic --- - drivers/thermal/rockchip_thermal.c | 27 --------------------------- + drivers/thermal/rockchip_thermal.c | 27 ---------- 1 file changed, 27 deletions(-) diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c -index 3beff9b6fac3..7b18a705dfad 100644 +index 111111111111..222222222222 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -1098,10 +1098,8 @@ static const struct rockchip_tsadc_chip px30_tsadc_data = { @@ -198,5 +198,5 @@ index 3beff9b6fac3..7b18a705dfad 100644 .id = rk3568_code_table, .length = ARRAY_SIZE(rk3568_code_table), -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0042-FROMLIST-v2-thermal-rockchip-shut-up-GRF-warning.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0042-FROMLIST-v2-thermal-rockchip-shut-up-GRF-warning.patch index 1c7c88414..c787ebd07 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0042-FROMLIST-v2-thermal-rockchip-shut-up-GRF-warning.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0042-FROMLIST-v2-thermal-rockchip-shut-up-GRF-warning.patch @@ -1,7 +1,7 @@ -From dc6441a5dea8462b3168c6bd00b3dd8685e7bdfd Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 20 Aug 2025 19:40:48 +0200 -Subject: [PATCH 042/108] FROMLIST(v2): thermal: rockchip: shut up GRF warning +Subject: FROMLIST(v2): thermal: rockchip: shut up GRF warning Most of the recent Rockchip devices do not have a GRF associated with the tsadc IP. Let's avoid printing a warning on those devices. @@ -11,11 +11,11 @@ Reviewed-by: Heiko Stuebner Tested-by: Diederik de Haas Reviewed-by: Dragan Simic --- - drivers/thermal/rockchip_thermal.c | 23 ++++++++++++++++++----- + drivers/thermal/rockchip_thermal.c | 23 ++++++++-- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c -index 7b18a705dfad..c49ddf70f86e 100644 +index 111111111111..222222222222 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -74,6 +74,7 @@ struct chip_tsadc_table { @@ -141,5 +141,5 @@ index 7b18a705dfad..c49ddf70f86e 100644 rockchip_get_trim_configuration(dev, np, thermal); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0043-FROMLIST-v2-dt-bindings-thermal-rockchip-tighten-grf.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0043-FROMLIST-v2-dt-bindings-thermal-rockchip-tighten-grf.patch index 7176f2653..95a57ba61 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0043-FROMLIST-v2-dt-bindings-thermal-rockchip-tighten-grf.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0043-FROMLIST-v2-dt-bindings-thermal-rockchip-tighten-grf.patch @@ -1,8 +1,8 @@ -From 6a7b792844c90010f77e6e39ba20458938340090 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 20 Aug 2025 19:40:49 +0200 -Subject: [PATCH 043/108] FROMLIST(v2): dt-bindings: thermal: rockchip: tighten - grf requirements +Subject: FROMLIST(v2): dt-bindings: thermal: rockchip: tighten grf + requirements Instead of having an optional rockchip,grf property, forbid using it on platforms without registers in a GRF being needed for thermal monitoring @@ -12,11 +12,11 @@ Signed-off-by: Sebastian Reichel Acked-by: Conor Dooley Reviewed-by: Dragan Simic --- - .../bindings/thermal/rockchip-thermal.yaml | 15 +++++++++++++++ + Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml | 15 ++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml -index 573f447cc26e..9fa5c4c49d76 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml @@ -119,6 +119,21 @@ required: @@ -42,5 +42,5 @@ index 573f447cc26e..9fa5c4c49d76 100644 not: properties: -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0044-FROMLIST-v3-media-rkvdec-Add-HEVC-backend.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0044-FROMLIST-v3-media-rkvdec-Add-HEVC-backend.patch index f93b723a3..76691dbea 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0044-FROMLIST-v3-media-rkvdec-Add-HEVC-backend.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0044-FROMLIST-v3-media-rkvdec-Add-HEVC-backend.patch @@ -1,7 +1,7 @@ -From 1e4384c38f0651af63b89609c5dedfba33e21e1b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 5 Sep 2025 16:19:19 +0000 -Subject: [PATCH 044/108] FROMLIST(v3): media: rkvdec: Add HEVC backend +Subject: FROMLIST(v3): media: rkvdec: Add HEVC backend The Rockchip VDEC supports the HEVC codec with the Main and Main10 Profile up to Level 5.1 High tier: 4096x2304@60 fps. @@ -15,18 +15,16 @@ Tested-by: Nicolas Dufresne Reviewed-by: Nicolas Dufresne Signed-off-by: Jonas Karlman --- - .../media/platform/rockchip/rkvdec/Makefile | 2 +- - .../rockchip/rkvdec/rkvdec-hevc-data.c | 1848 +++++++++++++++++ - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 817 ++++++++ - .../platform/rockchip/rkvdec/rkvdec-regs.h | 2 + - .../media/platform/rockchip/rkvdec/rkvdec.c | 76 + - .../media/platform/rockchip/rkvdec/rkvdec.h | 1 + + drivers/media/platform/rockchip/rkvdec/Makefile | 2 +- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c | 1848 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 817 ++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h | 2 + + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 76 + + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 + 6 files changed, 2745 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index cb86b429cfaa..a77122641d14 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -1,3 +1,3 @@ @@ -36,7 +34,7 @@ index cb86b429cfaa..a77122641d14 100644 +rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-hevc.o rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c new file mode 100644 -index 000000000000..eac4ea604949 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c @@ -0,0 +1,1848 @@ @@ -1890,7 +1888,7 @@ index 000000000000..eac4ea604949 +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c new file mode 100644 -index 000000000000..9b5cf70188db +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -0,0 +1,817 @@ @@ -2712,7 +2710,7 @@ index 000000000000..9b5cf70188db + .get_image_fmt = rkvdec_hevc_get_image_fmt, +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h -index 15b9bee92016..540c8bdf24e4 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h @@ -28,6 +28,7 @@ @@ -2732,7 +2730,7 @@ index 15b9bee92016..540c8bdf24e4 100644 #define RKVDEC_MODE_VP9 2 #define RKVDEC_RPS_MODE BIT(24) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index d3b31f461194..f26e4a1150c9 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -158,6 +158,67 @@ static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { @@ -2826,7 +2824,7 @@ index d3b31f461194..f26e4a1150c9 100644 .fourcc = V4L2_PIX_FMT_H264_SLICE, .frmsize = { diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index f6e8bf38add3..c062c5c5bbb2 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -139,6 +139,7 @@ void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); @@ -2838,5 +2836,5 @@ index f6e8bf38add3..c062c5c5bbb2 100644 #endif /* RKVDEC_H_ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0045-FROMLIST-v3-media-rkvdec-Add-variants-support.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0045-FROMLIST-v3-media-rkvdec-Add-variants-support.patch index 17978e9ef..6ddf7974f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0045-FROMLIST-v3-media-rkvdec-Add-variants-support.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0045-FROMLIST-v3-media-rkvdec-Add-variants-support.patch @@ -1,7 +1,7 @@ -From bc218b36dcc4a6472ac65ee1db817cc64cbf790f Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 5 Sep 2025 16:19:20 +0000 -Subject: [PATCH 045/108] FROMLIST(v3): media: rkvdec: Add variants support +Subject: FROMLIST(v3): media: rkvdec: Add variants support Different versions of the Rockchip VDEC IP exists and one way they can differ is what decoding formats are supported. @@ -13,12 +13,12 @@ Signed-off-by: Alex Bee Reviewed-by: Nicolas Dufresne Signed-off-by: Jonas Karlman --- - .../media/platform/rockchip/rkvdec/rkvdec.c | 22 ++++++++++++++++++- - .../media/platform/rockchip/rkvdec/rkvdec.h | 11 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 22 +++++++++- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 11 +++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index f26e4a1150c9..9406805675d8 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -14,6 +14,7 @@ @@ -97,7 +97,7 @@ index f26e4a1150c9..9406805675d8 100644 INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index c062c5c5bbb2..d2e17eb2cca6 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -22,6 +22,10 @@ @@ -140,5 +140,5 @@ index c062c5c5bbb2..d2e17eb2cca6 100644 struct rkvdec_ctx { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0046-FROMLIST-v3-media-rkvdec-Implement-capability-filter.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0046-FROMLIST-v3-media-rkvdec-Implement-capability-filter.patch index 74730d215..414e09612 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0046-FROMLIST-v3-media-rkvdec-Implement-capability-filter.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0046-FROMLIST-v3-media-rkvdec-Implement-capability-filter.patch @@ -1,8 +1,7 @@ -From 61705b83d47a950b13a03b712581f1f31d410bac Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 10 Aug 2025 21:24:33 +0000 -Subject: [PATCH 046/108] FROMLIST(v3): media: rkvdec: Implement capability - filtering +Subject: FROMLIST(v3): media: rkvdec: Implement capability filtering Add filtering of coded formats and controls depending on a variant capabilities. @@ -10,11 +9,11 @@ capabilities. Signed-off-by: Alex Bee Signed-off-by: Jonas Karlman --- - .../media/platform/rockchip/rkvdec/rkvdec.c | 67 ++++++++++++++----- + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 67 +++++++--- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 9406805675d8..adbc277a3112 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -365,13 +365,36 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { @@ -156,5 +155,5 @@ index 9406805675d8..adbc277a3112 100644 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0047-FROMLIST-v3-media-rkvdec-Add-RK3288-variant.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0047-FROMLIST-v3-media-rkvdec-Add-RK3288-variant.patch index a3497c40f..0cc2ac5a8 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0047-FROMLIST-v3-media-rkvdec-Add-RK3288-variant.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0047-FROMLIST-v3-media-rkvdec-Add-RK3288-variant.patch @@ -1,7 +1,7 @@ -From d0a24ad239a154b3e967f8c48856fbe7a1491def Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 10 Aug 2025 21:24:34 +0000 -Subject: [PATCH 047/108] FROMLIST(v3): media: rkvdec: Add RK3288 variant +Subject: FROMLIST(v3): media: rkvdec: Add RK3288 variant Add a RK3288 variant, a version of the Rockchip VDEC IP that only support HEVC decoding. @@ -13,7 +13,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 9 insertions(+) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index adbc277a3112..918ac6d38950 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -1221,6 +1221,11 @@ static void rkvdec_watchdog_func(struct work_struct *work) @@ -40,5 +40,5 @@ index adbc277a3112..918ac6d38950 100644 .compatible = "rockchip,rk3399-vdec", .data = &rk3399_rkvdec_variant, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0048-FROMLIST-v3-media-rkvdec-Disable-QoS-for-HEVC-and-VP.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0048-FROMLIST-v3-media-rkvdec-Disable-QoS-for-HEVC-and-VP.patch index 214c19465..2f7624c5c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0048-FROMLIST-v3-media-rkvdec-Disable-QoS-for-HEVC-and-VP.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0048-FROMLIST-v3-media-rkvdec-Disable-QoS-for-HEVC-and-VP.patch @@ -1,8 +1,7 @@ -From 887446046b0547e1d76d0eef142a785a339d22b6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 10 Aug 2025 21:24:35 +0000 -Subject: [PATCH 048/108] FROMLIST(v3): media: rkvdec: Disable QoS for HEVC and - VP9 on RK3328 +Subject: FROMLIST(v3): media: rkvdec: Disable QoS for HEVC and VP9 on RK3328 The RK3328 VDEC has a HW quirk that require QoS to be disabled when HEVC or VP9 is decoded, otherwise the decoded picture may become corrupted. @@ -13,15 +12,15 @@ decoding is started. Signed-off-by: Alex Bee Signed-off-by: Jonas Karlman --- - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 3 +++ - .../platform/rockchip/rkvdec/rkvdec-regs.h | 2 ++ - .../platform/rockchip/rkvdec/rkvdec-vp9.c | 4 ++++ - .../media/platform/rockchip/rkvdec/rkvdec.c | 24 +++++++++++++++++++ - .../media/platform/rockchip/rkvdec/rkvdec.h | 5 ++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 3 ++ + drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h | 2 + + drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c | 4 ++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 24 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 5 ++ 5 files changed, 38 insertions(+) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c -index 9b5cf70188db..fc7e6a260b0a 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -789,6 +789,9 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) @@ -35,7 +34,7 @@ index 9b5cf70188db..fc7e6a260b0a 100644 reg = (run.pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) ? 0 : RKVDEC_WR_DDR_ALIGN_EN; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h -index 540c8bdf24e4..c627b6b6f53a 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h @@ -219,6 +219,8 @@ @@ -48,7 +47,7 @@ index 540c8bdf24e4..c627b6b6f53a 100644 #define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450 diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c -index 0e7e16f20eeb..b4bf01e839ef 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c @@ -824,6 +824,10 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) @@ -63,7 +62,7 @@ index 0e7e16f20eeb..b4bf01e839ef 100644 writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 918ac6d38950..ef0ad92600f3 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -902,6 +902,18 @@ void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) @@ -112,7 +111,7 @@ index 918ac6d38950..ef0ad92600f3 100644 .compatible = "rockchip,rk3399-vdec", .data = &rk3399_rkvdec_variant, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index d2e17eb2cca6..892d2380b59d 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -26,6 +26,8 @@ @@ -142,5 +141,5 @@ index d2e17eb2cca6..892d2380b59d 100644 extern const struct rkvdec_coded_fmt_ops rkvdec_hevc_fmt_ops; extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0049-FROMLIST-v3-media-dt-bindings-rockchip-vdec-Add-RK32.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0049-FROMLIST-v3-media-dt-bindings-rockchip-vdec-Add-RK32.patch index 6a707f7da..7eeaa58d6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0049-FROMLIST-v3-media-dt-bindings-rockchip-vdec-Add-RK32.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0049-FROMLIST-v3-media-dt-bindings-rockchip-vdec-Add-RK32.patch @@ -1,8 +1,8 @@ -From c6cad4f9200d4990edea865767d30fe86fa7bdfb Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 10 Aug 2025 21:24:36 +0000 -Subject: [PATCH 049/108] FROMLIST(v3): media: dt-bindings: rockchip,vdec: Add - RK3288 compatible +Subject: FROMLIST(v3): media: dt-bindings: rockchip,vdec: Add RK3288 + compatible Add a RK3288 compatible for a version of the Rockchip VDEC IP that only support HEVC decoding. @@ -14,7 +14,7 @@ Acked-by: Conor Dooley 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -index 96b6c8938768..809fda45b3bd 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml @@ -16,6 +16,7 @@ description: |- @@ -26,5 +26,5 @@ index 96b6c8938768..809fda45b3bd 100644 - const: rockchip,rk3576-vdec - const: rockchip,rk3588-vdec -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0050-FROMLIST-v3-ARM-dts-rockchip-Add-vdec-node-for-RK328.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0050-FROMLIST-v3-ARM-dts-rockchip-Add-vdec-node-for-RK328.patch index ed8aa1351..2f4114378 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0050-FROMLIST-v3-ARM-dts-rockchip-Add-vdec-node-for-RK328.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0050-FROMLIST-v3-ARM-dts-rockchip-Add-vdec-node-for-RK328.patch @@ -1,8 +1,7 @@ -From 5b0a6858cd6203fe8ec20b22ccd8f0779f8236d6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 10 Aug 2025 21:24:37 +0000 -Subject: [PATCH 050/108] FROMLIST(v3): ARM: dts: rockchip: Add vdec node for - RK3288 +Subject: FROMLIST(v3): ARM: dts: rockchip: Add vdec node for RK3288 RK3288 contains a Rockchip VDEC block that only support HEVC decoding. Add a vdec node for this. @@ -10,11 +9,11 @@ decoding. Add a vdec node for this. Signed-off-by: Alex Bee Signed-off-by: Jonas Karlman --- - arch/arm/boot/dts/rockchip/rk3288.dtsi | 17 ++++++++++++++++- + arch/arm/boot/dts/rockchip/rk3288.dtsi | 17 +++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi -index 42d705b544ec..eab0c9a2d482 100644 +index 111111111111..222222222222 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi @@ -1293,6 +1293,21 @@ vpu_mmu: iommu@ff9a0800 { @@ -49,5 +48,5 @@ index 42d705b544ec..eab0c9a2d482 100644 gpu: gpu@ffa30000 { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0051-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Add-CEC-support.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0051-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Add-CEC-support.patch index 034d48505..b47476ec4 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0051-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Add-CEC-support.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0051-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Add-CEC-support.patch @@ -1,7 +1,7 @@ -From 792c0c64580b83df20052e21bd2bbb310b394010 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:50:59 +0300 -Subject: [PATCH 051/108] FROMLIST(v4): drm/bridge: dw-hdmi-qp: Add CEC support +Subject: FROMLIST(v4): drm/bridge: dw-hdmi-qp: Add CEC support Add support for the CEC interface of the Synopsys DesignWare HDMI QP TX controller. @@ -20,13 +20,13 @@ Reviewed-by: Dmitry Baryshkov Signed-off-by: Cristian Ciocaltea --- drivers/gpu/drm/bridge/synopsys/Kconfig | 8 + - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 212 +++++++++++++++++++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h | 14 ++ + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 212 ++++++++++ + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h | 14 + include/drm/bridge/dw_hdmi_qp.h | 1 + 4 files changed, 235 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig -index f3ab2f985f8c..99878f051067 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/Kconfig +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig @@ -54,6 +54,14 @@ config DRM_DW_HDMI_QP @@ -45,7 +45,7 @@ index f3ab2f985f8c..99878f051067 100644 tristate select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 8f5059edb582..1ab30dfaf988 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -18,6 +18,7 @@ @@ -309,7 +309,7 @@ index 8f5059edb582..1ab30dfaf988 100644 if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h -index 72987e6c4689..91a15f82e32a 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h @@ -488,9 +488,23 @@ @@ -337,7 +337,7 @@ index 72987e6c4689..91a15f82e32a 100644 #define CEC_TX_DATA3_0 0x1024 #define CEC_TX_DATA7_4 0x1028 diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h -index e9be6d507ad9..b4a9b739734e 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -23,6 +23,7 @@ struct dw_hdmi_qp_plat_data { @@ -349,5 +349,5 @@ index e9be6d507ad9..b4a9b739734e 100644 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0052-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Fixup-timer-base-s.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0052-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Fixup-timer-base-s.patch index 6b53b401f..a3c12e8da 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0052-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Fixup-timer-base-s.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0052-FROMLIST-v4-drm-bridge-dw-hdmi-qp-Fixup-timer-base-s.patch @@ -1,8 +1,7 @@ -From e22bf4ac4e23f523be5efa42f828f1aee065bcad Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:00 +0300 -Subject: [PATCH 052/108] FROMLIST(v4): drm/bridge: dw-hdmi-qp: Fixup timer - base setup +Subject: FROMLIST(v4): drm/bridge: dw-hdmi-qp: Fixup timer base setup Currently the TIMER_BASE_CONFIG0 register gets initialized to a fixed value as initially found in vendor driver code supporting the RK3588 @@ -21,12 +20,12 @@ dw_hdmi_qp_init_hw(). Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 12 +++++++++--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 12 +++++++--- include/drm/bridge/dw_hdmi_qp.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 1ab30dfaf988..a1fc3de58fb7 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -161,6 +161,7 @@ struct dw_hdmi_qp { @@ -67,7 +66,7 @@ index 1ab30dfaf988..a1fc3de58fb7 100644 ret = devm_request_threaded_irq(dev, plat_data->main_irq, diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h -index b4a9b739734e..76ecf3130199 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -24,6 +24,7 @@ struct dw_hdmi_qp_plat_data { @@ -79,5 +78,5 @@ index b4a9b739734e..76ecf3130199 100644 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0053-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Improve-error-ha.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0053-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Improve-error-ha.patch index ef735efb6..4acf8aa8c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0053-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Improve-error-ha.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0053-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Improve-error-ha.patch @@ -1,8 +1,8 @@ -From 72dda50cf756db33fb8ee40e861da77f4673d8c5 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:01 +0300 -Subject: [PATCH 053/108] FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Improve error - handling with dev_err_probe() +Subject: FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Improve error handling with + dev_err_probe() The error handling in dw_hdmi_qp_rockchip_bind() is quite inconsistent, i.e. in some cases the error code is not included in the message, while @@ -14,11 +14,11 @@ by switching to dev_err_probe(), which also reduces the code a bit. Reviewed-by: Daniel Stone Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 62 +++++++------------ + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 62 ++++------ 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 7d531b6f4c09..4e7794aa2dde 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -457,10 +457,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, @@ -126,5 +126,5 @@ index 7d531b6f4c09..4e7794aa2dde 100644 return drm_connector_attach_encoder(connector, encoder); } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0054-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-CEC-IRQ-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0054-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-CEC-IRQ-.patch index 13a1b6630..d074f238f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0054-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-CEC-IRQ-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0054-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-CEC-IRQ-.patch @@ -1,8 +1,8 @@ -From dc1e6185af563cfd6dcf4b927c5a519d4d42e8dc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:02 +0300 -Subject: [PATCH 054/108] FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Provide CEC - IRQ in dw_hdmi_qp_plat_data +Subject: FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Provide CEC IRQ in + dw_hdmi_qp_plat_data In order to support the CEC interface of the DesignWare HDMI QP IP block, setup platform data to include the required IRQ number. @@ -14,7 +14,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 4e7794aa2dde..39b46327afd8 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -527,6 +527,10 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, @@ -29,5 +29,5 @@ index 4e7794aa2dde..39b46327afd8 100644 if (irq < 0) return irq; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0055-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-ref-cloc.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0055-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-ref-cloc.patch index 04c055373..ecee7d4db 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0055-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-ref-cloc.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0055-FROMLIST-v4-drm-rockchip-dw_hdmi_qp-Provide-ref-cloc.patch @@ -1,8 +1,8 @@ -From bb8b943652a1bca73c6ca813e7f8dc0a88901880 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:03 +0300 -Subject: [PATCH 055/108] FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Provide ref - clock rate in dw_hdmi_qp_plat_data +Subject: FROMLIST(v4): drm/rockchip: dw_hdmi_qp: Provide ref clock rate in + dw_hdmi_qp_plat_data In order to support correct initialization of the timer base in the HDMI QP IP block, setup platform data to include the required reference clock @@ -14,11 +14,11 @@ dw_hdmi_qp_rockchip_bind(). Reviewed-by: Daniel Stone Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 11 ++++++++++- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 11 +++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 39b46327afd8..5280383febe2 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -431,14 +431,15 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, @@ -54,5 +54,5 @@ index 39b46327afd8..5280383febe2 100644 GPIOD_OUT_HIGH); if (IS_ERR(hdmi->enable_gpio)) -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0056-FROMLIST-v4-arm64-defconfig-Enable-DW-HDMI-QP-CEC-su.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0056-FROMLIST-v4-arm64-defconfig-Enable-DW-HDMI-QP-CEC-su.patch index 0e1d3c98f..85354893c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0056-FROMLIST-v4-arm64-defconfig-Enable-DW-HDMI-QP-CEC-su.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0056-FROMLIST-v4-arm64-defconfig-Enable-DW-HDMI-QP-CEC-su.patch @@ -1,8 +1,7 @@ -From fbd9100ef71d7b8ad4f38e070055a7c3f40a0a15 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:04 +0300 -Subject: [PATCH 056/108] FROMLIST(v4): arm64: defconfig: Enable DW HDMI QP CEC - support +Subject: FROMLIST(v4): arm64: defconfig: Enable DW HDMI QP CEC support Enable support for the CEC interface of the Synopsys DesignWare HDMI QP IP block. @@ -15,7 +14,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 58f87d09366c..fca9cca01449 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -963,6 +963,7 @@ CONFIG_DRM_CDNS_MHDP8546=m @@ -27,5 +26,5 @@ index 58f87d09366c..fca9cca01449 100644 CONFIG_DRM_V3D=m CONFIG_DRM_VC4=m -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0057-FROMLIST-v2-drm-rockchip-vop2-Check-bpc-before-switc.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0057-FROMLIST-v2-drm-rockchip-vop2-Check-bpc-before-switc.patch index e7b2d268d..f06a427dd 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0057-FROMLIST-v2-drm-rockchip-vop2-Check-bpc-before-switc.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0057-FROMLIST-v2-drm-rockchip-vop2-Check-bpc-before-switc.patch @@ -1,8 +1,8 @@ -From f5fcaa3b0bd4e940b09dc0bb62f5723380e5312b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 25 Aug 2025 13:08:32 +0300 -Subject: [PATCH 057/108] FROMLIST(v2): drm/rockchip: vop2: Check bpc before - switching DCLK source +Subject: FROMLIST(v2): drm/rockchip: vop2: Check bpc before switching DCLK + source When making use of the HDMI PHY PLL as a VOP2 DCLK source, it's output rate does normally match the mode clock. But this is only applicable @@ -20,11 +20,11 @@ source. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 60 ++++++++++++-------- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 60 ++++++---- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index b50927a824b4..977ccbf16344 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -101,7 +101,7 @@ enum vop2_afbc_format { @@ -109,5 +109,5 @@ index b50927a824b4..977ccbf16344 100644 } } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0058-FROMLIST-v2-drm-bridge-dw-hdmi-qp-Handle-platform-su.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0058-FROMLIST-v2-drm-bridge-dw-hdmi-qp-Handle-platform-su.patch index 46a05fa80..d1d640192 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0058-FROMLIST-v2-drm-bridge-dw-hdmi-qp-Handle-platform-su.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0058-FROMLIST-v2-drm-bridge-dw-hdmi-qp-Handle-platform-su.patch @@ -1,8 +1,8 @@ -From bcb6034e1f56e27cd5526f961f6d71c3a5bebea9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 25 Aug 2025 13:08:33 +0300 -Subject: [PATCH 058/108] FROMLIST(v2): drm/bridge: dw-hdmi-qp: Handle platform - supported formats and color depth +Subject: FROMLIST(v2): drm/bridge: dw-hdmi-qp: Handle platform supported + formats and color depth Extend struct dw_hdmi_qp_plat_data to include the supported display output formats and maximum bits per color channel. When provided by the @@ -13,12 +13,12 @@ to also show the current HDMI output format and bpc. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 11 +++++++++-- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 11 ++++++++-- include/drm/bridge/dw_hdmi_qp.h | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index a1fc3de58fb7..54377ba3a607 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -867,8 +867,9 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, @@ -47,7 +47,7 @@ index a1fc3de58fb7..54377ba3a607 100644 if (IS_ERR(hdmi->bridge.ddc)) return ERR_CAST(hdmi->bridge.ddc); diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h -index 76ecf3130199..3f461f6b9bbf 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -25,6 +25,10 @@ struct dw_hdmi_qp_plat_data { @@ -62,5 +62,5 @@ index 76ecf3130199..3f461f6b9bbf 100644 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0059-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Switch-to-phy_co.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0059-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Switch-to-phy_co.patch index c3e66d4f0..230e4131b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0059-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Switch-to-phy_co.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0059-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Switch-to-phy_co.patch @@ -1,8 +1,7 @@ -From 3498b6cf10a44db616505ddb82ac399be6bf867c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 25 Aug 2025 13:08:34 +0300 -Subject: [PATCH 059/108] FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Switch to - phy_configure() +Subject: FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Switch to phy_configure() Stop relying on phy_set_bus_width() based workaround to setup the TMDS character rate and, instead, use the recently introduced HDMI PHY @@ -19,11 +18,11 @@ this purpose. Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 37 ++++++++++--------- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 37 +++++----- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 5280383febe2..6f2006e7999b 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -13,6 +13,7 @@ @@ -98,5 +97,5 @@ index 5280383febe2..6f2006e7999b 100644 static const struct -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0060-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Use-bit-macros-f.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0060-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Use-bit-macros-f.patch index 7e5329d1c..2ee63dab9 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0060-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Use-bit-macros-f.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0060-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Use-bit-macros-f.patch @@ -1,8 +1,8 @@ -From 9edb994862d977209a27a5043bb3076d9c38b688 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 25 Aug 2025 13:08:35 +0300 -Subject: [PATCH 060/108] FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Use bit - macros for RK3576 regs +Subject: FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Use bit macros for RK3576 + regs For consistency and improved readability, redefine a few RK3576 specific register configurations by relying on GENMASK() and unshifted values for @@ -14,11 +14,11 @@ required. Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 21 +++++++------------ + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 21 ++++------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 6f2006e7999b..0f2b421134af 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -38,21 +38,16 @@ @@ -52,5 +52,5 @@ index 6f2006e7999b..0f2b421134af 100644 #define RK3576_I2S_SEL_MASK BIT(0) #define RK3576_SPDIF_SEL_MASK BIT(1) -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0061-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Add-high-color-d.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0061-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Add-high-color-d.patch index 1fbfc54d6..929611c0c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0061-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Add-high-color-d.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0061-FROMLIST-v2-drm-rockchip-dw_hdmi_qp-Add-high-color-d.patch @@ -1,8 +1,7 @@ -From 297e66d6175b36881e401d27baab14548b3feebc Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 25 Aug 2025 13:08:36 +0300 -Subject: [PATCH 061/108] FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Add high - color depth support +Subject: FROMLIST(v2): drm/rockchip: dw_hdmi_qp: Add high color depth support Since both RK3576 and RK3588 SoCs are capable of handling 10 bpc color depth, introduce a pair of new helpers to program the necessary @@ -18,11 +17,11 @@ assignments. Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 59 ++++++++++++++++++- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 59 +++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 0f2b421134af..81f106ac7b56 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -7,6 +7,7 @@ @@ -153,5 +152,5 @@ index 0f2b421134af..81f106ac7b56 100644 encoder = &hdmi->encoder.encoder; encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch index b995d8960..e34361684 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch @@ -1,8 +1,7 @@ -From 05a6c754cfa875530326c613a59785547de4dd91 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 18 Jul 2025 14:41:13 +0800 -Subject: [PATCH 062/108] FROMLIST(v1): drm/rockchip: vop2: Add delay between - poll registers +Subject: drm/rockchip: vop2: Add delay between poll registers According to the implementation of read_poll_timeout_atomic, if the delay time is 0, it will only use a simple loop based on timeout_us to @@ -17,7 +16,7 @@ Signed-off-by: Andy Yan 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c -index 42a4833a90a3..bf771b2f2188 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2066,7 +2066,7 @@ static void rk3568_vop2_wait_for_port_mux_done(struct vop2 *vop2) @@ -39,5 +38,5 @@ index 42a4833a90a3..bf771b2f2188 100644 DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n", atv_layer_cfg, cfg); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch index 6414cc12b..e20e6712f 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch @@ -1,8 +1,8 @@ -From ec1091a646f0e1fbe8d68c633628c213637029e2 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 18 Jul 2025 14:41:14 +0800 -Subject: [PATCH 063/108] FROMLIST(v1): drm/rockchip: vop2: Only wait for - changed layer cfg done when there is pending cfgdone bits +Subject: drm/rockchip: vop2: Only wait for changed layer cfg done when there + is pending cfgdone bits The write of cfgdone bits always done at .atomic_flush. When userspace makes plane zpos changes of two crtc within one commit, @@ -13,11 +13,11 @@ So only wait when there is pending cfgdone bits to avoid long timeout. Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568") Signed-off-by: Andy Yan --- - drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 13 +++++++++++-- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 13 ++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c -index bf771b2f2188..5a3d8c834ca9 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2106,6 +2106,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) @@ -48,5 +48,5 @@ index bf771b2f2188..5a3d8c834ca9 100644 vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); mutex_unlock(&vop2->ovl_lock); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch index 5a2eaadd0..a84c36433 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch @@ -1,8 +1,7 @@ -From 733ffb85946a2e09960fd43feea4421651b761b9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Tue, 24 Jun 2025 14:29:38 +0200 -Subject: [PATCH 064/108] FROMLIST(v1): media: verisilicon: Export only needed - pixels formats. +Subject: media: verisilicon: Export only needed pixels formats. When enumerating the pixels formats check if the context request to only export post-processed pixels formats. @@ -17,7 +16,7 @@ Reviewed-by: Nicolas Dufresne 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c -index 7c3515cf7d64..7869faf921f4 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -222,6 +222,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv, @@ -48,5 +47,5 @@ index 7c3515cf7d64..7869faf921f4 100644 bool mode_none = formats[i].codec_mode == HANTRO_MODE_NONE; fmt = &formats[i]; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch index 98b026e0f..ec14866ca 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch @@ -1,8 +1,8 @@ -From 896424a6dad60bb2faf5375765e559883cb9f31f Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 28 Aug 2025 01:49:00 +0000 -Subject: [PATCH 065/108] FROMLIST(v2): media: verisilicon: Explicitly disable - selection api ioctls for decoders +Subject: FROMLIST(v2): media: verisilicon: Explicitly disable selection api + ioctls for decoders Call the dedicated v4l2_disable_ioctl helper instead of manually checking whether the current context is an encoder for the selection @@ -16,7 +16,7 @@ Reviewed-by: Nicolas Dufresne 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c -index c31fd75902d4..df637f4a8827 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -928,6 +928,8 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) @@ -29,7 +29,7 @@ index c31fd75902d4..df637f4a8827 100644 video_set_drvdata(vfd, vpu); diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c -index 7869faf921f4..f7231a3d8183 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -667,8 +667,7 @@ static int vidioc_g_selection(struct file *file, void *priv, @@ -53,5 +53,5 @@ index 7869faf921f4..f7231a3d8183 100644 /* Change not allowed if the queue is streaming. */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch index 281c70feb..fdcb69bd7 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch @@ -1,8 +1,7 @@ -From f099b720f1cef83dd8073cb08b1d1272496d2695 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 23 Jun 2025 18:05:29 +0200 -Subject: [PATCH 066/108] DETLEV(v3): bitmap: introduce hardware-specific - bitfield operations +Subject: DETLEV(v3): bitmap: introduce hardware-specific bitfield operations Hardware of various vendors, but very notably Rockchip, often uses 32-bit registers where the upper 16-bit half of the register is a @@ -29,26 +28,12 @@ initializers, like FIELD_PREP_CONST. Suggested-by: Signed-off-by: Nicolas Frattaroli --- - MAINTAINERS | 1 + - include/linux/hw_bitfield.h | 62 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 63 insertions(+) - create mode 100644 include/linux/hw_bitfield.h + include/linux/hw_bitfield.h | 62 ++++++++++ + 1 file changed, 62 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index a19231134b01..db4cb02cf04e 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -4276,6 +4276,7 @@ F: include/linux/bits.h - F: include/linux/cpumask.h - F: include/linux/cpumask_types.h - F: include/linux/find.h -+F: include/linux/hw_bitfield.h - F: include/linux/nodemask.h - F: include/linux/nodemask_types.h - F: include/uapi/linux/bits.h diff --git a/include/linux/hw_bitfield.h b/include/linux/hw_bitfield.h new file mode 100644 -index 000000000000..df202e167ce4 +index 000000000000..111111111111 --- /dev/null +++ b/include/linux/hw_bitfield.h @@ -0,0 +1,62 @@ @@ -115,5 +100,5 @@ index 000000000000..df202e167ce4 + +#endif /* _LINUX_HW_BITFIELD_H */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch index 645aaa6c4..35af39e5b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch @@ -1,8 +1,7 @@ -From 2568fcb4a2bfc6388f1ef634986fa580c7b688dd Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 27 May 2025 11:00:22 -0400 -Subject: [PATCH 067/108] DETLEV(v3): media: rkvdec: Switch to using structs - instead of writel +Subject: DETLEV(v3): media: rkvdec: Switch to using structs instead of writel In an effort to merge the rkvdec2 driver [1] with this one, switch from writel() calls to using structs to represent the register mappings. @@ -40,16 +39,16 @@ This also shows that the fluster score hasn't changed. Signed-off-by: Detlev Casanova --- - .../platform/rockchip/rkvdec/rkvdec-h264.c | 165 +++-- - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 66 +- - .../platform/rockchip/rkvdec/rkvdec-regs.h | 571 ++++++++++++------ - .../platform/rockchip/rkvdec/rkvdec-vp9.c | 231 +++---- - .../media/platform/rockchip/rkvdec/rkvdec.c | 10 +- - .../media/platform/rockchip/rkvdec/rkvdec.h | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c | 165 ++- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 66 +- + drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h | 571 +++++++--- + drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c | 231 ++-- + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 10 +- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 + 6 files changed, 589 insertions(+), 455 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c -index d14b4d173448..1adb2e1f5f0e 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -115,6 +115,7 @@ struct rkvdec_h264_run { @@ -298,7 +297,7 @@ index d14b4d173448..1adb2e1f5f0e 100644 writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c -index fc7e6a260b0a..4de4a75f0f44 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -129,6 +129,7 @@ struct rkvdec_hevc_run { @@ -431,7 +430,7 @@ index fc7e6a260b0a..4de4a75f0f44 100644 writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h -index c627b6b6f53a..2d6ba5f1df9a 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h @@ -3,7 +3,12 @@ @@ -1023,7 +1022,7 @@ index c627b6b6f53a..2d6ba5f1df9a 100644 + #endif /* RKVDEC_REGS_H_ */ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c -index b4bf01e839ef..e1f6957ccdac 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c @@ -163,6 +163,7 @@ struct rkvdec_vp9_ctx { @@ -1397,7 +1396,7 @@ index b4bf01e839ef..e1f6957ccdac 100644 rkvdec_quirks_disable_qos(ctx); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index ef0ad92600f3..540d549ec08d 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -914,6 +914,15 @@ void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx) @@ -1425,7 +1424,7 @@ index ef0ad92600f3..540d549ec08d 100644 } } diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 892d2380b59d..9ffc3060ce25 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -151,6 +151,7 @@ struct rkvdec_aux_buf { @@ -1437,5 +1436,5 @@ index 892d2380b59d..9ffc3060ce25 100644 void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch index 135f31432..09f687b9d 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch @@ -1,23 +1,21 @@ -From 01b65b0e479cf2f72373fa2e57d6509bde350124 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 10:34:55 -0400 -Subject: [PATCH 068/108] DETLEV(v3): media: rkvdec: Move cabac tables to their - own source file +Subject: DETLEV(v3): media: rkvdec: Move cabac tables to their own source file This is in preparation to add support for new variants that will use the same tables. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Makefile | 7 +- - .../{rkvdec-hevc-data.c => rkvdec-cabac.c} | 506 +++++++++++++++++- - .../platform/rockchip/rkvdec/rkvdec-h264.c | 501 +---------------- - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 6 +- + drivers/media/platform/rockchip/rkvdec/Makefile | 7 +- + drivers/media/platform/rockchip/rkvdec/{rkvdec-hevc-data.c => rkvdec-cabac.c} | 506 +++++++++- + drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c | 501 +-------- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 6 +- 4 files changed, 514 insertions(+), 506 deletions(-) - rename drivers/media/platform/rockchip/rkvdec/{rkvdec-hevc-data.c => rkvdec-cabac.c} (86%) diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index a77122641d14..a8ff5e3d7bec 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -1,3 +1,8 @@ @@ -34,7 +32,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c b/drivers similarity index 86% rename from drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c rename to drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c -index eac4ea604949..bc87f59636ea 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-data.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c @@ -1,19 +1,517 @@ @@ -560,7 +558,7 @@ index eac4ea604949..bc87f59636ea 100644 0x68, 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, 0x40, 0x68, 0x58, 0x60, 0x40, 0x1f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x60, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c -index 1adb2e1f5f0e..15f2378bbc02 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -15,6 +15,8 @@ @@ -1079,7 +1077,7 @@ index 1adb2e1f5f0e..15f2378bbc02 100644 { u8 bit = field.offset % 32, word = field.offset / 32; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c -index 4de4a75f0f44..e8b8b7bc6cdc 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -16,7 +16,6 @@ @@ -1110,5 +1108,5 @@ index 4de4a75f0f44..e8b8b7bc6cdc 100644 struct rkvdec_sps_pps_packet param_set[RKV_PPS_LEN]; struct rkvdec_rps_packet rps[RKV_RPS_LEN]; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0069-DETLEV-v3-media-rkvdec-Use-structs-to-represent-the-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0069-DETLEV-v3-media-rkvdec-Use-structs-to-represent-the-.patch index af99ffa02..22c9a50c7 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0069-DETLEV-v3-media-rkvdec-Use-structs-to-represent-the-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0069-DETLEV-v3-media-rkvdec-Use-structs-to-represent-the-.patch @@ -1,8 +1,7 @@ -From 44fc0f7334d7b7818e2ee63bd1d22692c49d9883 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Wed, 11 Jun 2025 12:28:56 -0400 -Subject: [PATCH 069/108] DETLEV(v3): media: rkvdec: Use structs to represent - the HW RPS +Subject: DETLEV(v3): media: rkvdec: Use structs to represent the HW RPS This is in preparation to add support for other variants of the decoder. @@ -11,11 +10,11 @@ support that is present in e.g. rk3588. Signed-off-by: Detlev Casanova --- - .../platform/rockchip/rkvdec/rkvdec-h264.c | 97 ++++++++++++++++--- + drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c | 97 ++++++++-- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c -index 15f2378bbc02..3527919aa8ff 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -19,7 +19,6 @@ extern const s8 rkvdec_h264_cabac_table[4][464][2]; @@ -167,5 +166,5 @@ index 15f2378bbc02..3527919aa8ff 100644 } } -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0070-DETLEV-v3-media-rkvdec-Move-h264-functions-to-common.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0070-DETLEV-v3-media-rkvdec-Move-h264-functions-to-common.patch index edb3b98f0..1f1efa5bd 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0070-DETLEV-v3-media-rkvdec-Move-h264-functions-to-common.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0070-DETLEV-v3-media-rkvdec-Move-h264-functions-to-common.patch @@ -1,8 +1,7 @@ -From c7b2662ce199453cd088ea7568849fa4ef09e854 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 13:16:24 -0400 -Subject: [PATCH 070/108] DETLEV(v3): media: rkvdec: Move h264 functions to - common file +Subject: DETLEV(v3): media: rkvdec: Move h264 functions to common file This is a preparation commit to add support for new variants of the decoder. @@ -12,16 +11,14 @@ The functions will later be shared with vdpu381 (rk3588) and vdpu383 Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Makefile | 1 + - .../rockchip/rkvdec/rkvdec-h264-common.c | 253 ++++++++++++++ - .../rockchip/rkvdec/rkvdec-h264-common.h | 79 +++++ - .../platform/rockchip/rkvdec/rkvdec-h264.c | 308 +----------------- + drivers/media/platform/rockchip/rkvdec/Makefile | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c | 253 ++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h | 79 +++ + drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c | 308 +--------- 4 files changed, 337 insertions(+), 304 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index a8ff5e3d7bec..d2ba7a7c15e5 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -4,5 +4,6 @@ rockchip-vdec-y += \ @@ -33,7 +30,7 @@ index a8ff5e3d7bec..d2ba7a7c15e5 100644 rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c new file mode 100644 -index 000000000000..e7557c3a5cfa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c @@ -0,0 +1,253 @@ @@ -292,7 +289,7 @@ index 000000000000..e7557c3a5cfa + diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h new file mode 100644 -index 000000000000..df95a1678734 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h @@ -0,0 +1,79 @@ @@ -376,7 +373,7 @@ index 000000000000..df95a1678734 +int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, const struct v4l2_ctrl_h264_sps *sps); +void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c -index 3527919aa8ff..a80b5b44a570 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -14,6 +14,7 @@ @@ -756,5 +753,5 @@ index 3527919aa8ff..a80b5b44a570 100644 rkvdec_run_postamble(ctx, &run.base); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0071-DETLEV-v3-media-rkvdec-Move-hevc-functions-to-common.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0071-DETLEV-v3-media-rkvdec-Move-hevc-functions-to-common.patch index 7b56efabe..736ba7988 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0071-DETLEV-v3-media-rkvdec-Move-hevc-functions-to-common.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0071-DETLEV-v3-media-rkvdec-Move-hevc-functions-to-common.patch @@ -1,8 +1,7 @@ -From c9b6428c52f3bdb692e8cbaa8aec2cdcfecc66ef Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Fri, 15 Aug 2025 17:24:37 -0400 -Subject: [PATCH 071/108] DETLEV(v3): media: rkvdec: Move hevc functions to - common file +Subject: DETLEV(v3): media: rkvdec: Move hevc functions to common file This is a preparation commit to add support for new variants of the decoder. @@ -12,16 +11,14 @@ The functions will later be shared with vdpu381 (rk3588) and vdpu383 Signed-off-by: Detlev Casanova --- - .../rockchip/rkvdec/rkvdec-hevc-common.c | 230 +++++++++++++++++ - .../rockchip/rkvdec/rkvdec-hevc-common.h | 46 ++++ - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 240 +----------------- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c | 230 +++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h | 46 ++ + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 240 +--------- 3 files changed, 282 insertions(+), 234 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c new file mode 100644 -index 000000000000..6fd3b703ac11 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c @@ -0,0 +1,230 @@ @@ -257,7 +254,7 @@ index 000000000000..6fd3b703ac11 +} diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h new file mode 100644 -index 000000000000..bebab62a861e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h @@ -0,0 +1,46 @@ @@ -308,7 +305,7 @@ index 000000000000..bebab62a861e +int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); +void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c -index e8b8b7bc6cdc..887b6c165a7e 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -16,6 +16,7 @@ @@ -612,5 +609,5 @@ index e8b8b7bc6cdc..887b6c165a7e 100644 .adjust_fmt = rkvdec_hevc_adjust_fmt, .start = rkvdec_hevc_start, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0072-DETLEV-v3-media-rkvdec-Add-per-variant-configuration.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0072-DETLEV-v3-media-rkvdec-Add-per-variant-configuration.patch index 0d73c7685..7a0ad194c 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0072-DETLEV-v3-media-rkvdec-Add-per-variant-configuration.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0072-DETLEV-v3-media-rkvdec-Add-per-variant-configuration.patch @@ -1,20 +1,19 @@ -From f76fef2efa1a4fe481e10c118870cb54d349c5a2 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 14:05:08 -0400 -Subject: [PATCH 072/108] DETLEV(v3): media: rkvdec: Add per variant - configuration +Subject: DETLEV(v3): media: rkvdec: Add per variant configuration This is to prepare for adding different variants of the decoder and support specific formats and ops. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/rkvdec.c | 33 +++++++++++++------ - .../media/platform/rockchip/rkvdec/rkvdec.h | 11 ++++++- + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 33 +++++++--- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 11 +++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 540d549ec08d..033c03051f2e 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -390,12 +390,13 @@ rkvdec_enum_coded_fmt_desc(struct rkvdec_ctx *ctx, int index) @@ -101,7 +100,7 @@ index 540d549ec08d..033c03051f2e 100644 INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 9ffc3060ce25..d8a1b3e8e0ef 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -70,8 +70,9 @@ vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) @@ -138,5 +137,5 @@ index 9ffc3060ce25..d8a1b3e8e0ef 100644 struct rkvdec_ctx { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0073-DETLEV-v3-media-rkvdec-Add-RCB-and-SRAM-support.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0073-DETLEV-v3-media-rkvdec-Add-RCB-and-SRAM-support.patch index 1248ce5f0..160a72f6d 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0073-DETLEV-v3-media-rkvdec-Add-RCB-and-SRAM-support.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0073-DETLEV-v3-media-rkvdec-Add-RCB-and-SRAM-support.patch @@ -1,7 +1,7 @@ -From 3beb7a1601be3f294c3352ccca0b93cb290bbaa8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 14:53:27 -0400 -Subject: [PATCH 073/108] DETLEV(v3): media: rkvdec: Add RCB and SRAM support +Subject: DETLEV(v3): media: rkvdec: Add RCB and SRAM support The RCB (Rows and Cols Buffers) are a set of buffers used by other variations of the decoder to store temporary data. @@ -23,17 +23,15 @@ This commit is in preparation of other variants support. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Makefile | 1 + - .../platform/rockchip/rkvdec/rkvdec-rcb.c | 174 ++++++++++++++++++ - .../platform/rockchip/rkvdec/rkvdec-rcb.h | 29 +++ - .../media/platform/rockchip/rkvdec/rkvdec.c | 29 ++- - .../media/platform/rockchip/rkvdec/rkvdec.h | 13 ++ + drivers/media/platform/rockchip/rkvdec/Makefile | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c | 174 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h | 29 ++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 29 +- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 13 + 5 files changed, 242 insertions(+), 4 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index d2ba7a7c15e5..3b34f39b17d6 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -6,4 +6,5 @@ rockchip-vdec-y += \ @@ -44,7 +42,7 @@ index d2ba7a7c15e5..3b34f39b17d6 100644 rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c new file mode 100644 -index 000000000000..210e59db2c62 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c @@ -0,0 +1,174 @@ @@ -224,7 +222,7 @@ index 000000000000..210e59db2c62 + diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h new file mode 100644 -index 000000000000..30e8002555c8 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h @@ -0,0 +1,29 @@ @@ -258,7 +256,7 @@ index 000000000000..30e8002555c8 +int rkvdec_rcb_buf_count(struct rkvdec_ctx *ctx); +void rkvdec_free_rcb(struct rkvdec_ctx *ctx); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 033c03051f2e..19deb1d34a18 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -10,6 +10,7 @@ @@ -360,7 +358,7 @@ index 033c03051f2e..19deb1d34a18 100644 } diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index d8a1b3e8e0ef..86d1af5dee5e 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -19,6 +19,7 @@ @@ -423,5 +421,5 @@ index d8a1b3e8e0ef..86d1af5dee5e 100644 void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0074-DETLEV-v3-media-rkvdec-Support-per-variant-interrupt.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0074-DETLEV-v3-media-rkvdec-Support-per-variant-interrupt.patch index d8790941b..c537198bc 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0074-DETLEV-v3-media-rkvdec-Support-per-variant-interrupt.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0074-DETLEV-v3-media-rkvdec-Support-per-variant-interrupt.patch @@ -1,20 +1,19 @@ -From c6b8b1969778e5e3fe6e805cbd087b1fbd64c73a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 15:13:46 -0400 -Subject: [PATCH 074/108] DETLEV(v3): media: rkvdec: Support per-variant - interrupt handler +Subject: DETLEV(v3): media: rkvdec: Support per-variant interrupt handler Preparation commit for supporting different variants with different interrupt management. Signed-off-by: Detlev Casanova --- - drivers/media/platform/rockchip/rkvdec/rkvdec.c | 15 ++++++++++++--- + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 15 ++++++++-- drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 19deb1d34a18..a0dca7bff071 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -1218,10 +1218,9 @@ static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec) @@ -55,7 +54,7 @@ index 19deb1d34a18..a0dca7bff071 100644 static const struct rkvdec_variant rk3288_rkvdec_variant = { diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 86d1af5dee5e..117ebf198a1e 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -121,6 +121,7 @@ struct rkvdec_config { @@ -67,5 +66,5 @@ index 86d1af5dee5e..117ebf198a1e 100644 struct rkvdec_dev { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0075-DETLEV-v3-media-rkvdec-Enable-all-clocks-without-nam.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0075-DETLEV-v3-media-rkvdec-Enable-all-clocks-without-nam.patch index 8c6043b33..00c2c95b1 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0075-DETLEV-v3-media-rkvdec-Enable-all-clocks-without-nam.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0075-DETLEV-v3-media-rkvdec-Enable-all-clocks-without-nam.patch @@ -1,8 +1,7 @@ -From 4533e8af728b440b1addd0115c52d67a2d2c0ac1 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 16:40:09 -0400 -Subject: [PATCH 075/108] DETLEV(v3): media: rkvdec: Enable all clocks without - naming them +Subject: DETLEV(v3): media: rkvdec: Enable all clocks without naming them For other variants, the clock names and number will differ. @@ -11,12 +10,12 @@ them to avoid having a list for each variant. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/rkvdec.c | 24 +++++-------------- - .../media/platform/rockchip/rkvdec/rkvdec.h | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 24 +++------- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 + 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index a0dca7bff071..3f9f2e8857f4 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -1311,15 +1311,10 @@ static const struct of_device_id of_rkvdec_match[] = { @@ -78,7 +77,7 @@ index a0dca7bff071..3f9f2e8857f4 100644 return 0; } diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 117ebf198a1e..5c238e443d7d 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -131,6 +131,7 @@ struct rkvdec_dev { @@ -90,5 +89,5 @@ index 117ebf198a1e..5c238e443d7d 100644 struct mutex vdev_lock; /* serializes ioctls */ struct delayed_work watchdog_work; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0076-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0076-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch index 8fd498c2d..2616d9219 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0076-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0076-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch @@ -1,8 +1,7 @@ -From d8d4918709c884597c505f70a6dead48581699e9 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 15:53:52 -0400 -Subject: [PATCH 076/108] DETLEV(v3): media: rkvdec: Add H264 support for the - VDPU381 variant +Subject: DETLEV(v3): media: rkvdec: Add H264 support for the VDPU381 variant This decoder variant is found in Rockchip RK3588 SoC family. @@ -19,19 +18,17 @@ Fluster score for JVT-AVC_V1 is 129/135. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Makefile | 1 + - .../rockchip/rkvdec/rkvdec-h264-common.h | 2 + - .../platform/rockchip/rkvdec/rkvdec-h264.c | 2 - - .../rockchip/rkvdec/rkvdec-vdpu381-h264.c | 469 ++++++++++++++++++ - .../rockchip/rkvdec/rkvdec-vdpu381-regs.h | 427 ++++++++++++++++ - .../media/platform/rockchip/rkvdec/rkvdec.c | 173 ++++++- - .../media/platform/rockchip/rkvdec/rkvdec.h | 6 + + drivers/media/platform/rockchip/rkvdec/Makefile | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h | 2 + + drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c | 2 - + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c | 469 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h | 427 +++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 173 +++- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 6 + 7 files changed, 1076 insertions(+), 4 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index 3b34f39b17d6..c4167eb6fc79 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -7,4 +7,5 @@ rockchip-vdec-y += \ @@ -41,7 +38,7 @@ index 3b34f39b17d6..c4167eb6fc79 100644 + rkvdec-vdpu381-h264.o \ rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h -index df95a1678734..38446e2886e3 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h @@ -66,6 +66,8 @@ struct rkvdec_rps { @@ -54,7 +51,7 @@ index df95a1678734..38446e2886e3 100644 void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder, struct rkvdec_h264_run *run, diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c -index a80b5b44a570..d50e985cff95 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -16,8 +16,6 @@ @@ -68,7 +65,7 @@ index a80b5b44a570..d50e985cff95 100644 #define RKV_ERROR_INFO_SIZE (256 * 144 * 4) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c new file mode 100644 -index 000000000000..e65a56bc9c63 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c @@ -0,0 +1,469 @@ @@ -543,7 +540,7 @@ index 000000000000..e65a56bc9c63 +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h new file mode 100644 -index 000000000000..11b545e9ee7e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h @@ -0,0 +1,427 @@ @@ -975,7 +972,7 @@ index 000000000000..11b545e9ee7e + +#endif /* __RKVDEC_REGS_H__ */ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index 3f9f2e8857f4..b8efee7af74c 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -29,6 +29,7 @@ @@ -1220,7 +1217,7 @@ index 3f9f2e8857f4..b8efee7af74c 100644 rkvdec->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rkvdec->regs)) diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 5c238e443d7d..23c5237de5f7 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -122,6 +122,8 @@ struct rkvdec_config { @@ -1256,5 +1253,5 @@ index 5c238e443d7d..23c5237de5f7 100644 + #endif /* RKVDEC_H_ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0077-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0077-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch index f6822ec8b..1dcc2945e 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0077-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0077-DETLEV-v3-media-rkvdec-Add-H264-support-for-the-VDPU.patch @@ -1,8 +1,7 @@ -From f4b2e0c1cce961b7a1abd8bb27760857af6e7faa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Tue, 10 Jun 2025 17:45:17 -0400 -Subject: [PATCH 077/108] DETLEV(v3): media: rkvdec: Add H264 support for the - VDPU383 variant +Subject: DETLEV(v3): media: rkvdec: Add H264 support for the VDPU383 variant This variant is used on the RK3576 SoC. @@ -17,23 +16,20 @@ The other test suites are not supported yet. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Kconfig | 1 + - .../media/platform/rockchip/rkvdec/Makefile | 3 + - .../rockchip/rkvdec/rkvdec-hevc-common.c | 413 ++++++++++-- - .../rockchip/rkvdec/rkvdec-hevc-common.h | 84 ++- - .../platform/rockchip/rkvdec/rkvdec-hevc.c | 5 +- - .../rockchip/rkvdec/rkvdec-vdpu381-hevc.c | 588 ++++++++++++++++++ - .../rockchip/rkvdec/rkvdec-vdpu383-h264.c | 582 +++++++++++++++++ - .../rockchip/rkvdec/rkvdec-vdpu383-regs.h | 284 +++++++++ - .../media/platform/rockchip/rkvdec/rkvdec.c | 212 ++++++- - .../media/platform/rockchip/rkvdec/rkvdec.h | 10 +- + drivers/media/platform/rockchip/rkvdec/Kconfig | 1 + + drivers/media/platform/rockchip/rkvdec/Makefile | 3 + + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c | 413 ++++++- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h | 84 +- + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 5 +- + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c | 588 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c | 582 +++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h | 284 +++++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 212 +++- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 10 +- 10 files changed, 2109 insertions(+), 73 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h diff --git a/drivers/media/platform/rockchip/rkvdec/Kconfig b/drivers/media/platform/rockchip/rkvdec/Kconfig -index 5f3bdd848a2c..3303b0ce3280 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Kconfig +++ b/drivers/media/platform/rockchip/rkvdec/Kconfig @@ -8,6 +8,7 @@ config VIDEO_ROCKCHIP_VDEC @@ -45,7 +41,7 @@ index 5f3bdd848a2c..3303b0ce3280 100644 help Support for the Rockchip Video Decoder IP present on Rockchip SoCs, diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index c4167eb6fc79..e30fdd7d51c3 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -6,6 +6,9 @@ rockchip-vdec-y += \ @@ -59,7 +55,7 @@ index c4167eb6fc79..e30fdd7d51c3 100644 + rkvdec-vdpu383-h264.o \ rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c -index 6fd3b703ac11..3646b3ce4ea0 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c @@ -18,6 +18,143 @@ @@ -556,7 +552,7 @@ index 6fd3b703ac11..3646b3ce4ea0 100644 rkvdec_run_preamble(ctx, &run->base); } diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h -index bebab62a861e..da58da149566 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h @@ -15,14 +15,68 @@ @@ -666,7 +662,7 @@ index bebab62a861e..da58da149566 100644 int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c -index 887b6c165a7e..b28d54b8bb57 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -25,9 +25,6 @@ @@ -690,7 +686,7 @@ index 887b6c165a7e..b28d54b8bb57 100644 assemble_sw_rps(ctx, &run); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c new file mode 100644 -index 000000000000..96dfa3576a8b +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c @@ -0,0 +1,588 @@ @@ -1284,7 +1280,7 @@ index 000000000000..96dfa3576a8b +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c new file mode 100644 -index 000000000000..bb2c62d9c3d4 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c @@ -0,0 +1,582 @@ @@ -1872,7 +1868,7 @@ index 000000000000..bb2c62d9c3d4 +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h new file mode 100644 -index 000000000000..2b614393a3af +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h @@ -0,0 +1,284 @@ @@ -2161,7 +2157,7 @@ index 000000000000..2b614393a3af + +#endif /* __RKVDEC_VDPU838_REGS_H__ */ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index b8efee7af74c..ad8ab9d37add 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -9,6 +9,7 @@ @@ -2475,7 +2471,7 @@ index b8efee7af74c..ad8ab9d37add 100644 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 23c5237de5f7..33cd3406b5ea 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -124,6 +124,8 @@ struct rkvdec_config { @@ -2516,5 +2512,5 @@ index 23c5237de5f7..33cd3406b5ea 100644 #endif /* RKVDEC_H_ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0078-DETLEV-v3-media-rkvdec-Add-HEVC-support-for-the-VDPU.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0078-DETLEV-v3-media-rkvdec-Add-HEVC-support-for-the-VDPU.patch index adcf21f0b..9f48054e6 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0078-DETLEV-v3-media-rkvdec-Add-HEVC-support-for-the-VDPU.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0078-DETLEV-v3-media-rkvdec-Add-HEVC-support-for-the-VDPU.patch @@ -1,8 +1,7 @@ -From 093791bfc067b55252555e4a05d7291baf4b6231 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Wed, 11 Jun 2025 17:04:28 -0400 -Subject: [PATCH 078/108] DETLEV(v3): media: rkvdec: Add HEVC support for the - VDPU383 variant +Subject: DETLEV(v3): media: rkvdec: Add HEVC support for the VDPU383 variant The VDPU383 decoder is used on the RK3576 SoC and has support for HEVC. @@ -13,16 +12,15 @@ The fluster score for JCT-VC-HEVC_V1 is 146/147. Signed-off-by: Detlev Casanova --- - .../media/platform/rockchip/rkvdec/Makefile | 1 + - .../rockchip/rkvdec/rkvdec-hevc-common.c | 49 +- - .../rockchip/rkvdec/rkvdec-vdpu383-hevc.c | 680 ++++++++++++++++++ - .../media/platform/rockchip/rkvdec/rkvdec.c | 94 ++- - .../media/platform/rockchip/rkvdec/rkvdec.h | 2 + + drivers/media/platform/rockchip/rkvdec/Makefile | 1 + + drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c | 49 +- + drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c | 680 ++++++++++ + drivers/media/platform/rockchip/rkvdec/rkvdec.c | 94 +- + drivers/media/platform/rockchip/rkvdec/rkvdec.h | 2 + 5 files changed, 783 insertions(+), 43 deletions(-) - create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile -index e30fdd7d51c3..e629d571e4d8 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -11,4 +11,5 @@ rockchip-vdec-y += \ @@ -32,7 +30,7 @@ index e30fdd7d51c3..e629d571e4d8 100644 + rkvdec-vdpu383-hevc.o \ rkvdec-vp9.o diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c -index 3646b3ce4ea0..e5d240d97792 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c @@ -155,60 +155,25 @@ static void set_ref_poc(struct rkvdec_rps_short_term_ref_set *set, int poc, int @@ -105,7 +103,7 @@ index 3646b3ce4ea0..e5d240d97792 100644 } diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c new file mode 100644 -index 000000000000..7d53c28e954e +index 000000000000..111111111111 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c @@ -0,0 +1,680 @@ @@ -790,7 +788,7 @@ index 000000000000..7d53c28e954e + .get_image_fmt = rkvdec_hevc_get_image_fmt, +}; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -index ad8ab9d37add..1e263f6d73b8 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -526,6 +526,22 @@ static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = { @@ -930,7 +928,7 @@ index ad8ab9d37add..1e263f6d73b8 100644 static const struct of_device_id of_rkvdec_match[] = { diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h -index 33cd3406b5ea..aa77b6f69d62 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h @@ -125,6 +125,7 @@ struct rkvdec_config { @@ -949,5 +947,5 @@ index 33cd3406b5ea..aa77b6f69d62 100644 #endif /* RKVDEC_H_ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0079-FROMLIST-v1-phy-rockchip-samsung-hdptx-Fix-reported-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0079-FROMLIST-v1-phy-rockchip-samsung-hdptx-Fix-reported-.patch index 588d6dfab..fc1129383 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0079-FROMLIST-v1-phy-rockchip-samsung-hdptx-Fix-reported-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0079-FROMLIST-v1-phy-rockchip-samsung-hdptx-Fix-reported-.patch @@ -1,8 +1,8 @@ -From e188edc9095f85bf1b31fef871b71fa2ed215d0c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 28 Jul 2025 22:52:42 +0300 -Subject: [PATCH 079/108] FROMLIST(v1): phy: rockchip: samsung-hdptx: Fix - reported clock rate in high bpc mode +Subject: phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc + mode When making use of the clock provider functionality, the output clock does normally match the TMDS character rate, which is what the PHY PLL @@ -22,11 +22,11 @@ Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth managem Reported-by: Andy Yan Signed-off-by: Cristian Ciocaltea --- - drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------ + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++---- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 79db57ee90d1..8adf6e84fc0b 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1038,7 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) @@ -66,5 +66,5 @@ index 79db57ee90d1..8adf6e84fc0b 100644 /* -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0080-FROMLIST-v1-phy-rockchip-samsung-hdptx-Reduce-ROPLL-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0080-FROMLIST-v1-phy-rockchip-samsung-hdptx-Reduce-ROPLL-.patch index 87fe4e998..095eb7718 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0080-FROMLIST-v1-phy-rockchip-samsung-hdptx-Reduce-ROPLL-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0080-FROMLIST-v1-phy-rockchip-samsung-hdptx-Reduce-ROPLL-.patch @@ -1,8 +1,7 @@ -From 72423228c09903350f4fffb49725a6974e708d63 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 5 Jun 2025 20:09:27 +0300 -Subject: [PATCH 080/108] FROMLIST(v1): phy: rockchip: samsung-hdptx: Reduce - ROPLL loop bandwidth +Subject: phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth Due to its relatively low frequency, a noise stemming from the 24MHz PLL reference clock may traverse the low-pass loop filter of ROPLL, which @@ -19,7 +18,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 8adf6e84fc0b..9751f7ad00f4 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { @@ -42,5 +41,5 @@ index 8adf6e84fc0b..9751f7ad00f4 100644 REG_SEQ0(CMN_REG(005c), 0x25), REG_SEQ0(CMN_REG(005e), 0x4f), -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0081-FROMLIST-v1-phy-rockchip-samsung-hdptx-Prevent-Inter.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0081-FROMLIST-v1-phy-rockchip-samsung-hdptx-Prevent-Inter.patch index 47bededcd..6ac608c99 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0081-FROMLIST-v1-phy-rockchip-samsung-hdptx-Prevent-Inter.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0081-FROMLIST-v1-phy-rockchip-samsung-hdptx-Prevent-Inter.patch @@ -1,8 +1,8 @@ -From 3b9abe6ec5bea5ccedaec0b955704a2f6401b717 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 5 Jun 2025 22:33:29 +0300 -Subject: [PATCH 081/108] FROMLIST(v1): phy: rockchip: samsung-hdptx: Prevent - Inter-Pair Skew from exceeding the limits +Subject: phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding + the limits Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of other lanes. It's worth noting this might only happen when dealing with @@ -17,7 +17,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 9751f7ad00f4..5605610465bc 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { @@ -47,5 +47,5 @@ index 9751f7ad00f4..5605610465bc 100644 static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0082-FROMLIST-v4-phy-hdmi-Add-HDMI-2.1-FRL-configuration-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0082-FROMLIST-v4-phy-hdmi-Add-HDMI-2.1-FRL-configuration-.patch index a61f71633..41fb58e8d 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0082-FROMLIST-v4-phy-hdmi-Add-HDMI-2.1-FRL-configuration-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0082-FROMLIST-v4-phy-hdmi-Add-HDMI-2.1-FRL-configuration-.patch @@ -1,8 +1,7 @@ -From 37d415b4ca7709e66a731960de178d2b8f037238 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 30 May 2025 00:56:48 +0300 -Subject: [PATCH 082/108] FROMLIST(v4): phy: hdmi: Add HDMI 2.1 FRL - configuration options +Subject: FROMLIST(v4): phy: hdmi: Add HDMI 2.1 FRL configuration options The HDMI 2.1 specification introduced the Fixed Rate Link (FRL) mode, aiming to replace the older Transition-Minimized Differential Signaling @@ -19,11 +18,11 @@ Add support for configuring the FRL mode for HDMI PHYs. Signed-off-by: Cristian Ciocaltea --- - include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++-- + include/linux/phy/phy-hdmi.h | 19 +++++++++- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h -index f0ec963c6e84..d4cf4430ee8f 100644 +index 111111111111..222222222222 100644 --- a/include/linux/phy/phy-hdmi.h +++ b/include/linux/phy/phy-hdmi.h @@ -6,16 +6,31 @@ @@ -61,5 +60,5 @@ index f0ec963c6e84..d4cf4430ee8f 100644 #endif /* __PHY_HDMI_H_ */ -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0083-FROMLIST-v4-phy-rockchip-samsung-hdptx-Use-usleep_ra.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0083-FROMLIST-v4-phy-rockchip-samsung-hdptx-Use-usleep_ra.patch index 378c9def5..72d9e90f7 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0083-FROMLIST-v4-phy-rockchip-samsung-hdptx-Use-usleep_ra.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0083-FROMLIST-v4-phy-rockchip-samsung-hdptx-Use-usleep_ra.patch @@ -1,8 +1,8 @@ -From 619a6bd21c5e9614436d0c10593c69f2459f3593 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 28 May 2025 13:21:49 +0300 -Subject: [PATCH 083/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Use - usleep_range() instead of udelay() +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Use usleep_range() + instead of udelay() rk_hdptx_dp_reset() is allowed to sleep, hence replace the busy waiting with usleep_range(), to allow other threads to run. @@ -13,7 +13,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 5605610465bc..83ec892bd676 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1075,7 +1075,7 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx) @@ -26,5 +26,5 @@ index 5605610465bc..83ec892bd676 100644 regmap_update_bits(hdptx->regmap, LANE_REG(0301), -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0084-FROMLIST-v4-phy-rockchip-samsung-hdptx-Fix-coding-st.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0084-FROMLIST-v4-phy-rockchip-samsung-hdptx-Fix-coding-st.patch index d8f357446..d3980750b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0084-FROMLIST-v4-phy-rockchip-samsung-hdptx-Fix-coding-st.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0084-FROMLIST-v4-phy-rockchip-samsung-hdptx-Fix-coding-st.patch @@ -1,8 +1,8 @@ -From 0b918f0ad444ecd4724ff9cdc3012c5e0b9a46aa Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 28 May 2025 13:35:01 +0300 -Subject: [PATCH 084/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Fix - coding style alignment +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Fix coding style + alignment Handle a bunch of reported checkpatch.pl complaints: @@ -10,11 +10,11 @@ Handle a bunch of reported checkpatch.pl complaints: Signed-off-by: Cristian Ciocaltea --- - drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 12 ++++++------ + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 12 +++++----- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 83ec892bd676..495427fc44b3 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1657,11 +1657,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx, @@ -60,5 +60,5 @@ index 83ec892bd676..495427fc44b3 100644 LN_TX_SER_40BIT_EN_HBR2_MASK, FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1)); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0085-FROMLIST-v4-phy-rockchip-samsung-hdptx-Consistently-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0085-FROMLIST-v4-phy-rockchip-samsung-hdptx-Consistently-.patch index 6522e0dd7..94e254da5 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0085-FROMLIST-v4-phy-rockchip-samsung-hdptx-Consistently-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0085-FROMLIST-v4-phy-rockchip-samsung-hdptx-Consistently-.patch @@ -1,8 +1,8 @@ -From 4791689329ad6f2825579aa8a175bc0ea9d5be9a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 4 Jun 2025 12:03:11 +0300 -Subject: [PATCH 085/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: - Consistently use [rk_]hdptx_[tmds_] prefixes +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Consistently use + [rk_]hdptx_[tmds_] prefixes Fix the naming inconsistencies for some of the functions and global variables: @@ -13,11 +13,11 @@ variables: Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 62 +++++++++---------- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 62 +++++----- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 495427fc44b3..f2202b1195e7 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -32,17 +32,17 @@ @@ -222,5 +222,5 @@ index 495427fc44b3..f2202b1195e7 100644 static const struct clk_ops hdptx_phy_clk_ops = { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0086-FROMLIST-v4-phy-rockchip-samsung-hdptx-Enable-lane-o.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0086-FROMLIST-v4-phy-rockchip-samsung-hdptx-Enable-lane-o.patch index 98f434fa1..738980dc8 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0086-FROMLIST-v4-phy-rockchip-samsung-hdptx-Enable-lane-o.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0086-FROMLIST-v4-phy-rockchip-samsung-hdptx-Enable-lane-o.patch @@ -1,8 +1,8 @@ -From 5b006eeec285767ac34a21e70e186833d21a1a21 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 4 Jun 2025 10:25:49 +0300 -Subject: [PATCH 086/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Enable - lane output in common helper +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Enable lane output in + common helper In preparation to support FRL mode, move the PHY lane output enablement from the TMDS specific configuration to the common *_post_enable_lane() @@ -14,7 +14,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index f2202b1195e7..3bb4ce993088 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -830,6 +830,8 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx) @@ -43,5 +43,5 @@ index f2202b1195e7..3bb4ce993088 100644 rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq); rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0087-FROMLIST-v4-phy-rockchip-samsung-hdptx-Cleanup-_cmn_.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0087-FROMLIST-v4-phy-rockchip-samsung-hdptx-Cleanup-_cmn_.patch index da3ca90d9..d8db01c05 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0087-FROMLIST-v4-phy-rockchip-samsung-hdptx-Cleanup-_cmn_.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0087-FROMLIST-v4-phy-rockchip-samsung-hdptx-Cleanup-_cmn_.patch @@ -1,8 +1,8 @@ -From b0bb97f5d92761409c626b98ebe9e1ff5d9788ef Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 5 Jun 2025 21:31:22 +0300 -Subject: [PATCH 087/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Cleanup - *_cmn_init_seq lists +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Cleanup *_cmn_init_seq + lists Drop redundant reg_sequence entries from rk_hdptx_common_cmn_init_seq[], i.e. those that are either duplicated or overridden in @@ -16,11 +16,11 @@ No functional changes intended at this point. Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 22 ++++--------------- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 22 ++-------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 3bb4ce993088..699b86732b8d 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -465,13 +465,11 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = { @@ -111,5 +111,5 @@ index 3bb4ce993088..699b86732b8d 100644 REG_SEQ0(CMN_REG(0089), 0x00), REG_SEQ0(CMN_REG(0095), 0x00), -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0088-FROMLIST-v4-phy-rockchip-samsung-hdptx-Compute-clk-r.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0088-FROMLIST-v4-phy-rockchip-samsung-hdptx-Compute-clk-r.patch index f4723aae9..0f8718f6b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0088-FROMLIST-v4-phy-rockchip-samsung-hdptx-Compute-clk-r.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0088-FROMLIST-v4-phy-rockchip-samsung-hdptx-Compute-clk-r.patch @@ -1,8 +1,8 @@ -From 28365add3cd89ed89b26368df2adca48fa9bdd3c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 6 Jun 2025 18:18:23 +0300 -Subject: [PATCH 088/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Compute - clk rate from PLL config +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Compute clk rate from PLL + config Improve ->recalc_rate() callback of hdptx_phy_clk_ops to calculate the initial clock rate based on the actual PHY PLL configuration as @@ -10,11 +10,11 @@ retrieved from the related hardware registers. Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 91 ++++++++++++++++++- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 91 +++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 699b86732b8d..6e2443f78968 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1851,12 +1851,101 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw) @@ -121,5 +121,5 @@ index 699b86732b8d..6e2443f78968 100644 static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0089-FROMLIST-v4-phy-rockchip-samsung-hdptx-Drop-hw_rate-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0089-FROMLIST-v4-phy-rockchip-samsung-hdptx-Drop-hw_rate-.patch index 63ea9c338..22cc4c327 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0089-FROMLIST-v4-phy-rockchip-samsung-hdptx-Drop-hw_rate-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0089-FROMLIST-v4-phy-rockchip-samsung-hdptx-Drop-hw_rate-.patch @@ -1,8 +1,7 @@ -From bbbde68b59ec0489a6d6f011ce90b104bbc0c782 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 1 Aug 2025 17:10:15 +0300 -Subject: [PATCH 089/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Drop - hw_rate driver data +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Drop hw_rate driver data The ->hw_rate member of struct rk_hdptx_phy was mainly used to keep track of the clock rate programmed in hardware and support implementing @@ -13,11 +12,11 @@ work reliably, hence remove the now redundant struct member. Signed-off-by: Cristian Ciocaltea --- - drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 13 ++----------- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 13 ++-------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 6e2443f78968..4195387108d8 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -401,7 +401,6 @@ struct rk_hdptx_phy { @@ -62,5 +61,5 @@ index 6e2443f78968..4195387108d8 100644 if (ret || !(status & HDPTX_I_PLL_EN)) return 0; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0090-FROMLIST-v4-phy-rockchip-samsung-hdptx-Switch-to-dri.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0090-FROMLIST-v4-phy-rockchip-samsung-hdptx-Switch-to-dri.patch index 0186e3baa..09167326e 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0090-FROMLIST-v4-phy-rockchip-samsung-hdptx-Switch-to-dri.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0090-FROMLIST-v4-phy-rockchip-samsung-hdptx-Switch-to-dri.patch @@ -1,8 +1,8 @@ -From 2389df2772d3d3eacf1bb853567bec0516e14e36 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 7 Jul 2025 23:23:52 +0300 -Subject: [PATCH 090/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Switch to - driver specific HDMI config +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Switch to driver specific + HDMI config In preparation to support the FRL operation mode which gets configured via the lanes and rate per lane tuple, switch to a driver specific @@ -15,11 +15,11 @@ operating in FRL mode. Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 44 +++++++++++-------- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 44 ++++++---- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 4195387108d8..a44614bc73e9 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -387,6 +387,11 @@ struct rk_hdptx_phy_cfg { @@ -167,5 +167,5 @@ index 4195387108d8..a44614bc73e9 100644 /* -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0091-FROMLIST-v4-phy-rockchip-samsung-hdptx-Extend-rk_hdp.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0091-FROMLIST-v4-phy-rockchip-samsung-hdptx-Extend-rk_hdp.patch index a265c1b76..08d32df40 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0091-FROMLIST-v4-phy-rockchip-samsung-hdptx-Extend-rk_hdp.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0091-FROMLIST-v4-phy-rockchip-samsung-hdptx-Extend-rk_hdp.patch @@ -1,7 +1,7 @@ -From f3e898eab91001240ab1e3b3c9a0bea18db959fd Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 8 Jul 2025 12:19:37 +0300 -Subject: [PATCH 091/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Extend +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Extend rk_hdptx_phy_verify_hdmi_config() helper In order to facilitate introduction of HDMI 2.1 FRL support and to avoid @@ -14,11 +14,11 @@ parameter. Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 35 ++++++++++--------- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 35 +++++----- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index a44614bc73e9..58eac67cc3b2 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1472,25 +1472,24 @@ static int rk_hdptx_phy_power_off(struct phy *phy) @@ -112,5 +112,5 @@ index a44614bc73e9..58eac67cc3b2 100644 /* -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0092-FROMLIST-v4-phy-rockchip-samsung-hdptx-Add-HDMI-2.1-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0092-FROMLIST-v4-phy-rockchip-samsung-hdptx-Add-HDMI-2.1-.patch index f28e5a048..eedf9e334 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0092-FROMLIST-v4-phy-rockchip-samsung-hdptx-Add-HDMI-2.1-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0092-FROMLIST-v4-phy-rockchip-samsung-hdptx-Add-HDMI-2.1-.patch @@ -1,8 +1,7 @@ -From 2927cd7f8d3dfa8180a55c1bb394250e8472f3ab Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 30 May 2025 00:58:26 +0300 -Subject: [PATCH 092/108] FROMLIST(v4): phy: rockchip: samsung-hdptx: Add HDMI - 2.1 FRL support +Subject: FROMLIST(v4): phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support The PHY is capable of handling four HDMI 2.1 Fixed Rate Link (FRL) lanes, and each one can operate at any of the rates of 3Gbps, 6Gbps, @@ -14,11 +13,11 @@ Co-developed-by: Algea Cao Signed-off-by: Algea Cao Signed-off-by: Cristian Ciocaltea --- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 459 +++++++++++++++++- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 459 +++++++++- 1 file changed, 436 insertions(+), 23 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 58eac67cc3b2..bb8738e42b01 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -22,6 +22,7 @@ @@ -665,5 +664,5 @@ index 58eac67cc3b2..bb8738e42b01 100644 static const struct clk_ops hdptx_phy_clk_ops = { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0093-FROMLIST-v1-drm-Add-CRTC-background-color-property.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0093-FROMLIST-v1-drm-Add-CRTC-background-color-property.patch index ff4a7fb72..e1bb97565 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0093-FROMLIST-v1-drm-Add-CRTC-background-color-property.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0093-FROMLIST-v1-drm-Add-CRTC-background-color-property.patch @@ -1,7 +1,7 @@ -From 8edd688a06834f43c9b7f1698cfe4fc57f2ff54a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 19 Aug 2025 11:21:35 +0300 -Subject: [PATCH 093/108] FROMLIST(v1): drm: Add CRTC background color property +Subject: drm: Add CRTC background color property Some display controllers can be hardware programmed to show non-black colors for pixels that are either not covered by any plane or are @@ -24,17 +24,17 @@ Signed-off-by: Matt Roper Signed-off-by: Cristian Ciocaltea --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + - drivers/gpu/drm/drm_atomic_uapi.c | 4 +++ - drivers/gpu/drm/drm_blend.c | 37 ++++++++++++++++++++--- - drivers/gpu/drm/drm_mode_config.c | 6 ++++ - include/drm/drm_blend.h | 4 ++- - include/drm/drm_crtc.h | 12 ++++++++ - include/drm/drm_mode_config.h | 5 +++ - include/uapi/drm/drm_mode.h | 36 ++++++++++++++++++++++ + drivers/gpu/drm/drm_atomic_uapi.c | 4 + + drivers/gpu/drm/drm_blend.c | 37 +++++++++- + drivers/gpu/drm/drm_mode_config.c | 6 ++ + include/drm/drm_blend.h | 4 +- + include/drm/drm_crtc.h | 12 +++ + include/drm/drm_mode_config.h | 5 ++ + include/uapi/drm/drm_mode.h | 36 +++++++++ 8 files changed, 100 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c -index 7142e163e618..fc93ef6eebc4 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -75,6 +75,7 @@ __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, @@ -46,7 +46,7 @@ index 7142e163e618..fc93ef6eebc4 100644 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c -index ecc73d52bfae..1d6693e9a268 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -407,6 +407,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, @@ -68,7 +68,7 @@ index ecc73d52bfae..1d6693e9a268 100644 *val = 0; else if (property == crtc->scaling_filter_property) diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c -index 6852d73c931c..3af042f087c2 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -191,10 +191,6 @@ @@ -127,7 +127,7 @@ index 6852d73c931c..3af042f087c2 100644 +} +EXPORT_SYMBOL(drm_crtc_attach_background_color_property); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c -index 25f376869b3a..6d70bfab45ca 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -375,6 +375,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) @@ -144,7 +144,7 @@ index 25f376869b3a..6d70bfab45ca 100644 DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, "IN_FORMATS", 0); diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h -index 88bdfec3bd88..c7e888767c81 100644 +index 111111111111..222222222222 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -31,8 +31,9 @@ @@ -165,7 +165,7 @@ index 88bdfec3bd88..c7e888767c81 100644 +void drm_crtc_attach_background_color_property(struct drm_crtc *crtc); #endif diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h -index caa56e039da2..cd769f0726ef 100644 +index 111111111111..222222222222 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -274,6 +274,18 @@ struct drm_crtc_state { @@ -188,7 +188,7 @@ index caa56e039da2..cd769f0726ef 100644 * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h -index 2e848b816218..ea422afec5c4 100644 +index 111111111111..222222222222 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -814,6 +814,11 @@ struct drm_mode_config { @@ -204,7 +204,7 @@ index 2e848b816218..ea422afec5c4 100644 /** * @suggested_x_property: Optional connector property with a hint for diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h -index c082810c08a8..be117fecb654 100644 +index 111111111111..222222222222 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -1355,6 +1355,42 @@ struct drm_mode_closefb { @@ -251,5 +251,5 @@ index c082810c08a8..be117fecb654 100644 } #endif -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0094-FROMLIST-v1-drm-rockchip-vop2-Support-setting-custom.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0094-FROMLIST-v1-drm-rockchip-vop2-Support-setting-custom.patch index 9ea161994..e567fa96d 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0094-FROMLIST-v1-drm-rockchip-vop2-Support-setting-custom.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0094-FROMLIST-v1-drm-rockchip-vop2-Support-setting-custom.patch @@ -1,8 +1,7 @@ -From 97c862211e36128d84364a4a0cc76645e2a351d1 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 15 Aug 2025 18:36:54 +0300 -Subject: [PATCH 094/108] FROMLIST(v1): drm/rockchip: vop2: Support setting - custom background color +Subject: drm/rockchip: vop2: Support setting custom background color VOP2 allows configuring the background color of each video output port. @@ -16,12 +15,12 @@ controller. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 ++++++++++++- - drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 ++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 +++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index 977ccbf16344..565bd060fe5a 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1548,6 +1548,7 @@ static void vop2_post_config(struct drm_crtc *crtc) @@ -66,7 +65,7 @@ index 977ccbf16344..565bd060fe5a 100644 if (vop2->lut_regs) { const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h -index fa5c56f16047..596558adc120 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -659,6 +659,10 @@ enum dst_factor_mode { @@ -81,5 +80,5 @@ index fa5c56f16047..596558adc120 100644 #define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0) -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0095-WIP-SCRAMB-drm-bridge-Add-detect_ctx-hook.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0095-WIP-SCRAMB-drm-bridge-Add-detect_ctx-hook.patch index 094eabe1a..56f1fe466 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0095-WIP-SCRAMB-drm-bridge-Add-detect_ctx-hook.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0095-WIP-SCRAMB-drm-bridge-Add-detect_ctx-hook.patch @@ -1,7 +1,7 @@ -From e6bf6df2c65f1ab644f2c7e4fa2cae88f675d1f6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 10 Jan 2025 22:48:01 +0200 -Subject: [PATCH 095/108] [WIP-SCRAMB] drm/bridge: Add ->detect_ctx() hook +Subject: [WIP-SCRAMB] drm/bridge: Add ->detect_ctx() hook Add a ->detect() variant that also provides a drm_modeset_acquire_ctx reference for greater flexibility in operation, e.g. to support adding @@ -17,7 +17,7 @@ Signed-off-by: Cristian Ciocaltea 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c -index 4bde00083047..9d74ef28b6ad 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -1244,6 +1244,9 @@ drm_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) @@ -31,7 +31,7 @@ index 4bde00083047..9d74ef28b6ad 100644 } EXPORT_SYMBOL_GPL(drm_bridge_detect); diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h -index b0e6653ee42e..ca52f9fce7ed 100644 +index 111111111111..222222222222 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -663,6 +663,13 @@ struct drm_bridge_funcs { @@ -49,5 +49,5 @@ index b0e6653ee42e..ca52f9fce7ed 100644 * @get_modes: * -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0096-WIP-SCRAMB-drm-bridge-connector-Switch-from-detect-t.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0096-WIP-SCRAMB-drm-bridge-connector-Switch-from-detect-t.patch index 49f94d286..d5c13634d 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0096-WIP-SCRAMB-drm-bridge-connector-Switch-from-detect-t.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0096-WIP-SCRAMB-drm-bridge-connector-Switch-from-detect-t.patch @@ -1,8 +1,8 @@ -From 1bcc6e8cccb0206ba43da361f51d30c38874065d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 10 Jan 2025 23:04:23 +0200 -Subject: [PATCH 096/108] [WIP-SCRAMB] drm/bridge-connector: Switch from - ->detect() to ->detect_ctx() +Subject: [WIP-SCRAMB] drm/bridge-connector: Switch from ->detect() to + ->detect_ctx() In preparation to provide scrambling support to the HDMI Connector framework, make use of the more flexible ->detect_ctx() bridge connector @@ -10,11 +10,11 @@ helper hook instead of ->detect(). Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/display/drm_bridge_connector.c | 77 ++++++++++--------- + drivers/gpu/drm/display/drm_bridge_connector.c | 77 +++++----- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c -index 5eb7e9bfe361..908029d93516 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -200,39 +200,6 @@ static void drm_bridge_connector_disable_hpd(struct drm_connector *connector) @@ -130,5 +130,5 @@ index 5eb7e9bfe361..908029d93516 100644 .enable_hpd = drm_bridge_connector_enable_hpd, .disable_hpd = drm_bridge_connector_disable_hpd, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0097-WIP-SCRAMB-drm-bridge-dw-hdmi-qp-Add-high-TMDS-clock.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0097-WIP-SCRAMB-drm-bridge-dw-hdmi-qp-Add-high-TMDS-clock.patch index 710c3ba08..373f34f20 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0097-WIP-SCRAMB-drm-bridge-dw-hdmi-qp-Add-high-TMDS-clock.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0097-WIP-SCRAMB-drm-bridge-dw-hdmi-qp-Add-high-TMDS-clock.patch @@ -1,8 +1,8 @@ -From 305c4919507121e097dc5e3845997119d157a122 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 13 Sep 2024 17:30:35 +0300 -Subject: [PATCH 097/108] [WIP-SCRAMB] drm/bridge: dw-hdmi-qp: Add high TMDS - clock ratio and scrambling support +Subject: [WIP-SCRAMB] drm/bridge: dw-hdmi-qp: Add high TMDS clock ratio and + scrambling support Enable use of HDMI 2.0 display modes, e.g. 4K@60Hz, by permitting TMDS character rates above the 340 MHz limit of HDMI 1.4b. @@ -14,11 +14,11 @@ Additionally, filter out HDMI 2.1 display modes. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 214 ++++++++++++++++++- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 214 +++++++++- 1 file changed, 203 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 54377ba3a607..16736bcf26e1 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -20,6 +20,7 @@ @@ -323,5 +323,5 @@ index 54377ba3a607..16736bcf26e1 100644 regs = devm_platform_ioremap_resource(pdev, 0); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0098-WIP-YUV420-drm-rockchip-vop2-Add-YUV420-output-forma.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0098-WIP-YUV420-drm-rockchip-vop2-Add-YUV420-output-forma.patch index 53fff7ee9..029fb12cc 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0098-WIP-YUV420-drm-rockchip-vop2-Add-YUV420-output-forma.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0098-WIP-YUV420-drm-rockchip-vop2-Add-YUV420-output-forma.patch @@ -1,20 +1,19 @@ -From 9032e47657fb721baec689a428d9f1746d983d92 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 4 Dec 2024 13:26:13 +0200 -Subject: [PATCH 098/108] [WIP-YUV420] drm/rockchip: vop2: Add YUV420 output - format support +Subject: [WIP-YUV420] drm/rockchip: vop2: Add YUV420 output format support TODO: proper colorspace conversion handling Signed-off-by: Cristian Ciocaltea --- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 + - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 43 ++++++++++++++++++++ - drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 3 ++ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 43 ++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 3 + 3 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -index c183e82a42a5..36417c86da2d 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -57,6 +57,8 @@ struct rockchip_crtc_state { @@ -27,7 +26,7 @@ index c183e82a42a5..36417c86da2d 100644 * Rockchip drm private structure. * diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index 565bd060fe5a..3987be9fdec3 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -655,6 +655,39 @@ static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win, @@ -95,7 +94,7 @@ index 565bd060fe5a..3987be9fdec3 100644 static int us_to_vertical_line(struct drm_display_mode *mode, int us) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h -index 596558adc120..27cd4a573b57 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -666,6 +666,9 @@ enum dst_factor_mode { @@ -109,5 +108,5 @@ index 596558adc120..27cd4a573b57 100644 #define RK3568_SYS_DSP_INFACE_EN_LVDS1 BIT(24) #define RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX GENMASK(22, 21) -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0099-WIP-YUV420-drm-rockchip-dw_hdmi_qp-Add-YUV420-output.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0099-WIP-YUV420-drm-rockchip-dw_hdmi_qp-Add-YUV420-output.patch index c31ada312..6103b8213 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0099-WIP-YUV420-drm-rockchip-dw_hdmi_qp-Add-YUV420-output.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0099-WIP-YUV420-drm-rockchip-dw_hdmi_qp-Add-YUV420-output.patch @@ -1,19 +1,19 @@ -From 60c2ed834b282e0fdaef4f3bb1c2266dfeaf6f59 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 4 Dec 2024 14:09:35 +0200 -Subject: [PATCH 099/108] [WIP-YUV420] drm/rockchip: dw_hdmi_qp: Add YUV420 - output format support +Subject: [WIP-YUV420] drm/rockchip: dw_hdmi_qp: Add YUV420 output format + support Program the necessary bridge registers to allow using the YUV420 color format. Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 28 ++++++++++++++++++- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 28 +++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 81f106ac7b56..75a0ea019ede 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -10,6 +10,8 @@ @@ -89,5 +89,5 @@ index 81f106ac7b56..75a0ea019ede 100644 encoder = &hdmi->encoder.encoder; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0100-WIP-FRL-dt-bindings-display-rockchip-Add-tmds-enable.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0100-WIP-FRL-dt-bindings-display-rockchip-Add-tmds-enable.patch index 55c94fb64..d9d0ffcbc 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0100-WIP-FRL-dt-bindings-display-rockchip-Add-tmds-enable.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0100-WIP-FRL-dt-bindings-display-rockchip-Add-tmds-enable.patch @@ -1,8 +1,8 @@ -From 390e4d53e0d0eb9875fe5f3c5754f70003680d50 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 29 May 2025 19:15:40 +0300 -Subject: [PATCH 100/108] [WIP-FRL] dt-bindings: display: rockchip: Add - tmds-enable-gpios property to rk3588-dw-hdmi-qp +Subject: [WIP-FRL] dt-bindings: display: rockchip: Add tmds-enable-gpios + property to rk3588-dw-hdmi-qp Add an optional property to RK3588 HDMI TX Controller binding describing a GPIO line to be asserted when operating in HDMI 1.4/2.0 TMDS mode and @@ -12,11 +12,11 @@ This is used to control an external level shifter for HDMI data lines. Signed-off-by: Cristian Ciocaltea --- - .../display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml | 10 ++++++++++ + Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml -index 96b4b088eebe..eec0d40c91ea 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml @@ -113,6 +113,13 @@ properties: @@ -53,5 +53,5 @@ index 96b4b088eebe..eec0d40c91ea 100644 ports { #address-cells = <1>; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0101-WIP-FRL-drm-rockchip-dw_hdmi_qp-Fixup-usage-of-enabl.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0101-WIP-FRL-drm-rockchip-dw_hdmi_qp-Fixup-usage-of-enabl.patch index 0804a73d9..1b2d4d5d1 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0101-WIP-FRL-drm-rockchip-dw_hdmi_qp-Fixup-usage-of-enabl.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0101-WIP-FRL-drm-rockchip-dw_hdmi_qp-Fixup-usage-of-enabl.patch @@ -1,8 +1,8 @@ -From f0e4a4ddcfabe86c58bdb0ab37492ff7c224a13a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 29 May 2025 19:50:25 +0300 -Subject: [PATCH 101/108] [WIP-FRL] drm/rockchip: dw_hdmi_qp: Fixup usage of - enable_gpio member in main struct +Subject: [WIP-FRL] drm/rockchip: dw_hdmi_qp: Fixup usage of enable_gpio member + in main struct The name of the enable_gpio member in struct rockchip_hdmi_qp is too generic, as initially "borrowed" from downstream BSP code. Moreover, @@ -20,11 +20,11 @@ devm_gpiod_get_optional() and rename the struct member accordingly. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 14 +++++++------- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 14 +++++----- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 75a0ea019ede..c18c0a9bf06c 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -96,7 +96,7 @@ struct rockchip_hdmi_qp { @@ -63,5 +63,5 @@ index 75a0ea019ede..c18c0a9bf06c 100644 hdmi->phy = devm_of_phy_get_by_index(dev, dev->of_node, 0); if (IS_ERR(hdmi->phy)) -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0102-WIP-FRL-arm64-dts-rockchip-Add-tmds-enable-gpios-to-.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0102-WIP-FRL-arm64-dts-rockchip-Add-tmds-enable-gpios-to-.patch index b69440f3c..65c65dbf9 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0102-WIP-FRL-arm64-dts-rockchip-Add-tmds-enable-gpios-to-.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0102-WIP-FRL-arm64-dts-rockchip-Add-tmds-enable-gpios-to-.patch @@ -1,8 +1,8 @@ -From 64347702316aadcff64bf18bd8f12d284752619d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 29 May 2025 19:31:51 +0300 -Subject: [PATCH 102/108] [WIP-FRL] arm64: dts: rockchip: Add tmds-enable-gpios - to rk3588-rock-5b +Subject: [WIP-FRL] arm64: dts: rockchip: Add tmds-enable-gpios to + rk3588-rock-5b In preparation to support HDMI 2.1 FRL operating mode, make use of the GPIO4_B1 and GPIO4_A1 lines (labeled HDMI0_TX_ON_H & HDMI1_TX_ON_H in @@ -18,7 +18,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi -index 612808d2b4c5..bd07021e9cc3 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi @@ -170,6 +170,7 @@ &gpu { @@ -38,5 +38,5 @@ index 612808d2b4c5..bd07021e9cc3 100644 }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0103-WIP-FRL-arm64-dts-rockchip-Assign-ACLK_VOP-to-750-MH.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0103-WIP-FRL-arm64-dts-rockchip-Assign-ACLK_VOP-to-750-MH.patch index 17c56090c..3958c3a5e 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0103-WIP-FRL-arm64-dts-rockchip-Assign-ACLK_VOP-to-750-MH.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0103-WIP-FRL-arm64-dts-rockchip-Assign-ACLK_VOP-to-750-MH.patch @@ -1,8 +1,7 @@ -From d77ca8c2a3dbf2a6e9fe19c6e32220e41c771e2e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 8 Jul 2025 20:12:00 +0300 -Subject: [PATCH 103/108] [WIP-FRL] arm64: dts: rockchip: Assign ACLK_VOP to - 750 MHz on rk3588 +Subject: [WIP-FRL] arm64: dts: rockchip: Assign ACLK_VOP to 750 MHz on rk3588 In preparation to support HDMI 2.1 display modes on RK3588, e.g. 4K@120Hz, increase ACLK_VOP from the default 500 MHz to 750 MHz. @@ -23,7 +22,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 3bd1b5e3b101..d4d66e456069 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -1436,6 +1436,8 @@ vop: vop@fdd90000 { @@ -36,5 +35,5 @@ index 3bd1b5e3b101..d4d66e456069 100644 <&cru HCLK_VOP>, <&cru DCLK_VOP0>, -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0104-WIP-FRL-drm-connector-hdmi-Handle-FRL-in-hdmi_clock_.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0104-WIP-FRL-drm-connector-hdmi-Handle-FRL-in-hdmi_clock_.patch index fde9c4b1b..2879ce659 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0104-WIP-FRL-drm-connector-hdmi-Handle-FRL-in-hdmi_clock_.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0104-WIP-FRL-drm-connector-hdmi-Handle-FRL-in-hdmi_clock_.patch @@ -1,8 +1,7 @@ -From af71d660b54edde6ae30380e5c378e60f68b3ce8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 3 Jul 2025 12:47:17 +0300 -Subject: [PATCH 104/108] [WIP-FRL] drm/connector: hdmi: Handle FRL in - hdmi_clock_valid() +Subject: [WIP-FRL] drm/connector: hdmi: Handle FRL in hdmi_clock_valid() Do not limit clock validation to max_tmds_clock if the sink advertises FRL support. @@ -15,7 +14,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c -index a561f124be99..0608443985f1 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -535,7 +535,9 @@ hdmi_clock_valid(const struct drm_connector *connector, @@ -30,5 +29,5 @@ index a561f124be99..0608443985f1 100644 if (funcs && funcs->tmds_char_rate_valid) { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0105-WIP-FRL-drm-bridge-dw-hdmi-qp-Add-HDMI-2.1-FRL-suppo.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0105-WIP-FRL-drm-bridge-dw-hdmi-qp-Add-HDMI-2.1-FRL-suppo.patch index 12a932f36..859426b9b 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0105-WIP-FRL-drm-bridge-dw-hdmi-qp-Add-HDMI-2.1-FRL-suppo.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0105-WIP-FRL-drm-bridge-dw-hdmi-qp-Add-HDMI-2.1-FRL-suppo.patch @@ -1,8 +1,7 @@ -From c9e07e82566586e8d4b15cf28c0b985afaaaea88 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 3 Jul 2025 12:42:38 +0300 -Subject: [PATCH 105/108] [WIP-FRL] drm/bridge: dw-hdmi-qp: Add HDMI 2.1 FRL - support +Subject: [WIP-FRL] drm/bridge: dw-hdmi-qp: Add HDMI 2.1 FRL support Implement the link training state machine required to support HDMI 2.1 FRL display modes. @@ -15,12 +14,12 @@ is the actual hardware limitation. Signed-off-by: Cristian Ciocaltea --- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 582 ++++++++++++++++++- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 582 +++++++++- include/drm/bridge/dw_hdmi_qp.h | 11 + 2 files changed, 577 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -index 16736bcf26e1..cbd97b1b15e7 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -41,9 +41,26 @@ @@ -706,7 +705,7 @@ index 16736bcf26e1..cbd97b1b15e7 100644 hdmi->dev = dev; diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h -index 3f461f6b9bbf..f2560dd5b510 100644 +index 111111111111..222222222222 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -7,16 +7,27 @@ @@ -738,5 +737,5 @@ index 3f461f6b9bbf..f2560dd5b510 100644 struct dw_hdmi_qp_plat_data { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0106-WIP-FRL-drm-rockchip-dw_hdmi_qp-Add-HDMI-2.1-FRL-sup.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0106-WIP-FRL-drm-rockchip-dw_hdmi_qp-Add-HDMI-2.1-FRL-sup.patch index 00068a804..96e0f8857 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0106-WIP-FRL-drm-rockchip-dw_hdmi_qp-Add-HDMI-2.1-FRL-sup.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0106-WIP-FRL-drm-rockchip-dw_hdmi_qp-Add-HDMI-2.1-FRL-sup.patch @@ -1,8 +1,7 @@ -From 10a7b19d103e899d0019d04b509d3862c0fb9f29 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 3 Jul 2025 12:44:04 +0300 -Subject: [PATCH 106/108] [WIP-FRL] drm/rockchip: dw_hdmi_qp: Add HDMI 2.1 FRL - support +Subject: [WIP-FRL] drm/rockchip: dw_hdmi_qp: Add HDMI 2.1 FRL support Extend ->enc_init() hooks of {rk3576,rk3588}_hdmi_ctrl_ops to enable HDMI 2.1 FRL operation mode. @@ -12,11 +11,11 @@ configuration when switching between TMDS and FRL. Signed-off-by: Cristian Ciocaltea --- - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 243 ++++++++++++++++-- + drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 243 ++++++++-- 1 file changed, 215 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index c18c0a9bf06c..69e9a76d4656 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -64,12 +64,17 @@ @@ -365,5 +364,5 @@ index c18c0a9bf06c..69e9a76d4656 100644 val = HIWORD_UPDATE(FIELD_PREP(RK3588_COLOR_DEPTH_MASK, RK3588_10BPC), RK3588_COLOR_DEPTH_MASK); -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0107-WIP-FRL-drm-rockchip-vop2-Add-HDMI-2.1-FRL-support.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0107-WIP-FRL-drm-rockchip-vop2-Add-HDMI-2.1-FRL-support.patch index a71f2df88..e0692f8bb 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0107-WIP-FRL-drm-rockchip-vop2-Add-HDMI-2.1-FRL-support.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0107-WIP-FRL-drm-rockchip-vop2-Add-HDMI-2.1-FRL-support.patch @@ -1,8 +1,7 @@ -From 0da627d4a92eb13f93cd8af89cf6daf33d4671c5 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Thu, 19 Jun 2025 23:57:01 +0300 -Subject: [PATCH 107/108] [WIP-FRL] drm/rockchip: vop2: Add HDMI 2.1 FRL - support +Subject: [WIP-FRL] drm/rockchip: vop2: Add HDMI 2.1 FRL support TODO: this has been "borrowed" from downstream code, although it might not really be required. @@ -13,7 +12,7 @@ Signed-off-by: Cristian Ciocaltea 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c -index 5a3d8c834ca9..74b6275da45d 100644 +index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -1578,6 +1578,15 @@ static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, @@ -33,5 +32,5 @@ index 5a3d8c834ca9..74b6275da45d 100644 /* * edp_pixclk = edp_dclk > dclk_core -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0108-WIP-arm64-dts-rockchip-add-pcie-wifi-support-to-Oran.patch b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0108-WIP-arm64-dts-rockchip-add-pcie-wifi-support-to-Oran.patch index 6a2279a75..875281b12 100644 --- a/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0108-WIP-arm64-dts-rockchip-add-pcie-wifi-support-to-Oran.patch +++ b/patch/kernel/archive/rockchip-6.17/patches.libreelec/rockchip-0108-WIP-arm64-dts-rockchip-add-pcie-wifi-support-to-Oran.patch @@ -1,8 +1,7 @@ -From d1726bef24dda956d6247c2a853b984ddd6ca62b Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Muhammed Efe Cetin Date: Tue, 10 Dec 2024 21:56:10 +0300 -Subject: [PATCH 108/108] WIP: arm64: dts: rockchip: add pcie wifi support to - OrangePi-5b +Subject: WIP: arm64: dts: rockchip: add pcie wifi support to OrangePi-5b Add the PCIe nodes to OrangePi-5b to allow the OrangePi AP6275P WiFi module to work. @@ -10,11 +9,11 @@ AP6275P WiFi module to work. Signed-off-by: Muhammed Efe Cetin Signed-off-by: Christian Hewitt --- - .../boot/dts/rockchip/rk3588s-orangepi-5b.dts | 33 +++++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5b.dts | 33 ++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5b.dts -index d21ec320d295..56e191ea8457 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5b.dts @@ -12,6 +12,39 @@ aliases { @@ -58,5 +57,5 @@ index d21ec320d295..56e191ea8457 100644 &sdhci { -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/rockchip-6.17/series.conf b/patch/kernel/archive/rockchip-6.17/series.conf index 5fb02fe91..15d5e2ef1 100644 --- a/patch/kernel/archive/rockchip-6.17/series.conf +++ b/patch/kernel/archive/rockchip-6.17/series.conf @@ -63,7 +63,7 @@ patches.libreelec/rockchip-0062-FROMLIST-v1-drm-rockchip-vop2-Add-delay-between-poll.patch patches.libreelec/rockchip-0063-FROMLIST-v1-drm-rockchip-vop2-Only-wait-for-changed-.patch patches.libreelec/rockchip-0064-FROMLIST-v1-media-verisilicon-Export-only-needed-pix.patch - patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch +# patches.libreelec/rockchip-0065-FROMLIST-v2-media-verisilicon-Explicitly-disable-sel.patch patches.libreelec/rockchip-0066-DETLEV-v3-bitmap-introduce-hardware-specific-bitfiel.patch patches.libreelec/rockchip-0067-DETLEV-v3-media-rkvdec-Switch-to-using-structs-inste.patch patches.libreelec/rockchip-0068-DETLEV-v3-media-rkvdec-Move-cabac-tables-to-their-ow.patch diff --git a/patch/kernel/archive/rockchip64-6.12/board-station-p2.patch b/patch/kernel/archive/rockchip64-6.12/board-station-p2.patch index 53423f7fe..d32368d34 100644 --- a/patch/kernel/archive/rockchip64-6.12/board-station-p2.patch +++ b/patch/kernel/archive/rockchip64-6.12/board-station-p2.patch @@ -346,7 +346,7 @@ index 111111111111..222222222222 100644 &pcie30phy { - status = "okay"; -+ tatus = "okay"; ++ status = "okay"; }; &pcie3x2 { diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3566-odroid-m1s.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3566-odroid-m1s.dts new file mode 100644 index 000000000..33bc5249d --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3566-odroid-m1s.dts @@ -0,0 +1,663 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include +#include +#include +#include +#include "rk3566.dtsi" + +/ { + model = "Hardkernel ODROID-M1S"; + compatible = "hardkernel,odroid-m1s", "rockchip,rk3566"; + + aliases { + ethernet0 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc0; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_led>, <&sys_led>; + + led_pwr: led-0 { + color = ; + default-state = "on"; + function = LED_FUNCTION_POWER; + gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + led_sys: led-1 { + color = ; + default-state = "on"; + function = LED_FUNCTION_HEARTBEAT; + gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + vcc3v3_lcd: regulator-3v3-vcc-lcd { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_pwren>; + regulator-name = "vcc3v3_lcd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_pcie: regulator-3v3-vcc-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pwren>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-3v3-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc5v0_usb2_host: regulator-5v0-vcc-usb2-host { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_host_pwren>; + regulator-name = "vcc5v0_usb2_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_usb2_otg: regulator-5v0-vcc-usb2-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_otg_pwren>; + regulator-name = "vcc5v0_usb2_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_usb3_host: regulator-5v0-vcc-usb3-host { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_host_pwren>; + regulator-name = "vcc5v0_usb3_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; +}; + +&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>; + 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 = <712500>; + regulator-max-microvolt = <1390000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clocks = <&cru I2S1_MCLKOUT_TX>; + clock-names = "mclk"; + clock-output-names = "rk809-clkout1", "rk809-clkout2"; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; + #sound-dai-cells = <0>; + system-power-controller; + wakeup-source; + + 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>; + + 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; + }; + }; + + 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; + }; + }; + + 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; + }; + }; + }; + }; +}; + +&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 = <1>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + }; +}; + +&pcie2x1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie20_pins>; + reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pinctrl { + lcd { + lcd_pwren: lcd-pwren { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + pwr_led: pwr-led { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led: sys-led { + rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie20_pins: pcie20-pins { + rockchip,pins = + <1 RK_PB0 4 &pcfg_pull_none>, + <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>, + <1 RK_PB1 4 &pcfg_pull_none>; + }; + + pcie_pwren: pcie-pwren { + rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + usb2_host_pwren: usb2-host-pwren { + rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb2_otg_pwren: usb2-otg-pwren { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb3_host_pwren: usb3-host-pwren { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_3v3>; + 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>; + cap-mmc-highspeed; + max-frequency = <200000000>; + mmc-hs200-1_8v; + no-sd; + no-sdio; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe &emmc_rstnout>; + 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_sd>; + vqmmc-supply = <&vccio_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 { + 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_usb3_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb2_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb2_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb2_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 = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-9tripod-x3568-v4.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-9tripod-x3568-v4.dts new file mode 100644 index 000000000..ad4d62060 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-9tripod-x3568-v4.dts @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "9Tripod X3568 v4"; + compatible = "9tripod,x3568-v4", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc0; + mmc2 = &sdmmc2; + rtc0 = &rtc0; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-vol-up { + label = "volume up"; + linux,code = ; + press-threshold-microvolt = <50000>; + }; + + button-vol-down { + label = "volume down"; + linux,code = ; + press-threshold-microvolt = <500000>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_work: led-0 { + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_HEARTBEAT; + color = ; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_work_en>; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + pdm_codec: pdm-codec { + compatible = "dmic-codec"; + num-channels = <2>; + #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>; + }; + }; + + spdif_dit: spdif-dit { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + spdif_sound: spdif-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + simple-audio-card,codec { + sound-dai = <&spdif_dit>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <300>; + reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + }; + + dc_12v: regulator-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc3v3_pcie: regulator-vcc3v3-pcie { + compatible = "regulator-gpio"; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <100000>; + regulator-max-microvolt = <3300000>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc3v3_pcie_en_pin>; + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <100000 0>, <3300000 1>; + startup-delay-us = <5000>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb_host: regulator-vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_host_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_otg: regulator-vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 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_usb>; + }; +}; + +&can1 { + assigned-clocks = <&cru CLK_CAN1>; + assigned-clock-rates = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&can1m1_pins>; + status = "okay"; +}; + +/* used for usb_host0_xhci */ +&combphy0 { + status = "okay"; +}; + +/* used for usb_host1_xhci */ +&combphy1 { + status = "okay"; +}; + +/* connected to sata2 */ +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + 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 = ; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; + system-power-controller; + #sound-dai-cells = <0>; + 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; + + 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; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_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; + }; + }; + + 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-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; + }; + }; + }; + + codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2c5 { + status = "okay"; + + rtc0: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + #clock-cells = <0>; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>; + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +/* used for AP6275S Bluetooth Sound */ +&i2s3_2ch { + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&pcie30phy { + status = "okay"; +}; + +&pcie3x2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pin>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pdm { + status = "okay"; +}; + +&pinctrl { + leds { + led_work_en: led_work_en { + rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable: wifi-enable { + rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_usb_host_en: vcc5v0_usb_host_en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_reset_pin: pcie-reset-pin { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin { + rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +/* Required remotectl for IR receiver */ +&pwm7 { + status = "disabled"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +/* used for eMMC */ +&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>; + status = "okay"; +}; + +/* used for microSD (TF) Slot */ +&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-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +/* used for AP6275S WiFi */ +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +/* used for Debug */ +&uart2 { + status = "okay"; +}; + +&uart3 { + pinctrl-0 = <&uart3m1_xfer>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4m1_xfer>; + status = "okay"; +}; + +/* used for WiFi/BT AP6275S */ +&uart8 { + pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn>; + status = "okay"; +}; + +&uart9 { + pinctrl-0 = <&uart9m1_xfer>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + 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_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb_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 = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/patch/kernel/archive/rockchip64-6.12/overlay/Makefile b/patch/kernel/archive/rockchip64-6.12/overlay/Makefile index a564638e5..ea4a4a4be 100644 --- a/patch/kernel/archive/rockchip64-6.12/overlay/Makefile +++ b/patch/kernel/archive/rockchip64-6.12/overlay/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ hinlink-h88k-240x135-lcd.dtbo \ + rk35xx-radxa-zero-3w-ext-ant.dtbo \ rk3308-otg-host.dtbo \ rk3308-s0-ext-antenna.dtbo \ rk3308-b@1.3ghz.dtbo \ @@ -17,6 +18,8 @@ dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ rockchip-rk3318-box-led-conf3.dtbo \ rockchip-rk3318-box-led-conf4.dtbo \ rockchip-rk3318-box-led-conf5.dtbo \ + rockchip-rk3318-box-led-conf6.dtbo \ + rockchip-rk3318-box-led-conf7.dtbo \ rockchip-rk3318-box-wlan-ap6330.dtbo \ rockchip-rk3318-box-wlan-ap6334.dtbo \ rockchip-rk3318-box-wlan-ext.dtbo \ diff --git a/patch/kernel/archive/rockchip64-6.12/overlay/README.rockchip-overlays b/patch/kernel/archive/rockchip64-6.12/overlay/README.rockchip-overlays index 2d06c061c..8d7af4388 100644 --- a/patch/kernel/archive/rockchip64-6.12/overlay/README.rockchip-overlays +++ b/patch/kernel/archive/rockchip64-6.12/overlay/README.rockchip-overlays @@ -159,8 +159,8 @@ or enabling the internal pull-up ### rk3318-box-led-conf1 -Activates led/gpio configuration for rk3318 tv box boards with signature -YX_RK3328 and clones +Generic default led/gpio configuration for rk3318 tv box boards. +Does not enable any specific or peculiar hardware. ### rk3318-box-led-conf2 @@ -178,6 +178,20 @@ system. Also enables gpio leds and keys. Generic rk3318-box configuration but with sdio chip on sdmmc-ext connector +### rk3318-box-led-conf5 + +Configuration for rk3318 boards with with signature YX_RK3328 and clones. + +### rk3318-box-led-conf6 + +Configuration for rk3318 boards with with signature T98_RK3318 and clones. +Seen in commercial tv boxes like Hongtop H50. + +### rk3318-box-led-conf7 + +Configuration for rk3318 boards with with signature T9_RK3318 and clones. +Seen in commercial tv boxes like T9 Sunwell 3318. + ### rk3318-box-emmc-ddr Activates eMMC DDR capability for rk3318 tv box boards. Probably all the eMMC chips diff --git a/patch/kernel/archive/rockchip64-6.12/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso b/patch/kernel/archive/rockchip64-6.12/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso new file mode 100644 index 000000000..7a32b8fe5 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso @@ -0,0 +1,37 @@ +/dts-v1/; +/plugin/; + +#include +#include + +/ { + compatible = "radxa,zero-3w", "rockchip,rk3566"; + + fragment@0 { + target-path = "/"; + __overlay__ { + board_antenna: board-antenna { + compatible = "regulator-fixed"; + enable-active-low; + gpio = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&ant_1>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-name = "board-antenna"; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&pinctrl>; + __overlay__ { + antenna { + ant_1: ant-1 { + rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + }; + }; +}; diff --git a/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf6.dtso b/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf6.dtso new file mode 100644 index 000000000..3d1e05043 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf6.dtso @@ -0,0 +1,57 @@ +/dts-v1/; +/plugin/; + +#include +#include +#include + +/** + * T98_RK3318 (Hongtop H50) + */ + +&{/} { + + i2c-display { + compatible = "i2c-gpio"; + sda-gpios = <&gpio1 RK_PD1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio1 RK_PD0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <5>; + i2c-gpio,sda-output-only; + i2c-gpio,scl-output-only; + #address-cells = <1>; + #size-cells = <0>; + + display-controller@24 { + #address-cells = <2>; + #size-cells = <0>; + + compatible = "fdhisi,fd650"; + reg = <0x24>; + tm16xx,digits = [04 03 02 01]; + tm16xx,segment-mapping = [03 04 05 00 01 02 06]; + + led@2,1 { + reg = <1 7>; + function = LED_FUNCTION_USB; + }; + + led@2,2 { + reg = <2 7>; + function = "colon"; + }; + + led@2,3 { + reg = <3 7>; + function = LED_FUNCTION_LAN; + }; + + led@2,4 { + reg = <4 7>; + function = LED_FUNCTION_WLAN; + }; + + }; + + }; + +}; diff --git a/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf7.dtso b/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf7.dtso new file mode 100644 index 000000000..e1aa172e7 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/overlay/rockchip-rk3318-box-led-conf7.dtso @@ -0,0 +1,76 @@ +/dts-v1/; +/plugin/; + +#include +#include +#include + +/** + * T9_RK3318 (T9 Sunwell 3318 version 4+32 GB) + */ + +&{/} { + + i2c_aux_display: i2c-aux-display { + + compatible = "i2c-gpio"; + sda-gpios = <&gpio2 RK_PC6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio2 RK_PC3 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <5>; + i2c-gpio,sda-output-only; + i2c-gpio,scl-output-only; + #address-cells = <1>; + #size-cells = <0>; + + display@24 { + compatible = "fdhisi,fd655"; + reg = <0x24>; + tm16xx,digits = [01 02 03 04]; + tm16xx,segment-mapping = [03 04 05 00 01 02 06]; + + leds { + #address-cells = <2>; + #size-cells = <0>; + + led@0,0 { + reg = <0 0>; + function = LED_FUNCTION_ALARM; + }; + + led@0,1 { + reg = <0 1>; + function = LED_FUNCTION_USB; + }; + + led@0,2 { + reg = <0 2>; + function = "play"; + }; + + led@0,3 { + reg = <0 3>; + function = "pause"; + }; + + led@0,4 { + reg = <0 4>; + function = "colon"; + }; + + led@0,5 { + reg = <0 5>; + function = LED_FUNCTION_LAN; + }; + + led@0,6 { + reg = <0 6>; + function = LED_FUNCTION_WLAN; + }; + + }; + + }; + + }; + +}; diff --git a/patch/kernel/archive/rockchip64-6.17/board-orangepi5-sata-supply.patch b/patch/kernel/archive/rockchip64-6.17/board-orangepi5-sata-supply.patch deleted file mode 100644 index 67b165231..000000000 --- a/patch/kernel/archive/rockchip64-6.17/board-orangepi5-sata-supply.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -index ad6d04793b0a..b811ec843936 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -@@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 { - gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; - regulator-name = "vcc3v3_pcie20"; - regulator-boot-on; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; - startup-delay-us = <50000>; - vin-supply = <&vcc5v0_sys>; - }; -@@ -27,6 +27,13 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&sata0 { -+ sata-port@0 { -+ target-supply = <&vcc3v3_pcie20>; -+ }; -+}; -+ -+ - &sfc { - status = "okay"; - }; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-mali-opp-table.patch b/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-mali-opp-table.patch deleted file mode 100644 index a1ae4cfb9..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-mali-opp-table.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paolo Sabatino -Date: Sat, 25 Sep 2021 15:26:41 +0000 -Subject: gpu operating points - ---- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 ++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -713,6 +713,31 @@ gpu: gpu@ff300000 { - clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; - clock-names = "bus", "core"; - resets = <&cru SRST_GPU_A>; -+ operating-points-v2 = <&gpu_opp_table>; -+ }; -+ -+ gpu_opp_table: gpu-opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-200000000 { -+ opp-hz = /bits/ 64 <200000000>; -+ opp-microvolt = <1050000 950000 1200000>; -+ }; -+ -+ opp-300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <1050000 950000 1200000>; -+ }; -+ -+ opp-400000000 { -+ opp-hz = /bits/ 64 <400000000>; -+ opp-microvolt = <1050000 950000 1200000>; -+ }; -+ -+ opp-500000000 { -+ opp-hz = /bits/ 64 <500000000>; -+ opp-microvolt = <1150000 950000 1200000>; -+ }; - }; - - h265e_mmu: iommu@ff330200 { --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-gpu-cooling-target.patch b/patch/kernel/archive/rockchip64-6.17/rk3328-gpu-cooling-target.patch deleted file mode 100644 index 2f3353fda..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-gpu-cooling-target.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Wed, 4 Aug 2021 00:14:33 -0400 -Subject: rk3328-gpu-cooling-target - -Signed-off-by: tonymac32 ---- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -594,6 +594,11 @@ map0 { - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - contribution = <4096>; - }; -+ map1 { -+ trip = <&target>; -+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ contribution = <4096>; -+ }; - }; - }; - -@@ -739,6 +744,7 @@ gpu: gpu@ff300000 { - power-domains = <&power RK3328_PD_GPU>; - resets = <&cru SRST_GPU_A>; - operating-points-v2 = <&gpu_opp_table>; -+ #cooling-cells = <2>; - }; - - gpu_opp_table: gpu-opp-table { --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-roc-cc-add-missing-nodes.patch b/patch/kernel/archive/rockchip64-6.17/rk3328-roc-cc-add-missing-nodes.patch deleted file mode 100644 index 068efbbd8..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-roc-cc-add-missing-nodes.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: tonymac32 -Date: Sat, 28 Jan 2023 17:07:35 -0500 -Subject: rk3328-roc-cc add missing nodes - -Signed-off-by: tonymac32 ---- - arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 32 ++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi -old mode 100644 -new mode 100755 -index 111111111111..222222222222 ---- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi -@@ -128,6 +128,14 @@ user_led: led-1 { - default-state = "off"; - }; - }; -+ -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&ir_int>; -+ pinctrl-names = "default"; -+ }; -+ - }; - - &analog_sound { -@@ -198,6 +206,10 @@ &gmac2io { - status = "okay"; - }; - -+&gpu { -+ mali-supply = <&vdd_logic>; -+}; -+ - &hdmi { - status = "okay"; - }; -@@ -338,6 +350,13 @@ &io_domains { - }; - - &pinctrl { -+ -+ ir { -+ ir_int: ir-int { -+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ - pmic { - pmic_int_l: pmic-int-l { - rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -@@ -368,6 +387,19 @@ &sdmmc { - status = "okay"; - }; - -+&spdif { -+ pinctrl-0 = <&spdifm0_tx>; -+ status = "okay"; -+}; -+ -+&spdif_out { -+ status = "okay"; -+}; -+ -+&spdif_sound { -+ status = "okay"; -+}; -+ - &tsadc { - status = "okay"; - }; --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1080-arm64-dts-rockchip-add-USB3-support-to-NanoPi-R6-ser.patch b/patch/kernel/archive/rockchip64-6.17/rk3588-1080-arm64-dts-rockchip-add-USB3-support-to-NanoPi-R6-ser.patch deleted file mode 100644 index cec8709ad..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1080-arm64-dts-rockchip-add-USB3-support-to-NanoPi-R6-ser.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muhammed Efe Cetin -Date: Tue, 10 Dec 2024 22:03:19 +0300 -Subject: arm64: dts: rockchip: add USB3 support to NanoPi R6 series boards - ---- - arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 19 ++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi -@@ -788,6 +788,15 @@ &u2phy0_otg { - status = "okay"; - }; - -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ phy-supply = <&vcc5v0_usb_otg0>; -+ status = "okay"; -+}; -+ - &u2phy2 { - status = "okay"; - }; -@@ -819,6 +828,16 @@ &usbdp_phy0 { - status = "okay"; - }; - -+&usb_host0_xhci { -+ dr_mode = "host"; -+ extcon = <&u2phy0>; -+ status = "okay"; -+}; -+ -+&usbdp_phy0 { -+ status = "okay"; -+}; -+ - &vop { - status = "okay"; - }; --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1090-arm64-dts-rockchip-Enable-HDMI-receiver-on-CM3588-NAS.patch b/patch/kernel/archive/rockchip64-6.17/rk3588-1090-arm64-dts-rockchip-Enable-HDMI-receiver-on-CM3588-NAS.patch deleted file mode 100644 index 17131481a..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1090-arm64-dts-rockchip-Enable-HDMI-receiver-on-CM3588-NAS.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ricardo Pardini -Date: Fri, 23 May 2025 15:33:24 +0200 -Subject: arm64: dts: rockchip: Enable HDMI receiver on CM3588-NAS - -The CM3588-NAS has a full-size HDMI port, which can be used for receiving -HDMI data. This enables support for it. - -Signed-off-by: Ricardo Pardini ---- - arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts | 17 ++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts -@@ -335,6 +335,17 @@ hdmi0_out_con: endpoint { - }; - }; - -+&hdmi_receiver_cma { -+ status = "okay"; -+}; -+ -+&hdmi_receiver { -+ hpd-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; -+ pinctrl-names = "default"; -+ status = "okay"; -+}; -+ - &hdptxphy0 { - status = "okay"; - }; -@@ -478,6 +489,12 @@ key1_pin: key1-pin { - }; - }; - -+ hdmirx { -+ hdmirx_hpd: hdmirx-5v-detection { -+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ - pcie { - pcie2_0_rst: pcie2-0-rst { - rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1091-arm64-dts-rockchip-Enable-HDMI-receiver-on-NanoPC-T6.patch b/patch/kernel/archive/rockchip64-6.17/rk3588-1091-arm64-dts-rockchip-Enable-HDMI-receiver-on-NanoPC-T6.patch deleted file mode 100644 index 4ea2fde43..000000000 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1091-arm64-dts-rockchip-Enable-HDMI-receiver-on-NanoPC-T6.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ricardo Pardini -Date: Fri, 23 May 2025 18:00:28 +0200 -Subject: arm64: dts: rockchip: Enable HDMI receiver on NanoPC-T6 - -The NanoPC-T6 (and its LTS variant) has a full-size HDMI port, which can be used -for receiving HDMI data. This enables support for it. - -Signed-off-by: Ricardo Pardini ---- - arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 17 ++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -@@ -399,6 +399,17 @@ &hdmi1_sound { - status = "okay"; - }; - -+&hdmi_receiver_cma { -+ status = "okay"; -+}; -+ -+&hdmi_receiver { -+ hpd-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; -+ pinctrl-names = "default"; -+ status = "okay"; -+}; -+ - &hdptxphy0 { - status = "okay"; - }; -@@ -665,6 +676,12 @@ usr_led_pin: usr-led-pin { - }; - }; - -+ hdmirx { -+ hdmirx_hpd: hdmirx-5v-detection { -+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ - headphone { - hp_det: hp-det { - rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; --- -Armbian - diff --git a/patch/kernel/archive/rockchip64-6.17/0000.patching_config.yaml b/patch/kernel/archive/rockchip64-6.18/0000.patching_config.yaml similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/0000.patching_config.yaml rename to patch/kernel/archive/rockchip64-6.18/0000.patching_config.yaml diff --git a/patch/kernel/archive/rockchip64-6.17/add-board-helios64.patch b/patch/kernel/archive/rockchip64-6.18/add-board-helios64.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/add-board-helios64.patch rename to patch/kernel/archive/rockchip64-6.18/add-board-helios64.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-firefly-rk3399-dts.patch b/patch/kernel/archive/rockchip64-6.18/board-firefly-rk3399-dts.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-firefly-rk3399-dts.patch rename to patch/kernel/archive/rockchip64-6.18/board-firefly-rk3399-dts.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-helios64-dts-fix-stability-issues.patch b/patch/kernel/archive/rockchip64-6.18/board-helios64-dts-fix-stability-issues.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-helios64-dts-fix-stability-issues.patch rename to patch/kernel/archive/rockchip64-6.18/board-helios64-dts-fix-stability-issues.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-helios64-remove-pcie-ep-gpios.patch b/patch/kernel/archive/rockchip64-6.18/board-helios64-remove-pcie-ep-gpios.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-helios64-remove-pcie-ep-gpios.patch rename to patch/kernel/archive/rockchip64-6.18/board-helios64-remove-pcie-ep-gpios.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopc-t4-add-typec-dp.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopc-t4-add-typec-dp.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-nanopc-t4-add-typec-dp.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopc-t4-add-typec-dp.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopi-m4v2-dts-add-sound-card.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopi-m4v2-dts-add-sound-card.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/board-nanopi-m4v2-dts-add-sound-card.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopi-m4v2-dts-add-sound-card.patch index 7fe3b640c..0d08a0c21 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-nanopi-m4v2-dts-add-sound-card.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-nanopi-m4v2-dts-add-sound-card.patch @@ -169,7 +169,7 @@ diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index 111111111111..222222222222 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig -@@ -75,6 +75,15 @@ config SND_SOC_ROCKCHIP_RT5645 +@@ -66,6 +66,15 @@ config SND_SOC_ROCKCHIP_RT5645 Say Y or M here if you want to add support for SoC audio on Rockchip boards using the RT5645/RT5650 codec, such as Veyron. @@ -184,7 +184,7 @@ index 111111111111..222222222222 100644 + config SND_SOC_RK3288_HDMI_ANALOG tristate "ASoC support multiple codecs for Rockchip RK3288 boards" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK + depends on I2C && GPIOLIB -- Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopi-r2c-plus.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopi-r2c-plus.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-nanopi-r2c-plus.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopi-r2c-plus.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopi-r2s.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopi-r2s.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-nanopi-r2s.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopi-r2s.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopi-r3s-fix-leds.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopi-r3s-fix-leds.patch similarity index 92% rename from patch/kernel/archive/rockchip64-6.17/board-nanopi-r3s-fix-leds.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopi-r3s-fix-leds.patch index 6b9d8423b..b867f5639 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-nanopi-r3s-fix-leds.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-nanopi-r3s-fix-leds.patch @@ -1,15 +1,15 @@ -From c80bdda0d87a7119152d95f7943212fc8265e104 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 30 Aug 2025 14:20:24 +0800 -Subject: [PATCH 1/3] Patching NanoPi-R3S LEDs +Subject: Patching NanoPi-R3S LEDs Signed-off-by: retro98boy --- - .../boot/dts/rockchip/rk3566-nanopi-r3s.dts | 41 ++++++++++++++----- + arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts | 41 +++++++--- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts -index fb1f65c86..553a9e599 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts @@ -52,19 +52,21 @@ power_led: led-0 { @@ -110,5 +110,5 @@ index fb1f65c86..553a9e599 100644 }; -- -2.51.0 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/board-nanopi-r4s-pwmfan.patch b/patch/kernel/archive/rockchip64-6.18/board-nanopi-r4s-pwmfan.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-nanopi-r4s-pwmfan.patch rename to patch/kernel/archive/rockchip64-6.18/board-nanopi-r4s-pwmfan.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-odroidm1-add-nodes-for-i2c-pwm-uart-spi.patch b/patch/kernel/archive/rockchip64-6.18/board-odroidm1-add-nodes-for-i2c-pwm-uart-spi.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-odroidm1-add-nodes-for-i2c-pwm-uart-spi.patch rename to patch/kernel/archive/rockchip64-6.18/board-odroidm1-add-nodes-for-i2c-pwm-uart-spi.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-odroidm2-fix-for-ethernet.patch b/patch/kernel/archive/rockchip64-6.18/board-odroidm2-fix-for-ethernet.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-odroidm2-fix-for-ethernet.patch rename to patch/kernel/archive/rockchip64-6.18/board-odroidm2-fix-for-ethernet.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-orangepi-r1-plus.patch b/patch/kernel/archive/rockchip64-6.18/board-orangepi-r1-plus.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-orangepi-r1-plus.patch rename to patch/kernel/archive/rockchip64-6.18/board-orangepi-r1-plus.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-orangepi-rk3399-pcie.patch b/patch/kernel/archive/rockchip64-6.18/board-orangepi-rk3399-pcie.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-orangepi-rk3399-pcie.patch rename to patch/kernel/archive/rockchip64-6.18/board-orangepi-rk3399-pcie.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-orangepi3b-add-uwe5622-wifi-bt-nodes.patch b/patch/kernel/archive/rockchip64-6.18/board-orangepi3b-add-uwe5622-wifi-bt-nodes.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-orangepi3b-add-uwe5622-wifi-bt-nodes.patch rename to patch/kernel/archive/rockchip64-6.18/board-orangepi3b-add-uwe5622-wifi-bt-nodes.patch diff --git a/patch/kernel/archive/rockchip64-6.18/board-orangepi5-sata-supply.patch b/patch/kernel/archive/rockchip64-6.18/board-orangepi5-sata-supply.patch new file mode 100644 index 000000000..055c93f2a --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/board-orangepi5-sata-supply.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: royka1 +Date: Mon, 6 Oct 2025 23:39:26 +0200 +Subject: Add sata node for Orange-Pi-5's overlay (#8707) + +> X-Git-Archeology: > recovered message: > * OPi5: SATA power via vcc3v3_pcie20; set to 3.3V; rename overlay +> X-Git-Archeology: > recovered message: > * Convert spaces to tabs +> X-Git-Archeology: > recovered message: > --------- +> X-Git-Archeology: > recovered message: > Co-authored-by: Igor +> X-Git-Archeology: - Revision 784d367e8aaffa1e2aed7bd844456921b9e8f97e: https://github.com/armbian/build/commit/784d367e8aaffa1e2aed7bd844456921b9e8f97e +> X-Git-Archeology: Date: Mon, 06 Oct 2025 23:39:26 +0200 +> X-Git-Archeology: From: royka1 +> X-Git-Archeology: Subject: Add sata overlay for Orange-Pi-5 (#8707) +> X-Git-Archeology: +> X-Git-Archeology: - Revision f0504a92e16dc4c4d0ae346cc5c0beb126a00298: https://github.com/armbian/build/commit/f0504a92e16dc4c4d0ae346cc5c0beb126a00298 +> X-Git-Archeology: Date: Sat, 18 Oct 2025 11:34:52 +0200 +> X-Git-Archeology: From: Jianfeng Liu +> X-Git-Archeology: Subject: rockchip64-6.18: update patches +> X-Git-Archeology: +--- + arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 11 ++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts +@@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 { + gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + regulator-name = "vcc3v3_pcie20"; + regulator-boot-on; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; + startup-delay-us = <50000>; + vin-supply = <&vcc5v0_sys>; + }; +@@ -27,6 +27,13 @@ &pcie2x1l2 { + status = "okay"; + }; + ++&sata0 { ++ sata-port@0 { ++ target-supply = <&vcc3v3_pcie20>; ++ }; ++}; ++ ++ + &sfc { + status = "okay"; + }; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip64-6.17/board-pbp-add-dp-alt-mode.patch b/patch/kernel/archive/rockchip64-6.18/board-pbp-add-dp-alt-mode.patch similarity index 92% rename from patch/kernel/archive/rockchip64-6.17/board-pbp-add-dp-alt-mode.patch rename to patch/kernel/archive/rockchip64-6.18/board-pbp-add-dp-alt-mode.patch index e410e4d8f..f17d853dd 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-pbp-add-dp-alt-mode.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-pbp-add-dp-alt-mode.patch @@ -40,7 +40,7 @@ index 111111111111..222222222222 100644 &edp { force-hpd; pinctrl-names = "default"; -@@ -692,6 +706,8 @@ fusb0: fusb30x@22 { +@@ -685,6 +699,8 @@ fusb0: fusb30x@22 { pinctrl-names = "default"; pinctrl-0 = <&fusb0_int_pin>; vbus-supply = <&vbus_typec>; @@ -49,7 +49,7 @@ index 111111111111..222222222222 100644 connector { compatible = "usb-c-connector"; -@@ -700,10 +716,19 @@ connector { +@@ -693,10 +709,19 @@ connector { op-sink-microwatt = <1000000>; power-role = "dual"; sink-pdos = @@ -71,7 +71,7 @@ index 111111111111..222222222222 100644 ports { #address-cells = <1>; -@@ -970,6 +995,7 @@ spiflash: flash@0 { +@@ -982,6 +1007,7 @@ spiflash: flash@0 { }; &tcphy0 { @@ -79,7 +79,7 @@ index 111111111111..222222222222 100644 status = "okay"; }; -@@ -1003,6 +1029,8 @@ &tsadc { +@@ -1015,6 +1041,8 @@ &tsadc { &u2phy0 { status = "okay"; @@ -88,7 +88,7 @@ index 111111111111..222222222222 100644 u2phy0_otg: otg-port { status = "okay"; -@@ -1079,7 +1107,9 @@ &usbdrd3_0 { +@@ -1091,7 +1119,9 @@ &usbdrd3_0 { }; &usbdrd_dwc3_0 { diff --git a/patch/kernel/archive/rockchip64-6.17/board-radxa-e25-sdmmc0-fix.patch b/patch/kernel/archive/rockchip64-6.18/board-radxa-e25-sdmmc0-fix.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-radxa-e25-sdmmc0-fix.patch rename to patch/kernel/archive/rockchip64-6.18/board-radxa-e25-sdmmc0-fix.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-radxa-e25-usb3-and-emmc-fix.patch b/patch/kernel/archive/rockchip64-6.18/board-radxa-e25-usb3-and-emmc-fix.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-radxa-e25-usb3-and-emmc-fix.patch rename to patch/kernel/archive/rockchip64-6.18/board-radxa-e25-usb3-and-emmc-fix.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-cc-dts-enable-dmc.patch b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-cc-dts-enable-dmc.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-cc-dts-enable-dmc.patch rename to patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-cc-dts-enable-dmc.patch index dfc179031..7448251b9 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-cc-dts-enable-dmc.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-cc-dts-enable-dmc.patch @@ -52,7 +52,7 @@ index 111111111111..222222222222 100644 gmac_clkin: external-gmac-clock { compatible = "fixed-clock"; clock-frequency = <125000000>; -@@ -111,6 +138,17 @@ &codec { +@@ -118,6 +145,17 @@ &codec { status = "okay"; }; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-cc-dts-ram-profile.patch b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-cc-dts-ram-profile.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-cc-dts-ram-profile.patch rename to patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-cc-dts-ram-profile.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-pc-dts-ram-profile.patch b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-pc-dts-ram-profile.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-pc-dts-ram-profile.patch rename to patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-pc-dts-ram-profile.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-pc.patch b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-pc.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-pc.patch rename to patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-pc.patch index 8d37eb6a3..b4863ac7a 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rk3328-roc-pc.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rk3328-roc-pc.patch @@ -4,14 +4,14 @@ Date: Tue, 12 Oct 2021 19:34:29 +0000 Subject: enable dmc for rk3328-roc-pc --- - arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts | 524 +++++++++- - 1 file changed, 466 insertions(+), 58 deletions(-) + arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts | 521 +++++++++- + 1 file changed, 464 insertions(+), 57 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts -@@ -1,109 +1,517 @@ +@@ -1,105 +1,512 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -// Copyright (c) 2021 T-Chip Intelligent Technology Co., Ltd +/* @@ -117,7 +117,7 @@ index 111111111111..222222222222 100644 + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; -+ }; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; @@ -187,11 +187,9 @@ index 111111111111..222222222222 100644 + opp-hz = /bits/ 64 <924000000>; + opp-microvolt = <1100000 1100000 1200000>; + }; - }; - }; - --&codec { -- mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ +&dfi { + status = "okay"; +}; @@ -216,17 +214,8 @@ index 111111111111..222222222222 100644 + +&cpu0 { + cpu-supply = <&vdd_arm>; - }; - - &gpu { -+ status = "okay"; - mali-supply = <&vdd_logic>; - }; - --&pinctrl { -- ir { -- ir_int: ir-int { -- rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++}; ++ +&gmac2phy { + phy-supply = <&vcc_phy>; + clock_in_out = "output"; @@ -308,13 +297,18 @@ index 111111111111..222222222222 100644 +&i2s1 { + #sound-dai-cells = <0>; + status = "okay"; -+}; -+ -+&codec { + }; + + &codec { +- mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + status = "okay"; -+}; -+ + }; + +-&pinctrl { +- ir { +- ir_int: ir-int { +- rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; +&emmc { + bus-width = <8>; + cap-mmc-highspeed; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rock3a-0001-emmc-sfc.patch b/patch/kernel/archive/rockchip64-6.18/board-rock3a-0001-emmc-sfc.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rock3a-0001-emmc-sfc.patch rename to patch/kernel/archive/rockchip64-6.18/board-rock3a-0001-emmc-sfc.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rock3a-0002-usb3.patch b/patch/kernel/archive/rockchip64-6.18/board-rock3a-0002-usb3.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rock3a-0002-usb3.patch rename to patch/kernel/archive/rockchip64-6.18/board-rock3a-0002-usb3.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rock3a-0003-add-gpio-names.patch b/patch/kernel/archive/rockchip64-6.18/board-rock3a-0003-add-gpio-names.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rock3a-0003-add-gpio-names.patch rename to patch/kernel/archive/rockchip64-6.18/board-rock3a-0003-add-gpio-names.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rock5c-add-gpio-names.patch b/patch/kernel/archive/rockchip64-6.18/board-rock5c-add-gpio-names.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rock5c-add-gpio-names.patch rename to patch/kernel/archive/rockchip64-6.18/board-rock5c-add-gpio-names.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rock64-mail-supply.patch b/patch/kernel/archive/rockchip64-6.18/board-rock64-mail-supply.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rock64-mail-supply.patch rename to patch/kernel/archive/rockchip64-6.18/board-rock64-mail-supply.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpi3-enable-dmc.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpi3-enable-dmc.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rockpi3-enable-dmc.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpi3-enable-dmc.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpi4-0003-arm64-dts-pcie.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpi4-0003-arm64-dts-pcie.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rockpi4-0003-arm64-dts-pcie.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpi4-0003-arm64-dts-pcie.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpis-dts-fixes.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpis-dts-fixes.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rockpis-dts-fixes.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpis-dts-fixes.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch index 2c7b06e6a..dd8e000fb 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-0001-Add-pcie-bus-scan-delay.patch @@ -13,7 +13,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boo index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -677,6 +677,7 @@ &pcie0 { +@@ -617,6 +617,7 @@ &pcie0 { vpcie1v8-supply = <&vcca_1v8>; vpcie12v-supply = <&vcc12v_dcin>; vpcie3v3-supply = <&vcc3v3_pcie>; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-change-rx_delay-for-gmac.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-change-rx_delay-for-gmac.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/board-rockpro64-change-rx_delay-for-gmac.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpro64-change-rx_delay-for-gmac.patch index 5ab1edbdc..945358ebe 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-change-rx_delay-for-gmac.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-change-rx_delay-for-gmac.patch @@ -12,7 +12,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boo index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -317,7 +317,7 @@ &gmac { +@@ -300,7 +300,7 @@ &gmac { snps,reset-active-low; snps,reset-delays-us = <0 10000 50000>; tx_delay = <0x28>; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-emmc.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-emmc.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-emmc.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-emmc.patch index 96fdbdcf0..48029d8c9 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-emmc.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-emmc.patch @@ -20,7 +20,7 @@ index 111111111111..222222222222 100644 stdout-path = "serial2:1500000n8"; }; -@@ -829,6 +830,7 @@ &sdmmc { +@@ -765,6 +766,7 @@ &sdmmc { &sdhci { bus-width = <8>; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-spi1-flash-speed.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-spi1-flash-speed.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-spi1-flash-speed.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-spi1-flash-speed.patch index d40cee738..8320c1817 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-fix-spi1-flash-speed.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-fix-spi1-flash-speed.patch @@ -12,7 +12,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boo index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -852,7 +852,7 @@ &spi1 { +@@ -788,7 +788,7 @@ &spi1 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-work-led-heartbeat.patch b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-work-led-heartbeat.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/board-rockpro64-work-led-heartbeat.patch rename to patch/kernel/archive/rockchip64-6.18/board-rockpro64-work-led-heartbeat.patch index 40d526a8a..7cffccb89 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-rockpro64-work-led-heartbeat.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-rockpro64-work-led-heartbeat.patch @@ -11,7 +11,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boo index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -@@ -66,7 +66,7 @@ leds { +@@ -57,7 +57,7 @@ leds { work_led: led-0 { label = "work"; diff --git a/patch/kernel/archive/rockchip64-6.17/board-rocks0.patch b/patch/kernel/archive/rockchip64-6.18/board-rocks0.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-rocks0.patch rename to patch/kernel/archive/rockchip64-6.18/board-rocks0.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-station-m2.patch b/patch/kernel/archive/rockchip64-6.18/board-station-m2.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/board-station-m2.patch rename to patch/kernel/archive/rockchip64-6.18/board-station-m2.patch diff --git a/patch/kernel/archive/rockchip64-6.17/board-station-p2.patch b/patch/kernel/archive/rockchip64-6.18/board-station-p2.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/board-station-p2.patch rename to patch/kernel/archive/rockchip64-6.18/board-station-p2.patch index 4d568d03b..b171f3ed9 100644 --- a/patch/kernel/archive/rockchip64-6.17/board-station-p2.patch +++ b/patch/kernel/archive/rockchip64-6.18/board-station-p2.patch @@ -9,8 +9,8 @@ Subject: [ARCHEOLOGY] fix rk3568-roc-pc > X-Git-Archeology: Subject: fix rk3568-roc-pc > X-Git-Archeology: --- - arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts | 380 ++++++++-- - 1 file changed, 325 insertions(+), 55 deletions(-) + arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts | 378 ++++++++-- + 1 file changed, 324 insertions(+), 54 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts index 111111111111..222222222222 100644 @@ -341,15 +341,6 @@ index 111111111111..222222222222 100644 }; }; -@@ -474,7 +622,7 @@ rgmii_phy1: phy@0 { - }; - - &pcie30phy { -- status = "okay"; -+ tatus = "okay"; - }; - - &pcie3x2 { @@ -487,19 +635,27 @@ &pcie3x2 { &pinctrl { diff --git a/patch/kernel/archive/rockchip64-6.17/drv-spi-spidev-remove-warnings.patch b/patch/kernel/archive/rockchip64-6.18/drv-spi-spidev-remove-warnings.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/drv-spi-spidev-remove-warnings.patch rename to patch/kernel/archive/rockchip64-6.18/drv-spi-spidev-remove-warnings.patch index 013ac0fce..32495a9e3 100644 --- a/patch/kernel/archive/rockchip64-6.17/drv-spi-spidev-remove-warnings.patch +++ b/patch/kernel/archive/rockchip64-6.18/drv-spi-spidev-remove-warnings.patch @@ -9,7 +9,7 @@ Signed-off-by: John Doe 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 5300c942a2a4..67e802d5419d 100644 +index 111111111111..222222222222 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -703,6 +703,7 @@ static const struct class spidev_class = { @@ -22,7 +22,7 @@ index 5300c942a2a4..67e802d5419d 100644 { .name = /* dh */ "dhcom-board" }, @@ -736,6 +737,7 @@ static int spidev_of_check(struct device *dev) } - + static const struct of_device_id spidev_dt_ids[] = { + { .compatible = "armbian,spi-dev", .data = &spidev_of_check }, { .compatible = "abb,spi-sensor", .data = &spidev_of_check }, diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3308-sakurapi-rk3308b.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3308-sakurapi-rk3308b.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3308-sakurapi-rk3308b.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3308-sakurapi-rk3308b.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3318-box.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3318-box.dts similarity index 97% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3318-box.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3318-box.dts index 7690565b9..e6338135b 100644 --- a/patch/kernel/archive/rockchip64-6.17/dt/rk3318-box.dts +++ b/patch/kernel/archive/rockchip64-6.18/dt/rk3318-box.dts @@ -23,7 +23,6 @@ }; /delete-node/ opp-table-0; - /delete-node/ gpu-opp-table; cpu0_opp_table: opp_table0 { compatible = "operating-points-v2"; @@ -59,30 +58,6 @@ }; }; - gpu_opp_table: gpu-opp-table { - compatible = "operating-points-v2"; - - opp-200000000 { - opp-hz = /bits/ 64 <200000000>; - opp-microvolt = <1000000 950000 1200000>; - }; - - opp-300000000 { - opp-hz = /bits/ 64 <300000000>; - opp-microvolt = <1050000 950000 1200000>; - }; - - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; - opp-microvolt = <1050000 950000 1200000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <1100000 950000 1200000>; - }; - }; - chosen { stdout-path = "serial2:1500000n8"; }; diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-dusun-dsom-010r.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-dusun-dsom-010r.dts similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-dusun-dsom-010r.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-dusun-dsom-010r.dts index 3c0c0eb55..f182985a3 100644 --- a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-dusun-dsom-010r.dts +++ b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-dusun-dsom-010r.dts @@ -126,7 +126,6 @@ }; /delete-node/ opp-table-0; - /delete-node/ gpu-opp-table; cpu0_opp_table: opp_table0 { compatible = "operating-points-v2"; @@ -160,30 +159,6 @@ }; }; - gpu_opp_table: gpu-opp-table { - compatible = "operating-points-v2"; - - opp-200000000 { - opp-hz = /bits/ 64 <200000000>; - opp-microvolt = <1000000 950000 1200000>; - }; - - opp-300000000 { - opp-hz = /bits/ 64 <300000000>; - opp-microvolt = <1050000 950000 1200000>; - }; - - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; - opp-microvolt = <1050000 950000 1200000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <1100000 950000 1200000>; - }; - }; - sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-heltec.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-heltec.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-heltec.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-heltec.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-mksklipad50.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-mksklipad50.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-mksklipad50.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-mksklipad50.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-mkspi.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-mkspi.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-mkspi.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-mkspi.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-neo3-rev02.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-neo3-rev02.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-neo3-rev02.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-neo3-rev02.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev00.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev00.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev00.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev00.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev06.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev06.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev06.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev06.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev20.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev20.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2-rev20.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2-rev20.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2s-plus-rev00.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2s-plus-rev00.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-nanopi-r2s-plus-rev00.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-nanopi-r2s-plus-rev00.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3328-z28pro.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3328-z28pro.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3328-z28pro.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3328-z28pro.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-am40.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-am40.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-am40.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-am40.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-fine3399.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-fine3399.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-fine3399.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-fine3399.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-nanopi-m4v2.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-nanopi-m4v2.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-nanopi-m4v2.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-nanopi-m4v2.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-nanopi-r4se.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-nanopi-r4se.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-nanopi-r4se.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-nanopi-r4se.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-orangepi-4-lts.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-orangepi-4-lts.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-orangepi-4-lts.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-orangepi-4-lts.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-orangepi-4.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-orangepi-4.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-orangepi-4.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-orangepi-4.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-rock-pi-4.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-rock-pi-4.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-rock-pi-4.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-rock-pi-4.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-tinker-2.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-tinker-2.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-tinker-2.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-tinker-2.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3399-xiaobao-nas.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3399-xiaobao-nas.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3399-xiaobao-nas.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3399-xiaobao-nas.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3566-h96-tvbox.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3566-h96-tvbox.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3566-h96-tvbox.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3566-h96-tvbox.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3566-jp-tvbox.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3566-jp-tvbox.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3566-jp-tvbox.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3566-jp-tvbox.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3566-lckfb-tspi.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3566-lckfb-tspi.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3566-lckfb-tspi.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3566-lckfb-tspi.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3566-nanopi-r3s-lts.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3566-nanopi-r3s-lts.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3566-nanopi-r3s-lts.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3566-nanopi-r3s-lts.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3566-panther-x2.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3566-panther-x2.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3566-panther-x2.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3566-panther-x2.dts diff --git a/patch/kernel/archive/rockchip64-6.18/dt/rk3568-9tripod-x3568-v4.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-9tripod-x3568-v4.dts new file mode 100644 index 000000000..ad4d62060 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-9tripod-x3568-v4.dts @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "9Tripod X3568 v4"; + compatible = "9tripod,x3568-v4", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc0; + mmc2 = &sdmmc2; + rtc0 = &rtc0; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-vol-up { + label = "volume up"; + linux,code = ; + press-threshold-microvolt = <50000>; + }; + + button-vol-down { + label = "volume down"; + linux,code = ; + press-threshold-microvolt = <500000>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_work: led-0 { + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_HEARTBEAT; + color = ; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_work_en>; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + pdm_codec: pdm-codec { + compatible = "dmic-codec"; + num-channels = <2>; + #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>; + }; + }; + + spdif_dit: spdif-dit { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + spdif_sound: spdif-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + simple-audio-card,codec { + sound-dai = <&spdif_dit>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <300>; + reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + }; + + dc_12v: regulator-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc3v3_pcie: regulator-vcc3v3-pcie { + compatible = "regulator-gpio"; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <100000>; + regulator-max-microvolt = <3300000>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc3v3_pcie_en_pin>; + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <100000 0>, <3300000 1>; + startup-delay-us = <5000>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb_host: regulator-vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_host_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_otg: regulator-vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 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_usb>; + }; +}; + +&can1 { + assigned-clocks = <&cru CLK_CAN1>; + assigned-clock-rates = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&can1m1_pins>; + status = "okay"; +}; + +/* used for usb_host0_xhci */ +&combphy0 { + status = "okay"; +}; + +/* used for usb_host1_xhci */ +&combphy1 { + status = "okay"; +}; + +/* connected to sata2 */ +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + 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 = ; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; + system-power-controller; + #sound-dai-cells = <0>; + 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; + + 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; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_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; + }; + }; + + 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-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; + }; + }; + }; + + codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2c5 { + status = "okay"; + + rtc0: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + #clock-cells = <0>; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>; + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +/* used for AP6275S Bluetooth Sound */ +&i2s3_2ch { + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&pcie30phy { + status = "okay"; +}; + +&pcie3x2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pin>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pdm { + status = "okay"; +}; + +&pinctrl { + leds { + led_work_en: led_work_en { + rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable: wifi-enable { + rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_usb_host_en: vcc5v0_usb_host_en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_reset_pin: pcie-reset-pin { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin { + rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +/* Required remotectl for IR receiver */ +&pwm7 { + status = "disabled"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +/* used for eMMC */ +&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>; + status = "okay"; +}; + +/* used for microSD (TF) Slot */ +&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-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +/* used for AP6275S WiFi */ +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +/* used for Debug */ +&uart2 { + status = "okay"; +}; + +&uart3 { + pinctrl-0 = <&uart3m1_xfer>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4m1_xfer>; + status = "okay"; +}; + +/* used for WiFi/BT AP6275S */ +&uart8 { + pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn>; + status = "okay"; +}; + +&uart9 { + pinctrl-0 = <&uart9m1_xfer>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + 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_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb_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 = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-h66k.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-h66k.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-h66k.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-h66k.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-h68k.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-h68k.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-h68k.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-h68k.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-hnas.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-hnas.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3568-hinlink-hnas.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3568-hinlink-hnas.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3568-mixtile-edge2.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-mixtile-edge2.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3568-mixtile-edge2.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3568-mixtile-edge2.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3568-yy3568.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3568-yy3568.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3568-yy3568.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3576-bananapi-m5-pro.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3576-bananapi-m5-pro.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3576-bananapi-m5-pro.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3576-bananapi-m5-pro.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3576-nanopi-m5.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3576-nanopi-m5.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3576-nanopi-m5.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3576-nanopi-m5.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3576-nanopi-r76s.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3576-nanopi-r76s.dts similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3576-nanopi-r76s.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3576-nanopi-r76s.dts index cbac958b9..f3d024a4a 100644 --- a/patch/kernel/archive/rockchip64-6.17/dt/rk3576-nanopi-r76s.dts +++ b/patch/kernel/archive/rockchip64-6.18/dt/rk3576-nanopi-r76s.dts @@ -797,6 +797,10 @@ }; /* UART Configuration */ +&uart0 { + status = "okay"; +}; + &uart5 { pinctrl-names = "default"; pinctrl-0 = <&uart5m0_xfer &uart5m0_ctsn &uart5m0_rtsn>; diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588-bananapi-m7.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588-bananapi-m7.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588-bananapi-m7.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588-bananapi-m7.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588-cyber-aib.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588-cyber-aib.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588-cyber-aib.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588-cyber-aib.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588-hinlink-h88k.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588-hinlink-h88k.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588-hinlink-h88k.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588-hinlink-h88k.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588-mixtile-blade3.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588-mixtile-blade3.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588-mixtile-blade3.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588-mixtile-blade3.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588s-nanopi-m6.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588s-nanopi-m6.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588s-nanopi-m6.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588s-nanopi-m6.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588s-orangepi-5-pro.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588s-orangepi-5-pro.dts similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588s-orangepi-5-pro.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588s-orangepi-5-pro.dts diff --git a/patch/kernel/archive/rockchip64-6.17/dt/rk3588s-youyeetoo-r1.dts b/patch/kernel/archive/rockchip64-6.18/dt/rk3588s-youyeetoo-r1.dts similarity index 85% rename from patch/kernel/archive/rockchip64-6.17/dt/rk3588s-youyeetoo-r1.dts rename to patch/kernel/archive/rockchip64-6.18/dt/rk3588s-youyeetoo-r1.dts index 953c66006..b50b2f58c 100644 --- a/patch/kernel/archive/rockchip64-6.17/dt/rk3588s-youyeetoo-r1.dts +++ b/patch/kernel/archive/rockchip64-6.18/dt/rk3588s-youyeetoo-r1.dts @@ -24,19 +24,44 @@ stdout-path = "serial2:1500000n8"; }; - leds { - compatible = "gpio-leds"; + es8323-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rockchip-es8323"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,pin-switches = "Headphones"; + simple-audio-card,routing = + "Headphones", "LOUT1", + "Headphones", "ROUT1", + "LINPUT1", "Microphone Jack", + "RINPUT1", "Microphone Jack", + "LINPUT2", "Onboard Microphone", + "RINPUT2", "Onboard Microphone"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Microphone", "Onboard Microphone", + "Headphone", "Headphones"; - sys_led: led-0 { - label = "sys_led"; - gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - pinctrl-names = "default"; - pinctrl-0 = <&sys_led_pin>; + simple-audio-card,cpu { + sound-dai = <&i2s0_8ch>; + }; + + simple-audio-card,codec { + sound-dai = <&es8323>; + system-clock-frequency = <12288000>; }; }; - /* HDMI 0 CONNECTOR */ + fan0: pwm-fan { + compatible = "pwm-fan"; + #cooling-cells = <2>; + cooling-levels = <100 160 190 200 215 235 255>; + pwms = <&pwm6 0 40000 0>; + fan-supply = <&vcc12v_dcin>; + }; hdmi0-con { compatible = "hdmi-connector"; @@ -49,7 +74,17 @@ }; }; - /* POWER REGULATOR 12V DC-IN */ + leds { + compatible = "gpio-leds"; + + sys_led: led-0 { + label = "sys_led"; + gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_led_pin>; + }; + }; vcc12v_dcin: vcc12v-dcin-regulator { compatible = "regulator-fixed"; @@ -60,8 +95,6 @@ regulator-max-microvolt = <12000000>; }; - /* POWER REGULATOR 5V SYS */ - vcc5v0_sys: vcc5v0-sys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc5v0_sys"; @@ -72,8 +105,6 @@ vin-supply = <&vcc12v_dcin>; }; - /* POWER REGULATOR CPU */ - vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_1v1_nldo_s3"; @@ -84,7 +115,15 @@ vin-supply = <&vcc5v0_sys>; }; - /* POWER REGULATOR 3V (SD) */ + vcc_3v3_pcie20: vcc3v3-pcie20-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_pcie20"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator { compatible = "regulator-fixed"; @@ -99,31 +138,7 @@ vin-supply = <&vcc_3v3_s3>; }; - /* POWER REGULATOR 3.3V (PCIE)*/ - - vcc_3v3_pcie20: vcc3v3-pcie20-regulator { - compatible = "regulator-fixed"; - regulator-name = "vcc_3v3_pcie20"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc_3v3_s3>; - }; - - /* POWER REGULATOR 5V (USB2 & USB3) */ - - vcc5v0_usb: vcc5v0-usb-regulator { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_usb"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc5v0_host_20: vcc5v0-host-20 { // U13 (USB 2.0) + vcc5v0_host_20: vcc5v0-host-20 { compatible = "regulator-fixed"; enable-active-high; gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; @@ -135,7 +150,7 @@ vin-supply = <&vcc5v0_usb>; }; - vcc5v0_host_30: vcc5v0-host-30 { // U12 (USB 3.0) + vcc5v0_host_30: vcc5v0-host-30 { compatible = "regulator-fixed"; enable-active-high; gpio = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; @@ -147,8 +162,16 @@ vin-supply = <&vcc5v0_usb>; }; + vcc5v0_usb: vcc5v0-usb-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; - /* BLUETOOTH */ wireless_bluetooth: wireless-bluetooth { compatible = "bluetooth-platdata"; clocks = <&hym8563>; @@ -156,7 +179,6 @@ status = "okay"; }; - /* WIFI */ wireless_wlan: wireless-wlan { compatible = "wlan-platdata"; wifi_chip_type = "rtl8852be"; @@ -165,15 +187,6 @@ WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; status = "okay"; }; - - /* FAN */ - fan0: pwm-fan { - compatible = "pwm-fan"; - #cooling-cells = <2>; - cooling-levels = <100 160 190 200 215 235 255>; - pwms = <&pwm6 0 40000 0>; - fan-supply = <&vcc12v_dcin>; - }; }; &combphy0_ps { @@ -184,21 +197,6 @@ status = "okay"; }; -&gmac1 { - clock_in_out = "output"; - phy-handle = <&rgmii_phy1>; - phy-mode = "rgmii-rxid"; - pinctrl-0 = <&gmac1_miim - &gmac1_tx_bus2 - &gmac1_rx_bus2 - &gmac1_rgmii_clk - &gmac1_rgmii_bus>; - pinctrl-names = "default"; - tx_delay = <0x42>; - tx_delay = <0x43>; - status = "okay"; -}; - &cpu_b0 { cpu-supply = <&vdd_cpu_big0_s0>; mem-supply = <&vdd_cpu_big0_mem_s0>; @@ -239,6 +237,21 @@ mem-supply = <&vdd_cpu_lit_mem_s0>; }; +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-rxid"; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + pinctrl-names = "default"; + rx_delay = <0x00>; + tx_delay = <0x43>; + status = "okay"; +}; + &gpu { mali-supply = <&vdd_gpu_s0>; status = "okay"; @@ -332,25 +345,68 @@ }; &i2c6 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c6m3_xfer>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m3_xfer>; - /* RTC */ - hym8563: hym8563@51 { - compatible = "haoyu,hym8563"; - reg = <0x51>; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "hym8563"; - status = "okay"; - }; + hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "hym8563"; + pinctrl-0 = <&hym8563_int>; + status = "okay"; + }; +}; + +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7m0_xfer>; + + /* + * in the Youyeetoo BSP source this was confusingly called an + * "ES8388" - it actually seems to be an ES8323 and the drivers + * for that work best + */ + + es8323: audio-codec@11 { + compatible = "everest,es8323"; + reg = <0x11>; + clocks = <&cru I2S0_8CH_MCLKOUT>; + clock-names = "mclk"; + assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; + assigned-clock-rates = <12288000>; + AVDD-supply = <&avcc_1v8_s0>; + DVDD-supply = <&avcc_1v8_s0>; + HPVDD-supply = <&vcc_3v3_s0>; + PVDD-supply = <&vcc_3v3_s0>; + #sound-dai-cells = <0>; + }; +}; + +&i2s0_8ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_lrck + &i2s0_mclk + &i2s0_sclk + &i2s0_sdi0 + &i2s0_sdo0>; + status = "okay"; }; &i2s5_8ch { status = "okay"; }; +&mdio1 { + rgmii_phy1: phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + }; +}; + &package_thermal { polling-delay = <1000>; @@ -379,14 +435,6 @@ }; }; - -&mdio1 { - rgmii_phy1: phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x1>; - }; -}; - &pcie2x1l1 { reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; rockchip,init-delay-ms = <100>; @@ -402,41 +450,40 @@ &pinctrl { - /* TODO: SOUND */ - sound { - hp_detect: hp-detect { - rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + headphone { + hp_det: hp-det { + rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; }; }; - /* GPIO LEDS */ + + hym8563 { + hym8563_int: hym8563-int { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-leds { sys_led_pin: sys-led-pin { rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; }; }; - /* RTC */ - hym8563 { - rtc_int: rtc-int { - rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - /* SD */ sdmmc { sd_s0_pwr: sd-s0-pwr { rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; }; }; - /* USB */ + usb { - vcc5v0_host20_en: vcc5v0-host20-en { // USB 2.0 - rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>; + vcc5v0_host20_en: vcc5v0-host20-en { + rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>; }; - vcc5v0_host30_en: vcc5v0-host30-en { // USB 3.0 - rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + vcc5v0_host30_en: vcc5v0-host30-en { + rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; }; }; - /* WIRELESS */ + wireless-wlan { wifi_host_wake_irq: wifi-host-wake-irq { rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; @@ -444,8 +491,37 @@ }; }; -&saradc { - vref-supply = <&avcc_1v8_s0>; +&pwm6 { + status = "okay"; +}; + +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { status = "okay"; }; @@ -454,25 +530,25 @@ no-sdio; no-sd; non-removable; - /* HS400 doesn't work properly -> https://github.com/torvalds/linux/commit/cee572756aa2cb46e959e9797ad4b730b78a050b */ - mmc-hs200-1_8v; max-frequency = <200000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; status = "okay"; }; &sdmmc { - max-frequency = <200000000>; - no-sdio; - no-mmc; bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; disable-wp; + max-frequency = <200000000>; + no-sdio; + no-mmc; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>; sd-uhs-sdr104; vmmc-supply = <&vcc_3v3_sd_s0>; vqmmc-supply = <&vccio_sd_s0>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>; status = "okay"; }; @@ -518,13 +594,13 @@ #gpio-cells = <2>; rk806_dvs1_null: dvs1-null-pins { - pins = "gpio_pwrctrl2"; + pins = "gpio_pwrctrl1"; function = "pin_fun0"; }; rk806_dvs2_null: dvs2-null-pins { pins = "gpio_pwrctrl2"; - function = "pin_fudr_moden0"; + function = "pin_fun0"; }; rk806_dvs3_null: dvs3-null-pins { @@ -803,30 +879,11 @@ }; }; -&uart2 { - pinctrl-0 = <&uart2m0_xfer>; - status = "okay"; -}; - -&pwm6{ - status = "okay"; -}; - &tsadc { status = "okay"; }; -/* USB */ - &u2phy0 { - status = "okay"; -}; - -&u2phy2 { - status = "okay"; -}; - -&u2phy3 { status = "okay"; }; @@ -835,20 +892,27 @@ status = "okay"; }; +&u2phy2 { + status = "okay"; +}; + &u2phy2_host { phy-supply = <&vcc5v0_host_20>; status = "okay"; }; -&u2phy3_host { - phy-supply = <&vcc5v0_host_20>; - status = "okay"; +&u2phy3 { + status = "okay"; }; -&usb_host0_xhci { +&u2phy3_host { + phy-supply = <&vcc5v0_host_20>; + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; status = "okay"; - dr_mode = "host"; - extcon = <&u2phy0>; }; &usb_host0_ehci { @@ -859,6 +923,12 @@ status = "okay"; }; +&usb_host0_xhci { + status = "okay"; + dr_mode = "host"; + extcon = <&u2phy0>; +}; + &usb_host1_ehci { status = "okay"; }; @@ -871,11 +941,11 @@ status = "okay"; }; -&vop_mmu { +&vop { status = "okay"; }; -&vop { +&vop_mmu { status = "okay"; }; diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-hdmi-mks-ips50-resolutions.patch b/patch/kernel/archive/rockchip64-6.18/general-add-hdmi-mks-ips50-resolutions.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/general-add-hdmi-mks-ips50-resolutions.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-hdmi-mks-ips50-resolutions.patch index a0339c3d6..3b0fa7fad 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-add-hdmi-mks-ips50-resolutions.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-add-hdmi-mks-ips50-resolutions.patch @@ -15,7 +15,7 @@ diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c -@@ -1550,6 +1550,16 @@ static const struct drm_display_mode edid_cea_modes_193[] = { +@@ -1561,6 +1561,16 @@ static const struct drm_display_mode edid_cea_modes_193[] = { 4272, 4400, 0, 2160, 2168, 2178, 2250, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, @@ -32,7 +32,7 @@ index 111111111111..222222222222 100644 }; /* -@@ -4215,7 +4225,7 @@ static bool drm_edid_has_cta_extension(const struct drm_edid *drm_edid) +@@ -4236,7 +4246,7 @@ static bool drm_edid_has_cta_extension(const struct drm_edid *drm_edid) static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic) { BUILD_BUG_ON(1 + ARRAY_SIZE(edid_cea_modes_1) - 1 != 127); diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-miniDP-dt-doc.patch b/patch/kernel/archive/rockchip64-6.18/general-add-miniDP-dt-doc.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-add-miniDP-dt-doc.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-miniDP-dt-doc.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-miniDP-virtual-extcon.patch b/patch/kernel/archive/rockchip64-6.18/general-add-miniDP-virtual-extcon.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/general-add-miniDP-virtual-extcon.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-miniDP-virtual-extcon.patch index 6fb6ea1e9..7b28d61e9 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-add-miniDP-virtual-extcon.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-add-miniDP-virtual-extcon.patch @@ -62,7 +62,7 @@ diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 111111111111..222222222222 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig -@@ -214,4 +214,14 @@ config EXTCON_RTK_TYPE_C +@@ -227,4 +227,14 @@ config EXTCON_RTK_TYPE_C The DHC (Digital Home Hub) RTD series SoC contains a type c module. This driver will detect the status of the type-c port. @@ -81,7 +81,7 @@ diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 111111111111..222222222222 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile -@@ -27,3 +27,4 @@ obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o +@@ -28,3 +28,4 @@ obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o obj-$(CONFIG_EXTCON_RTK_TYPE_C) += extcon-rtk-type-c.o diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-overlay-compilation-support.patch b/patch/kernel/archive/rockchip64-6.18/general-add-overlay-compilation-support.patch similarity index 97% rename from patch/kernel/archive/rockchip64-6.17/general-add-overlay-compilation-support.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-overlay-compilation-support.patch index 267fd37eb..75b5b3dd7 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-add-overlay-compilation-support.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-add-overlay-compilation-support.patch @@ -36,7 +36,7 @@ diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs index 111111111111..222222222222 100644 --- a/scripts/Makefile.dtbs +++ b/scripts/Makefile.dtbs -@@ -122,17 +122,23 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) +@@ -123,17 +123,23 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) quiet_cmd_dtc = DTC $(quiet_dtb_check_tag) $@ cmd_dtc = \ $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-overlay-configfs.patch b/patch/kernel/archive/rockchip64-6.18/general-add-overlay-configfs.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-add-overlay-configfs.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-overlay-configfs.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-panel-simple-dsi.patch b/patch/kernel/archive/rockchip64-6.18/general-add-panel-simple-dsi.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-add-panel-simple-dsi.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-panel-simple-dsi.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-pll-hdmi-timings.patch b/patch/kernel/archive/rockchip64-6.18/general-add-pll-hdmi-timings.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-add-pll-hdmi-timings.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-pll-hdmi-timings.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-add-xtx-spi-nor-chips.patch b/patch/kernel/archive/rockchip64-6.18/general-add-xtx-spi-nor-chips.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-add-xtx-spi-nor-chips.patch rename to patch/kernel/archive/rockchip64-6.18/general-add-xtx-spi-nor-chips.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-cryptov1-trng.patch b/patch/kernel/archive/rockchip64-6.18/general-cryptov1-trng.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/general-cryptov1-trng.patch rename to patch/kernel/archive/rockchip64-6.18/general-cryptov1-trng.patch index 2daa1002a..ffffaddca 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-cryptov1-trng.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-cryptov1-trng.patch @@ -18,7 +18,7 @@ diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 111111111111..222222222222 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig -@@ -694,6 +694,14 @@ config CRYPTO_DEV_ROCKCHIP +@@ -707,6 +707,14 @@ config CRYPTO_DEV_ROCKCHIP This driver interfaces with the hardware crypto accelerator. Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. diff --git a/patch/kernel/archive/rockchip64-6.17/general-disable-mtu-validation.patch b/patch/kernel/archive/rockchip64-6.18/general-disable-mtu-validation.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/general-disable-mtu-validation.patch rename to patch/kernel/archive/rockchip64-6.18/general-disable-mtu-validation.patch index 4c3523c4f..2d9301e7c 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-disable-mtu-validation.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-disable-mtu-validation.patch @@ -18,7 +18,7 @@ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/eth index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5934,27 +5934,15 @@ static void stmmac_set_rx_mode(struct net_device *dev) +@@ -5846,27 +5846,15 @@ static void stmmac_set_rx_mode(struct net_device *dev) static int stmmac_change_mtu(struct net_device *dev, int new_mtu) { struct stmmac_priv *priv = netdev_priv(dev); diff --git a/patch/kernel/archive/rockchip64-6.17/general-driver-tm16xx-led-driver.patch b/patch/kernel/archive/rockchip64-6.18/general-driver-tm16xx-led-driver.patch similarity index 87% rename from patch/kernel/archive/rockchip64-6.17/general-driver-tm16xx-led-driver.patch rename to patch/kernel/archive/rockchip64-6.18/general-driver-tm16xx-led-driver.patch index f39dd28dd..c79318594 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-driver-tm16xx-led-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-driver-tm16xx-led-driver.patch @@ -1,106 +1,7 @@ -From 80cbedd730c85b852ab68ebff40b520b339d9d3c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= -Date: Mon, 1 Sep 2025 12:16:39 -0400 -Subject: [PATCH 01/14] device property: Add scoped fwnode child node iterators -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add scoped versions of fwnode child node iterators that automatically -handle reference counting cleanup using the __free() attribute: - -- fwnode_for_each_child_node_scoped() -- fwnode_for_each_available_child_node_scoped() - -These macros follow the same pattern as existing scoped iterators in the -kernel, ensuring fwnode references are automatically released when the -iterator variable goes out of scope. This prevents resource leaks and -eliminates the need for manual cleanup in error paths. - -The implementation mirrors the non-scoped variants but uses -__free(fwnode_handle) for automatic resource management, providing a -safer and more convenient interface for drivers iterating over firmware -node children. - -Signed-off-by: Jean-François Lessard ---- - include/linux/property.h | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/include/linux/property.h b/include/linux/property.h -index 82f0cb3ab..862e20813 100644 ---- a/include/linux/property.h -+++ b/include/linux/property.h -@@ -176,6 +176,16 @@ struct fwnode_handle *fwnode_get_next_available_child_node( - for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ - child = fwnode_get_next_available_child_node(fwnode, child)) - -+#define fwnode_for_each_child_node_scoped(fwnode, child) \ -+ for (struct fwnode_handle *child __free(fwnode_handle) = \ -+ fwnode_get_next_child_node(fwnode, NULL); \ -+ child; child = fwnode_get_next_child_node(fwnode, child)) -+ -+#define fwnode_for_each_available_child_node_scoped(fwnode, child) \ -+ for (struct fwnode_handle *child __free(fwnode_handle) = \ -+ fwnode_get_next_available_child_node(fwnode, NULL); \ -+ child; child = fwnode_get_next_available_child_node(fwnode, child)) -+ - struct fwnode_handle *device_get_next_child_node(const struct device *dev, - struct fwnode_handle *child); - --- -2.43.0 - - -From 57483ceb601c6e5ae5e29b915b71ef6e546cb256 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= -Date: Mon, 1 Sep 2025 12:18:40 -0400 -Subject: [PATCH 02/14] i2c: core: Use fwnode_for_each_child_node_scoped() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Replace the manual __free(fwnode_handle) iterator declaration with the -new scoped iterator macro for cleaner, less error-prone code. - -This eliminates the need for explicit iterator variable declaration with -the cleanup attribute, making the code more consistent with other scoped -iterator usage patterns in the kernel. - -Reviewed-by: Andy Shevchenko -Signed-off-by: Jean-François Lessard ---- - drivers/i2c/i2c-core-slave.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/i2c/i2c-core-slave.c b/drivers/i2c/i2c-core-slave.c -index 7ee6b992b..02ca55c22 100644 ---- a/drivers/i2c/i2c-core-slave.c -+++ b/drivers/i2c/i2c-core-slave.c -@@ -112,10 +112,9 @@ bool i2c_detect_slave_mode(struct device *dev) - struct fwnode_handle *fwnode = dev_fwnode(dev); - - if (is_of_node(fwnode)) { -- struct fwnode_handle *child __free(fwnode_handle) = NULL; - u32 reg; - -- fwnode_for_each_child_node(fwnode, child) { -+ fwnode_for_each_child_node_scoped(fwnode, child) { - fwnode_property_read_u32(child, "reg", ®); - if (reg & I2C_OWN_SLAVE_ADDRESS) - return true; --- -2.43.0 - - -From 912e1aadb342a09838069e81dfeee8d9fa15ae68 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sun, 31 Aug 2025 00:23:51 -0400 -Subject: [PATCH 03/14] docs: ABI: auxdisplay: document linedisp library sysfs - attributes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: docs: ABI: auxdisplay: document linedisp library sysfs attributes Add ABI documentation for sysfs attributes provided by the line-display auxdisplay library module. These attributes enable text message display and @@ -114,15 +15,14 @@ The line-display library is used by multiple auxdisplay drivers and can expose these attributes either on linedisp.N child devices or directly on parent auxdisplay devices. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - .../ABI/testing/sysfs-auxdisplay-linedisp | 79 +++++++++++++++++++ + Documentation/ABI/testing/sysfs-auxdisplay-linedisp | 79 ++++++++++ 1 file changed, 79 insertions(+) - create mode 100644 Documentation/ABI/testing/sysfs-auxdisplay-linedisp diff --git a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp new file mode 100644 -index 000000000..45cf4e5a2 +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp @@ -0,0 +1,79 @@ @@ -206,17 +106,13 @@ index 000000000..45cf4e5a2 + Reference interface guidance: + - include/uapi/linux/map_to_14segment.h -- -2.43.0 +Armbian - -From aa2b721fbe8e792d71bba2a682278e217254a9d8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 30 Aug 2025 20:31:38 -0400 -Subject: [PATCH 04/14] auxdisplay: linedisp: encapsulate container_of usage - within to_linedisp -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: linedisp: encapsulate container_of usage within + to_linedisp Replace direct container_of() calls with a to_linedisp() helper function throughout the line-display auxdisplay library module. This abstraction @@ -226,13 +122,13 @@ auxdisplay devices. No functional changes in this patch. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - drivers/auxdisplay/line-display.c | 21 +++++++++++++-------- + drivers/auxdisplay/line-display.c | 21 ++++++---- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c -index 8590a4cd2..e44341b1e 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -31,6 +31,11 @@ @@ -320,17 +216,13 @@ index 8590a4cd2..e44341b1e 100644 kfree(linedisp->map); kfree(linedisp->message); -- -2.43.0 +Armbian - -From c7437adc19417a882214c1f6ea4c767fcc31ad64 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sun, 31 Aug 2025 13:53:01 -0400 -Subject: [PATCH 05/14] auxdisplay: linedisp: display static message when - length <= display size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: linedisp: display static message when length <= display + size Currently, when a message shorter than the display size is written, the content wraps around (e.g., "123" on a 4-digit display shows "1231") @@ -345,13 +237,13 @@ The scroll logic is also consolidated into a helper function for clarity. No API changes are introduced. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - drivers/auxdisplay/line-display.c | 30 +++++++++++++++++++++--------- + drivers/auxdisplay/line-display.c | 30 +++++++--- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c -index e44341b1e..73e4e77ea 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -36,6 +36,11 @@ static struct linedisp *to_linedisp(struct device *dev) @@ -414,16 +306,12 @@ index e44341b1e..73e4e77ea 100644 return count; } -- -2.43.0 +Armbian - -From fdf710de2bd90ed1477d9d04adbb645c6b9c8967 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 30 Aug 2025 20:35:34 -0400 -Subject: [PATCH 06/14] auxdisplay: linedisp: add num_chars sysfs attribute -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: linedisp: add num_chars sysfs attribute Add a read-only 'num_chars' sysfs attribute to report display digit count. @@ -433,14 +321,14 @@ messages, complementing the existing message and scroll controls. No functional changes to existing behavior. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - Documentation/ABI/testing/sysfs-auxdisplay-linedisp | 11 +++++++++++ - drivers/auxdisplay/line-display.c | 11 +++++++++++ + Documentation/ABI/testing/sysfs-auxdisplay-linedisp | 11 ++++++++++ + drivers/auxdisplay/line-display.c | 11 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp -index 45cf4e5a2..55f1b559e 100644 +index 111111111111..222222222222 100644 --- a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp +++ b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp @@ -15,6 +15,17 @@ Description: @@ -462,7 +350,7 @@ index 45cf4e5a2..55f1b559e 100644 Date: October 2021 KernelVersion: 5.16 diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c -index 73e4e77ea..7f3e53e28 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -178,6 +178,16 @@ static ssize_t message_store(struct device *dev, struct device_attribute *attr, @@ -491,17 +379,13 @@ index 73e4e77ea..7f3e53e28 100644 &dev_attr_map_seg7.attr, &dev_attr_map_seg14.attr, -- -2.43.0 +Armbian - -From 17407e87994e910b25d13151b9e5b82e6b5896ea Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 30 Aug 2025 20:41:39 -0400 -Subject: [PATCH 07/14] auxdisplay: linedisp: support attribute attachment to - auxdisplay devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: linedisp: support attribute attachment to auxdisplay + devices Enable linedisp library integration into existing kernel devices (like LED class) to provide a uniform 7-segment userspace API without creating @@ -520,14 +404,14 @@ Existing consumers of linedisp_register() are unaffected. The new API enables drivers like TM16XX to integrate 7-segment display functionality seamlessly within their LED class device hierarchy. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - drivers/auxdisplay/line-display.c | 180 +++++++++++++++++++++++++++++- + drivers/auxdisplay/line-display.c | 180 +++++++++- drivers/auxdisplay/line-display.h | 4 + 2 files changed, 178 insertions(+), 6 deletions(-) diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c -index 7f3e53e28..4e22373fc 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -6,20 +6,23 @@ @@ -777,7 +661,7 @@ index 7f3e53e28..4e22373fc 100644 put_device(&linedisp->dev); } diff --git a/drivers/auxdisplay/line-display.h b/drivers/auxdisplay/line-display.h -index 4348d7a2f..36853b639 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/line-display.h +++ b/drivers/auxdisplay/line-display.h @@ -6,6 +6,7 @@ @@ -799,17 +683,13 @@ index 4348d7a2f..36853b639 100644 unsigned int num_chars, const struct linedisp_ops *ops); void linedisp_unregister(struct linedisp *linedisp); -- -2.43.0 +Armbian - -From 6ab5f7cfaa821b995228b7e85e792f304f01865c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 16 Aug 2025 16:17:06 -0400 -Subject: [PATCH 08/14] dt-bindings: vendor-prefixes: Add fdhisi, titanmec, - princeton, winrise, wxicore -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: dt-bindings: vendor-prefixes: Add fdhisi, titanmec, princeton, + winrise, wxicore Add vendor prefixes of chip manufacturers supported by the TM16xx 7-segment LED matrix display controllers driver: @@ -825,20 +705,20 @@ either lack active .com domains or their .com domains are occupied by unrelated businesses. The fdhisi and titanmec prefixes were originally identified by -Andreas Färber. +Andreas Farber. -CC: Andreas Färber +CC: Andreas Farber Acked-by: Conor Dooley -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml -index 9ec8947df..cd42bf7a9 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml -@@ -542,6 +542,8 @@ patternProperties: +@@ -562,6 +562,8 @@ patternProperties: description: Fastrax Oy "^fcs,.*": description: Fairchild Semiconductor @@ -847,7 +727,7 @@ index 9ec8947df..cd42bf7a9 100644 "^feixin,.*": description: Shenzhen Feixin Photoelectic Co., Ltd "^feiyang,.*": -@@ -1235,6 +1237,8 @@ patternProperties: +@@ -1279,6 +1281,8 @@ patternProperties: description: Prime View International (PVI) "^primux,.*": description: Primux Trading, S.L. @@ -856,7 +736,7 @@ index 9ec8947df..cd42bf7a9 100644 "^probox2,.*": description: PROBOX2 (by W2COMP Co., Ltd.) "^pri,.*": -@@ -1569,6 +1573,8 @@ patternProperties: +@@ -1632,6 +1636,8 @@ patternProperties: description: Texas Instruments "^tianma,.*": description: Tianma Micro-electronics Co., Ltd. @@ -865,7 +745,7 @@ index 9ec8947df..cd42bf7a9 100644 "^tlm,.*": description: Trusted Logic Mobility "^tmt,.*": -@@ -1726,6 +1732,8 @@ patternProperties: +@@ -1791,6 +1797,8 @@ patternProperties: description: Wingtech Technology Co., Ltd. "^winlink,.*": description: WinLink Co., Ltd @@ -874,7 +754,7 @@ index 9ec8947df..cd42bf7a9 100644 "^winsen,.*": description: Winsen Corp. "^winstar,.*": -@@ -1742,6 +1750,8 @@ patternProperties: +@@ -1807,6 +1815,8 @@ patternProperties: description: Wobo "^wolfvision,.*": description: WolfVision GmbH @@ -884,17 +764,12 @@ index 9ec8947df..cd42bf7a9 100644 description: X-Powers "^xen,.*": -- -2.43.0 +Armbian - -From d10c4994c9d219df8e6917837c17b9a1f061412a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Mon, 1 Sep 2025 11:57:15 -0400 -Subject: [PATCH 09/14] dt-bindings: leds: add default-brightness property to - common.yaml -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: dt-bindings: leds: add default-brightness property to common.yaml Add default-brightness property to leds/common.yaml to establish a single canonical definition for LED brightness initialization. @@ -903,13 +778,13 @@ The property is currently defined locally in leds/leds-pwm.yaml and is needed by auxdisplay/titanmec,tm16xx.yaml. Properties should be defined in only one location to avoid type inconsistencies across bindings. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- Documentation/devicetree/bindings/leds/common.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml -index 3e8319e44..96bd7fd0f 100644 +index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/leds/common.yaml +++ b/Documentation/devicetree/bindings/leds/common.yaml @@ -173,6 +173,12 @@ properties: @@ -926,31 +801,24 @@ index 3e8319e44..96bd7fd0f 100644 description: This property specifies that the LED should be used, if at all possible, -- -2.43.0 +Armbian - -From 81cada2f3d9c8464fb851ba86b2384e654120860 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Mon, 1 Sep 2025 12:03:37 -0400 -Subject: [PATCH 10/14] dt-bindings: auxdisplay: add Titan Micro Electronics - TM16xx -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: dt-bindings: auxdisplay: add Titan Micro Electronics TM16xx Add documentation for TM16xx-compatible 7-segment LED display controllers with keyscan. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - .../bindings/auxdisplay/titanmec,tm16xx.yaml | 463 ++++++++++++++++++ - MAINTAINERS | 5 + - 2 files changed, 468 insertions(+) - create mode 100644 Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml + Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml | 463 ++++++++++ + 1 file changed, 463 insertions(+) diff --git a/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml new file mode 100644 -index 000000000..d324023bb +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml @@ -0,0 +1,463 @@ @@ -1417,34 +1285,14 @@ index 000000000..d324023bb + }; + }; + }; -diff --git a/MAINTAINERS b/MAINTAINERS -index f6206963e..9449dfc43 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -25441,6 +25441,11 @@ W: http://sourceforge.net/projects/tlan/ - F: Documentation/networking/device_drivers/ethernet/ti/tlan.rst - F: drivers/net/ethernet/ti/tlan.* - -+TM16XX-COMPATIBLE LED CONTROLLERS DISPLAY DRIVER -+M: Jean-François Lessard -+S: Maintained -+F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml -+ - TMIO/SDHI MMC DRIVER - M: Wolfram Sang - L: linux-mmc@vger.kernel.org -- -2.43.0 +Armbian - -From 176ec8dadd8b0e63dbafeb87b646706ad6f7c9f7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 16 Aug 2025 20:52:21 -0400 -Subject: [PATCH 11/14] auxdisplay: Add TM16xx 7-segment LED matrix display - controllers driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: Add TM16xx 7-segment LED matrix display controllers + driver Add driver for TM16xx family LED controllers and compatible chips from multiple vendors including Titan Micro, Fuda Hisi, i-Core, Princeton, and @@ -1461,34 +1309,16 @@ Tested-by: Boris Gjenero # Tested on X92 Tested-by: Paolo Sabatino # Tested on H96 Max (XY_RK3328) Tested-by: Christian Hewitt # Tested on X96 Max, Tanix TX3 Mini Tested-by: Martin Blumenstingl # Tested on Tanix TX3 Mini -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - MAINTAINERS | 3 + drivers/auxdisplay/Kconfig | 9 + drivers/auxdisplay/Makefile | 2 + - drivers/auxdisplay/tm16xx.h | 172 ++++++++++++ - drivers/auxdisplay/tm16xx_core.c | 459 +++++++++++++++++++++++++++++++ - 5 files changed, 645 insertions(+) - create mode 100644 drivers/auxdisplay/tm16xx.h - create mode 100644 drivers/auxdisplay/tm16xx_core.c + drivers/auxdisplay/tm16xx.h | 172 ++++ + drivers/auxdisplay/tm16xx_core.c | 459 ++++++++++ + 4 files changed, 642 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index 9449dfc43..7d5912f2d 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -25444,7 +25444,10 @@ F: drivers/net/ethernet/ti/tlan.* - TM16XX-COMPATIBLE LED CONTROLLERS DISPLAY DRIVER - M: Jean-François Lessard - S: Maintained -+F: Documentation/ABI/testing/sysfs-class-leds-tm16xx - F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml -+F: drivers/auxdisplay/tm16xx.h -+F: drivers/auxdisplay/tm16xx_core.c - - TMIO/SDHI MMC DRIVER - M: Wolfram Sang diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig -index bedc6133f..7bacf1111 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -526,6 +526,15 @@ config SEG_LED_GPIO @@ -1508,7 +1338,7 @@ index bedc6133f..7bacf1111 100644 # Character LCD with non-conforming interface section # diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile -index f5c13ed1c..7ecf3cd4a 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -16,3 +16,5 @@ obj-$(CONFIG_LINEDISP) += line-display.o @@ -1519,7 +1349,7 @@ index f5c13ed1c..7ecf3cd4a 100644 +tm16xx-y += tm16xx_core.o diff --git a/drivers/auxdisplay/tm16xx.h b/drivers/auxdisplay/tm16xx.h new file mode 100644 -index 000000000..973b6ac19 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/auxdisplay/tm16xx.h @@ -0,0 +1,172 @@ @@ -1697,7 +1527,7 @@ index 000000000..973b6ac19 +#endif /* _TM16XX_H */ diff --git a/drivers/auxdisplay/tm16xx_core.c b/drivers/auxdisplay/tm16xx_core.c new file mode 100644 -index 000000000..e090c578f +index 000000000000..111111111111 --- /dev/null +++ b/drivers/auxdisplay/tm16xx_core.c @@ -0,0 +1,459 @@ @@ -2161,17 +1991,12 @@ index 000000000..e090c578f +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("LINEDISP"); -- -2.43.0 +Armbian - -From aee73102a0488439a90552d63a8e74ff081508a7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Fri, 29 Aug 2025 22:28:35 -0400 -Subject: [PATCH 12/14] auxdisplay: TM16xx: Add keypad support for scanning - matrix keys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: TM16xx: Add keypad support for scanning matrix keys Add support for keypad scanning on TM16xx-compatible auxiliary display controllers. It handles keypad initialization, scanning, and input @@ -2187,31 +2012,17 @@ Key features include: This code is separated from main core driver to improve maintainability and reviewability. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - MAINTAINERS | 1 + - drivers/auxdisplay/Kconfig | 9 ++ + drivers/auxdisplay/Kconfig | 9 + drivers/auxdisplay/Makefile | 1 + - drivers/auxdisplay/tm16xx.h | 25 ++++ + drivers/auxdisplay/tm16xx.h | 25 ++ drivers/auxdisplay/tm16xx_core.c | 4 + - drivers/auxdisplay/tm16xx_keypad.c | 196 +++++++++++++++++++++++++++++ - 6 files changed, 236 insertions(+) - create mode 100644 drivers/auxdisplay/tm16xx_keypad.c + drivers/auxdisplay/tm16xx_keypad.c | 196 ++++++++++ + 5 files changed, 235 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index 7d5912f2d..84f213590 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -25448,6 +25448,7 @@ F: Documentation/ABI/testing/sysfs-class-leds-tm16xx - F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml - F: drivers/auxdisplay/tm16xx.h - F: drivers/auxdisplay/tm16xx_core.c -+F: drivers/auxdisplay/tm16xx_keypad.c - - TMIO/SDHI MMC DRIVER - M: Wolfram Sang diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig -index 7bacf1111..f9a2c0641 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -528,13 +528,22 @@ config SEG_LED_GPIO @@ -2238,7 +2049,7 @@ index 7bacf1111..f9a2c0641 100644 # Character LCD with non-conforming interface section # diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile -index 7ecf3cd4a..a9b9c8ff0 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_PARPORT_PANEL) += panel.o @@ -2247,7 +2058,7 @@ index 7ecf3cd4a..a9b9c8ff0 100644 tm16xx-y += tm16xx_core.o +tm16xx-$(CONFIG_TM16XX_KEYPAD) += tm16xx_keypad.o diff --git a/drivers/auxdisplay/tm16xx.h b/drivers/auxdisplay/tm16xx.h -index 973b6ac19..c503c6136 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/tm16xx.h +++ b/drivers/auxdisplay/tm16xx.h @@ -103,6 +103,7 @@ @@ -2302,7 +2113,7 @@ index 973b6ac19..c503c6136 100644 + #endif /* _TM16XX_H */ diff --git a/drivers/auxdisplay/tm16xx_core.c b/drivers/auxdisplay/tm16xx_core.c -index e090c578f..1d474d980 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/tm16xx_core.c +++ b/drivers/auxdisplay/tm16xx_core.c @@ -408,6 +408,10 @@ int tm16xx_probe(struct tm16xx_display *display) @@ -2318,7 +2129,7 @@ index e090c578f..1d474d980 100644 unregister_leds: diff --git a/drivers/auxdisplay/tm16xx_keypad.c b/drivers/auxdisplay/tm16xx_keypad.c new file mode 100644 -index 000000000..daa6afaf7 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/auxdisplay/tm16xx_keypad.c @@ -0,0 +1,196 @@ @@ -2519,17 +2330,12 @@ index 000000000..daa6afaf7 + return 0; +} -- -2.43.0 +Armbian - -From b05e349eda575c66f8b522869fe79149f74db731 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 23 Aug 2025 21:26:59 -0400 -Subject: [PATCH 13/14] auxdisplay: TM16xx: Add support for I2C-based - controllers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: TM16xx: Add support for I2C-based controllers Add support for TM16xx-compatible auxiliary display controllers connected via the I2C bus. @@ -2543,29 +2349,15 @@ The implementation includes: This allows platforms using TM16xx or compatible controllers over I2C to be managed by the TM16xx driver infrastructure. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - MAINTAINERS | 1 + - drivers/auxdisplay/Kconfig | 16 ++ + drivers/auxdisplay/Kconfig | 16 + drivers/auxdisplay/Makefile | 1 + - drivers/auxdisplay/tm16xx_i2c.c | 332 ++++++++++++++++++++++++++++++++ - 4 files changed, 350 insertions(+) - create mode 100644 drivers/auxdisplay/tm16xx_i2c.c + drivers/auxdisplay/tm16xx_i2c.c | 332 ++++++++++ + 3 files changed, 349 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index 84f213590..8a8a53efe 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -25448,6 +25448,7 @@ F: Documentation/ABI/testing/sysfs-class-leds-tm16xx - F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml - F: drivers/auxdisplay/tm16xx.h - F: drivers/auxdisplay/tm16xx_core.c -+F: drivers/auxdisplay/tm16xx_i2c.c - F: drivers/auxdisplay/tm16xx_keypad.c - - TMIO/SDHI MMC DRIVER diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig -index f9a2c0641..d48c2f189 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -544,6 +544,22 @@ config TM16XX_KEYPAD @@ -2592,7 +2384,7 @@ index f9a2c0641..d48c2f189 100644 # Character LCD with non-conforming interface section # diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile -index a9b9c8ff0..ba7b310f5 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o @@ -2602,7 +2394,7 @@ index a9b9c8ff0..ba7b310f5 100644 +obj-$(CONFIG_TM16XX_I2C) += tm16xx_i2c.o diff --git a/drivers/auxdisplay/tm16xx_i2c.c b/drivers/auxdisplay/tm16xx_i2c.c new file mode 100644 -index 000000000..013beceda +index 000000000000..111111111111 --- /dev/null +++ b/drivers/auxdisplay/tm16xx_i2c.c @@ -0,0 +1,332 @@ @@ -2939,17 +2731,12 @@ index 000000000..013beceda +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("TM16XX"); -- -2.43.0 +Armbian - -From 03ae70c0f50277360166c8bb0bf75b0077c84057 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= Date: Sat, 23 Aug 2025 21:55:14 -0400 -Subject: [PATCH 14/14] auxdisplay: TM16xx: Add support for SPI-based - controllers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: auxdisplay: TM16xx: Add support for SPI-based controllers Add support for TM16xx-compatible auxiliary display controllers connected via the SPI bus. @@ -2963,29 +2750,15 @@ The implementation includes: This allows platforms using TM16xx or compatible controllers over SPI to be managed by the TM16xx driver infrastructure. -Signed-off-by: Jean-François Lessard +Signed-off-by: Jean-Francois Lessard --- - MAINTAINERS | 1 + - drivers/auxdisplay/Kconfig | 16 ++ + drivers/auxdisplay/Kconfig | 16 + drivers/auxdisplay/Makefile | 1 + - drivers/auxdisplay/tm16xx_spi.c | 397 ++++++++++++++++++++++++++++++++ - 4 files changed, 415 insertions(+) - create mode 100644 drivers/auxdisplay/tm16xx_spi.c + drivers/auxdisplay/tm16xx_spi.c | 397 ++++++++++ + 3 files changed, 414 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index 8a8a53efe..5d5e5f01e 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -25450,6 +25450,7 @@ F: drivers/auxdisplay/tm16xx.h - F: drivers/auxdisplay/tm16xx_core.c - F: drivers/auxdisplay/tm16xx_i2c.c - F: drivers/auxdisplay/tm16xx_keypad.c -+F: drivers/auxdisplay/tm16xx_spi.c - - TMIO/SDHI MMC DRIVER - M: Wolfram Sang diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig -index d48c2f189..61e5af8d0 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -560,6 +560,22 @@ config TM16XX_I2C @@ -3012,7 +2785,7 @@ index d48c2f189..61e5af8d0 100644 # Character LCD with non-conforming interface section # diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile -index ba7b310f5..2485a3a67 100644 +index 111111111111..222222222222 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_TM16XX) += tm16xx.o @@ -3022,7 +2795,7 @@ index ba7b310f5..2485a3a67 100644 +obj-$(CONFIG_TM16XX_SPI) += tm16xx_spi.o diff --git a/drivers/auxdisplay/tm16xx_spi.c b/drivers/auxdisplay/tm16xx_spi.c new file mode 100644 -index 000000000..b305301f9 +index 000000000000..111111111111 --- /dev/null +++ b/drivers/auxdisplay/tm16xx_spi.c @@ -0,0 +1,397 @@ @@ -3424,5 +3197,5 @@ index 000000000..b305301f9 +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("TM16XX"); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/general-drm-panel-add-yixian-yx0345-panel.patch b/patch/kernel/archive/rockchip64-6.18/general-drm-panel-add-yixian-yx0345-panel.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/general-drm-panel-add-yixian-yx0345-panel.patch rename to patch/kernel/archive/rockchip64-6.18/general-drm-panel-add-yixian-yx0345-panel.patch index 5e3d342b2..b53f507bb 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-drm-panel-add-yixian-yx0345-panel.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-drm-panel-add-yixian-yx0345-panel.patch @@ -13,7 +13,7 @@ diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig -@@ -1087,6 +1087,15 @@ config DRM_PANEL_WIDECHIPS_WS2401 +@@ -1147,6 +1147,15 @@ config DRM_PANEL_WIDECHIPS_WS2401 480x800 display controller used in panels such as Samsung LMS380KF01. This display is used in the Samsung Galaxy Ace 2 GT-I8160 (Codina). @@ -33,7 +33,7 @@ diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile -@@ -112,3 +112,4 @@ obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o +@@ -117,3 +117,4 @@ obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o obj-$(CONFIG_DRM_PANEL_VISIONOX_R66451) += panel-visionox-r66451.o obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/patch/kernel/archive/rockchip64-6.17/general-drm-rockchip-Set-dma-mask-to-64-bit.patch b/patch/kernel/archive/rockchip64-6.18/general-drm-rockchip-Set-dma-mask-to-64-bit.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-drm-rockchip-Set-dma-mask-to-64-bit.patch rename to patch/kernel/archive/rockchip64-6.18/general-drm-rockchip-Set-dma-mask-to-64-bit.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-fix-es8316-kernel-panic.patch b/patch/kernel/archive/rockchip64-6.18/general-fix-es8316-kernel-panic.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-fix-es8316-kernel-panic.patch rename to patch/kernel/archive/rockchip64-6.18/general-fix-es8316-kernel-panic.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-fix-mmc-signal-voltage-before-reboot.patch b/patch/kernel/archive/rockchip64-6.18/general-fix-mmc-signal-voltage-before-reboot.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/general-fix-mmc-signal-voltage-before-reboot.patch rename to patch/kernel/archive/rockchip64-6.18/general-fix-mmc-signal-voltage-before-reboot.patch index d31da8ff8..d940531be 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-fix-mmc-signal-voltage-before-reboot.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-fix-mmc-signal-voltage-before-reboot.patch @@ -26,7 +26,7 @@ diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 111111111111..222222222222 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c -@@ -1374,6 +1374,14 @@ void mmc_power_off(struct mmc_host *host) +@@ -1373,6 +1373,14 @@ void mmc_power_off(struct mmc_host *host) if (host->ios.power_mode == MMC_POWER_OFF) return; diff --git a/patch/kernel/archive/rockchip64-6.17/general-hdmi-clock-fixes.patch b/patch/kernel/archive/rockchip64-6.18/general-hdmi-clock-fixes.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/general-hdmi-clock-fixes.patch rename to patch/kernel/archive/rockchip64-6.18/general-hdmi-clock-fixes.patch index 6ce8df7b8..1d48b1864 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-hdmi-clock-fixes.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-hdmi-clock-fixes.patch @@ -110,7 +110,7 @@ diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/ index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -69,15 +69,15 @@ static const u16 csc_coeff_rgb_out_eitu709[3][4] = { +@@ -70,15 +70,15 @@ static const u16 csc_coeff_rgb_out_eitu709[3][4] = { }; static const u16 csc_coeff_rgb_in_eitu601[3][4] = { @@ -136,7 +136,7 @@ diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockc index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -178,6 +178,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { +@@ -177,6 +177,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { } }; @@ -183,7 +183,7 @@ index 111111111111..222222222222 100644 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ { -@@ -343,6 +383,8 @@ static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, +@@ -338,6 +378,8 @@ static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi, display); diff --git a/patch/kernel/archive/rockchip64-6.17/general-increase-spdif-dma-burst.patch b/patch/kernel/archive/rockchip64-6.18/general-increase-spdif-dma-burst.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-increase-spdif-dma-burst.patch rename to patch/kernel/archive/rockchip64-6.18/general-increase-spdif-dma-burst.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-increasing_DMA_block_memory_allocation_to_2048.patch b/patch/kernel/archive/rockchip64-6.18/general-increasing_DMA_block_memory_allocation_to_2048.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-increasing_DMA_block_memory_allocation_to_2048.patch rename to patch/kernel/archive/rockchip64-6.18/general-increasing_DMA_block_memory_allocation_to_2048.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-pl330-01-fix-periodic-transfers.patch b/patch/kernel/archive/rockchip64-6.18/general-pl330-01-fix-periodic-transfers.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-pl330-01-fix-periodic-transfers.patch rename to patch/kernel/archive/rockchip64-6.18/general-pl330-01-fix-periodic-transfers.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-pl330-02-add-support-for-interleaved-transfers.patch b/patch/kernel/archive/rockchip64-6.18/general-pl330-02-add-support-for-interleaved-transfers.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-pl330-02-add-support-for-interleaved-transfers.patch rename to patch/kernel/archive/rockchip64-6.18/general-pl330-02-add-support-for-interleaved-transfers.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-pl330-04-bigger-mcode-buffer.patch b/patch/kernel/archive/rockchip64-6.18/general-pl330-04-bigger-mcode-buffer.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-pl330-04-bigger-mcode-buffer.patch rename to patch/kernel/archive/rockchip64-6.18/general-pl330-04-bigger-mcode-buffer.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-pl330-05-fix-unbalanced-power-down.patch b/patch/kernel/archive/rockchip64-6.18/general-pl330-05-fix-unbalanced-power-down.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-pl330-05-fix-unbalanced-power-down.patch rename to patch/kernel/archive/rockchip64-6.18/general-pl330-05-fix-unbalanced-power-down.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-pl330-06-fix-buffer-underruns.patch b/patch/kernel/archive/rockchip64-6.18/general-pl330-06-fix-buffer-underruns.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-pl330-06-fix-buffer-underruns.patch rename to patch/kernel/archive/rockchip64-6.18/general-pl330-06-fix-buffer-underruns.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-possibility-of-disabling-rk808-rtc.patch b/patch/kernel/archive/rockchip64-6.18/general-possibility-of-disabling-rk808-rtc.patch similarity index 92% rename from patch/kernel/archive/rockchip64-6.17/general-possibility-of-disabling-rk808-rtc.patch rename to patch/kernel/archive/rockchip64-6.18/general-possibility-of-disabling-rk808-rtc.patch index f9291da84..234c19da8 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-possibility-of-disabling-rk808-rtc.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-possibility-of-disabling-rk808-rtc.patch @@ -25,7 +25,7 @@ diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 111111111111..222222222222 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c -@@ -208,7 +208,7 @@ static int mfd_add_device(struct device *parent, int id, +@@ -209,7 +209,7 @@ static int mfd_add_device(struct device *parent, int id, match: if (!pdev->dev.of_node) @@ -38,7 +38,7 @@ diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index 111111111111..222222222222 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c -@@ -133,6 +133,7 @@ static const struct mfd_cell rk818s[] = { +@@ -134,6 +134,7 @@ static const struct mfd_cell rk818s[] = { { .name = "rk808-regulator", }, { .name = "rk808-rtc", diff --git a/patch/kernel/archive/rockchip64-6.17/general-rk3328-dtsi-trb-ent-quirk.patch b/patch/kernel/archive/rockchip64-6.18/general-rk3328-dtsi-trb-ent-quirk.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/general-rk3328-dtsi-trb-ent-quirk.patch rename to patch/kernel/archive/rockchip64-6.18/general-rk3328-dtsi-trb-ent-quirk.patch index 2b93925d8..65d70367f 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-rk3328-dtsi-trb-ent-quirk.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-rk3328-dtsi-trb-ent-quirk.patch @@ -48,7 +48,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -1071,6 +1071,7 @@ usbdrd3: usb@ff600000 { +@@ -1105,6 +1105,7 @@ usbdrd3: usb@ff600000 { snps,dis-del-phy-power-chg-quirk; snps,dis_enblslpm_quirk; snps,dis-tx-ipgap-linecheck-quirk; diff --git a/patch/kernel/archive/rockchip64-6.17/general-rk808-configurable-switch-voltage-steps.patch b/patch/kernel/archive/rockchip64-6.18/general-rk808-configurable-switch-voltage-steps.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-rk808-configurable-switch-voltage-steps.patch rename to patch/kernel/archive/rockchip64-6.18/general-rk808-configurable-switch-voltage-steps.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-rockchip-overlays.patch b/patch/kernel/archive/rockchip64-6.18/general-rockchip-overlays.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-rockchip-overlays.patch rename to patch/kernel/archive/rockchip64-6.18/general-rockchip-overlays.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-rt5651-add-mclk.patch b/patch/kernel/archive/rockchip64-6.18/general-rt5651-add-mclk.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-rt5651-add-mclk.patch rename to patch/kernel/archive/rockchip64-6.18/general-rt5651-add-mclk.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-st7796-driver.patch b/patch/kernel/archive/rockchip64-6.18/general-st7796-driver.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-st7796-driver.patch rename to patch/kernel/archive/rockchip64-6.18/general-st7796-driver.patch diff --git a/patch/kernel/archive/rockchip64-6.17/general-v4l2-iep-driver.patch b/patch/kernel/archive/rockchip64-6.18/general-v4l2-iep-driver.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/general-v4l2-iep-driver.patch rename to patch/kernel/archive/rockchip64-6.18/general-v4l2-iep-driver.patch index 4924c90b6..fd29ac829 100644 --- a/patch/kernel/archive/rockchip64-6.17/general-v4l2-iep-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/general-v4l2-iep-driver.patch @@ -186,7 +186,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -751,6 +751,28 @@ vop_mmu: iommu@ff373f00 { +@@ -785,6 +785,28 @@ vop_mmu: iommu@ff373f00 { status = "disabled"; }; @@ -246,7 +246,7 @@ index 111111111111..222222222222 100644 status = "disabled"; }; diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig -index 9bbeec4996aa..9fcf52f864b4 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/Kconfig +++ b/drivers/media/platform/rockchip/Kconfig @@ -5,3 +5,4 @@ comment "Rockchip media platform drivers" @@ -255,7 +255,7 @@ index 9bbeec4996aa..9fcf52f864b4 100644 source "drivers/media/platform/rockchip/rkvdec/Kconfig" +source "drivers/media/platform/rockchip/iep/Kconfig" diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile -index 286dc5c53f7e..85293a5fec41 100644 +index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/Makefile +++ b/drivers/media/platform/rockchip/Makefile @@ -2,3 +2,4 @@ diff --git a/patch/kernel/archive/rockchip64-6.17/general-workaround-broadcom-bt-serdev.patch b/patch/kernel/archive/rockchip64-6.18/general-workaround-broadcom-bt-serdev.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/general-workaround-broadcom-bt-serdev.patch rename to patch/kernel/archive/rockchip64-6.18/general-workaround-broadcom-bt-serdev.patch diff --git a/patch/kernel/archive/rockchip64-6.17/kernel-6.8-tools-cgroup-makefile.patch b/patch/kernel/archive/rockchip64-6.18/kernel-6.8-tools-cgroup-makefile.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/kernel-6.8-tools-cgroup-makefile.patch rename to patch/kernel/archive/rockchip64-6.18/kernel-6.8-tools-cgroup-makefile.patch diff --git a/patch/kernel/archive/rockchip64-6.17/media-0001-Add-rkvdec-Support-v5.patch b/patch/kernel/archive/rockchip64-6.18/media-0001-Add-rkvdec-Support-v5.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/media-0001-Add-rkvdec-Support-v5.patch rename to patch/kernel/archive/rockchip64-6.18/media-0001-Add-rkvdec-Support-v5.patch index fe568a9c1..fe6f0a79e 100644 --- a/patch/kernel/archive/rockchip64-6.17/media-0001-Add-rkvdec-Support-v5.patch +++ b/patch/kernel/archive/rockchip64-6.18/media-0001-Add-rkvdec-Support-v5.patch @@ -2891,7 +2891,7 @@ index 111111111111..222222222222 100644 } }; -@@ -1187,8 +1191,17 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1185,8 +1189,17 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } @@ -2910,7 +2910,7 @@ index 111111111111..222222222222 100644 { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); -@@ -1199,16 +1212,22 @@ static const char * const rkvdec_clk_names[] = { +@@ -1197,16 +1210,22 @@ static const char * const rkvdec_clk_names[] = { static int rkvdec_probe(struct platform_device *pdev) { @@ -3050,7 +3050,7 @@ index 111111111111..222222222222 100644 struct v4l2_frmsizeenum *fsize) { - const struct rkvdec_coded_fmt_desc *fmt; -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); ++ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file); + const struct rkvdec_coded_fmt_desc *desc; if (fsize->index != 0) @@ -3074,7 +3074,7 @@ index 111111111111..222222222222 100644 return 0; @@ -470,10 +494,10 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv, - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); + struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file); const struct rkvdec_coded_fmt_desc *desc; - desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat); @@ -3101,7 +3101,7 @@ index 111111111111..222222222222 100644 struct v4l2_fmtdesc *f) { - if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts)) -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); ++ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file); + const struct rkvdec_coded_fmt_desc *desc; + + desc = rkvdec_enum_coded_fmt_desc(ctx, f->index); @@ -3113,7 +3113,7 @@ index 111111111111..222222222222 100644 return 0; } -@@ -970,14 +998,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) +@@ -969,14 +997,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) int ret; for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) @@ -3157,7 +3157,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -@@ -1222,6 +1222,10 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1220,6 +1220,10 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } @@ -3168,7 +3168,7 @@ index 111111111111..222222222222 100644 static const struct rkvdec_variant rk3399_rkvdec_variant = { .capabilities = RKVDEC_CAPABILITY_HEVC | RKVDEC_CAPABILITY_H264 | -@@ -1229,6 +1233,10 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { +@@ -1227,6 +1231,10 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { }; static const struct of_device_id of_rkvdec_match[] = { @@ -3261,7 +3261,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -@@ -1226,6 +1226,13 @@ static const struct rkvdec_variant rk3288_rkvdec_variant = { +@@ -1224,6 +1224,13 @@ static const struct rkvdec_variant rk3288_rkvdec_variant = { .capabilities = RKVDEC_CAPABILITY_HEVC, }; @@ -3275,7 +3275,7 @@ index 111111111111..222222222222 100644 static const struct rkvdec_variant rk3399_rkvdec_variant = { .capabilities = RKVDEC_CAPABILITY_HEVC | RKVDEC_CAPABILITY_H264 | -@@ -1237,6 +1244,10 @@ static const struct of_device_id of_rkvdec_match[] = { +@@ -1235,6 +1242,10 @@ static const struct of_device_id of_rkvdec_match[] = { .compatible = "rockchip,rk3288-vdec", .data = &rk3288_rkvdec_variant, }, @@ -3286,7 +3286,7 @@ index 111111111111..222222222222 100644 { .compatible = "rockchip,rk3399-vdec", .data = &rk3399_rkvdec_variant, -@@ -1267,6 +1278,7 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1265,6 +1276,7 @@ static int rkvdec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rkvdec); rkvdec->dev = &pdev->dev; rkvdec->capabilities = variant->capabilities; @@ -3350,8 +3350,8 @@ index 111111111111..222222222222 100644 oneOf: + - const: rockchip,rk3288-vdec - const: rockchip,rk3399-vdec - - items: - - enum: + - const: rockchip,rk3576-vdec + - const: rockchip,rk3588-vdec -- Armbian @@ -3420,8 +3420,8 @@ Add controls to provide it as the raw data form the stream. Signed-off-by: Detlev Casanova --- Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst | 114 ++++++++++ + Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions | 2 + Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst | 12 + - Documentation/userspace-api/media/videodev2.h.rst.exceptions | 2 + 3 files changed, 128 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -3549,6 +3549,19 @@ index 111111111111..222222222222 100644 .. _v4l2-codec-stateless-av1: ``V4L2_CID_STATELESS_AV1_SEQUENCE (struct)`` +diff --git a/Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions +index 111111111111..222222222222 100644 +--- a/Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions ++++ b/Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions +@@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type` ++replace symbol V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS :c:type:`v4l2_ctrl_type` ++replace symbol V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_RECT :c:type:`v4l2_ctrl_type` + replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type` diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 111111111111..222222222222 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -3572,19 +3585,6 @@ index 111111111111..222222222222 100644 * - ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR`` - n/a - n/a -diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions -index 111111111111..222222222222 100644 ---- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions -+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions -@@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type` -+replace symbol V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS :c:type:`v4l2_ctrl_type` -+replace symbol V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_RECT :c:type:`v4l2_ctrl_type` - replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type` -- Armbian @@ -3643,7 +3643,7 @@ index 111111111111..222222222222 100644 case V4L2_CTRL_TYPE_HDR10_CLL_INFO: break; -@@ -1921,6 +1933,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, +@@ -1925,6 +1937,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); break; @@ -3688,7 +3688,7 @@ diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-contro index 111111111111..222222222222 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h -@@ -2088,6 +2088,8 @@ struct v4l2_ctrl_mpeg2_quantisation { +@@ -2093,6 +2093,8 @@ struct v4l2_ctrl_mpeg2_quantisation { #define V4L2_CID_STATELESS_HEVC_DECODE_MODE (V4L2_CID_CODEC_STATELESS_BASE + 405) #define V4L2_CID_STATELESS_HEVC_START_CODE (V4L2_CID_CODEC_STATELESS_BASE + 406) #define V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS (V4L2_CID_CODEC_STATELESS_BASE + 407) @@ -3697,9 +3697,9 @@ index 111111111111..222222222222 100644 enum v4l2_stateless_hevc_decode_mode { V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED, -@@ -2543,6 +2545,65 @@ struct v4l2_ctrl_hevc_scaling_matrix { - __u8 scaling_list_dc_coef_32x32[2]; - }; +@@ -3480,6 +3482,65 @@ struct v4l2_ctrl_av1_film_grain { + #define V4L2_CID_MPEG_MFC51_BASE V4L2_CID_CODEC_MFC51_BASE + #endif +#define V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED 0x1 + @@ -3767,7 +3767,7 @@ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 111111111111..222222222222 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -1974,6 +1974,8 @@ enum v4l2_ctrl_type { +@@ -1981,6 +1981,8 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272, V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273, V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274, @@ -3798,7 +3798,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1252,6 +1252,70 @@ vepu121_3_mmu: iommu@fdbac800 { +@@ -1353,6 +1353,70 @@ vepu121_3_mmu: iommu@fdbac800 { #iommu-cells = <0>; }; @@ -3869,7 +3869,7 @@ index 111111111111..222222222222 100644 av1d: video-codec@fdc70000 { compatible = "rockchip,rk3588-av1-vpu"; reg = <0x0 0xfdc70000 0x0 0x800>; -@@ -3093,6 +3157,16 @@ system_sram2: sram@ff001000 { +@@ -3248,6 +3312,16 @@ system_sram2: sram@ff001000 { ranges = <0x0 0x0 0xff001000 0xef000>; #address-cells = <1>; #size-cells = <1>; @@ -3907,7 +3907,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi -@@ -1139,6 +1139,41 @@ gpu: gpu@27800000 { +@@ -1289,6 +1289,41 @@ gpu: gpu@27800000 { status = "disabled"; }; @@ -3949,7 +3949,7 @@ index 111111111111..222222222222 100644 vop: vop@27d00000 { compatible = "rockchip,rk3576-vop"; reg = <0x0 0x27d00000 0x0 0x3000>, <0x0 0x27d05000 0x0 0x1000>; -@@ -2409,6 +2444,7 @@ sram: sram@3ff88000 { +@@ -2694,6 +2729,7 @@ sram: sram@3ff88000 { /* start address and size should be 4k align */ rkvdec_sram: rkvdec-sram@0 { reg = <0x0 0x78000>; @@ -3960,110 +3960,6 @@ index 111111111111..222222222222 100644 -- Armbian -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nicolas Frattaroli -Date: Mon, 23 Jun 2025 18:05:29 +0200 -Subject: bitmap: introduce hardware-specific bitfield operations - -Hardware of various vendors, but very notably Rockchip, often uses -32-bit registers where the upper 16-bit half of the register is a -write-enable mask for the lower half. - -This type of hardware setup allows for more granular concurrent register -write access. - -Over the years, many drivers have hand-rolled their own version of this -macro, usually without any checks, often called something like -HIWORD_UPDATE or FIELD_PREP_HIWORD, commonly with slightly different -semantics between them. - -Clearly there is a demand for such a macro, and thus the demand should -be satisfied in a common header file. As this is a convention that spans -across multiple vendors, and similar conventions may also have -cross-vendor adoption, it's best if it lives in a vendor-agnostic header -file that can be expanded over time. - -Add hw_bitfield.h with two macros: FIELD_PREP_WM16, and -FIELD_PREP_WM16_CONST. The latter is a version that can be used in -initializers, like FIELD_PREP_CONST. - -Suggested-by: -Signed-off-by: Nicolas Frattaroli ---- - include/linux/hw_bitfield.h | 62 ++++++++++ - 1 file changed, 62 insertions(+) - -diff --git a/include/linux/hw_bitfield.h b/include/linux/hw_bitfield.h -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/include/linux/hw_bitfield.h -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) 2025, Collabora Ltd. -+ */ -+ -+#ifndef _LINUX_HW_BITFIELD_H -+#define _LINUX_HW_BITFIELD_H -+ -+#include -+#include -+#include -+ -+/** -+ * FIELD_PREP_WM16() - prepare a bitfield element with a mask in the upper half -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP_WM16() masks and shifts up the value, as well as bitwise ORs the -+ * result with the mask shifted up by 16. -+ * -+ * This is useful for a common design of hardware registers where the upper -+ * 16-bit half of a 32-bit register is used as a write-enable mask. In such a -+ * register, a bit in the lower half is only updated if the corresponding bit -+ * in the upper half is high. -+ */ -+#define FIELD_PREP_WM16(_mask, _val) \ -+ ({ \ -+ typeof(_val) __val = _val; \ -+ typeof(_mask) __mask = _mask; \ -+ __BF_FIELD_CHECK(__mask, ((u16)0U), __val, \ -+ "HWORD_UPDATE: "); \ -+ (((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) | \ -+ ((__mask) << 16); \ -+ }) -+ -+/** -+ * FIELD_PREP_WM16_CONST() - prepare a constant bitfield element with a mask in -+ * the upper half -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP_WM16_CONST() masks and shifts up the value, as well as bitwise ORs -+ * the result with the mask shifted up by 16. -+ * -+ * This is useful for a common design of hardware registers where the upper -+ * 16-bit half of a 32-bit register is used as a write-enable mask. In such a -+ * register, a bit in the lower half is only updated if the corresponding bit -+ * in the upper half is high. -+ * -+ * Unlike FIELD_PREP_WM16(), this is a constant expression and can therefore -+ * be used in initializers. Error checking is less comfortable for this -+ * version. -+ */ -+#define FIELD_PREP_WM16_CONST(_mask, _val) \ -+ ( \ -+ FIELD_PREP_CONST(_mask, _val) | \ -+ (BUILD_BUG_ON_ZERO(const_true((u64)(_mask) > U16_MAX)) + \ -+ ((_mask) << 16)) \ -+ ) -+ -+ -+#endif /* _LINUX_HW_BITFIELD_H */ --- -Armbian - From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Thu, 26 Jun 2025 08:53:07 -0400 @@ -4081,7 +3977,7 @@ diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/brid index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -@@ -276,8 +276,7 @@ static unsigned int dw_hdmi_qp_find_n(struct dw_hdmi_qp *hdmi, unsigned long pix +@@ -277,8 +277,7 @@ static unsigned int dw_hdmi_qp_find_n(struct dw_hdmi_qp *hdmi, unsigned long pix if (n > 0) return n; @@ -5495,7 +5391,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -@@ -903,6 +903,15 @@ void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) +@@ -902,6 +902,15 @@ void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl); } @@ -5511,7 +5407,7 @@ index 111111111111..222222222222 100644 static void rkvdec_device_run(void *priv) { struct rkvdec_ctx *ctx = priv; -@@ -1217,7 +1226,6 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1215,7 +1224,6 @@ static void rkvdec_watchdog_func(struct work_struct *work) if (ctx) { dev_err(rkvdec->dev, "Frame processing timed out!\n"); writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT); @@ -8222,7 +8118,7 @@ index 111111111111..222222222222 100644 } return NULL; -@@ -1003,18 +1004,19 @@ static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx, +@@ -1002,18 +1003,19 @@ static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx, static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) { @@ -8248,7 +8144,7 @@ index 111111111111..222222222222 100644 if (ret) goto err_free_handler; } -@@ -1230,11 +1232,18 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1228,11 +1230,18 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } @@ -8267,7 +8163,7 @@ index 111111111111..222222222222 100644 .capabilities = RKVDEC_CAPABILITY_HEVC | RKVDEC_CAPABILITY_H264 | RKVDEC_CAPABILITY_VP9, -@@ -1242,6 +1251,7 @@ static const struct rkvdec_variant rk3328_rkvdec_variant = { +@@ -1240,6 +1249,7 @@ static const struct rkvdec_variant rk3328_rkvdec_variant = { }; static const struct rkvdec_variant rk3399_rkvdec_variant = { @@ -8275,7 +8171,7 @@ index 111111111111..222222222222 100644 .capabilities = RKVDEC_CAPABILITY_HEVC | RKVDEC_CAPABILITY_H264 | RKVDEC_CAPABILITY_VP9, -@@ -1285,6 +1295,7 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1283,6 +1293,7 @@ static int rkvdec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rkvdec); rkvdec->dev = &pdev->dev; @@ -8636,7 +8532,7 @@ index 111111111111..222222222222 100644 } rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR); -@@ -1324,8 +1338,6 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1322,8 +1336,6 @@ static int rkvdec_probe(struct platform_device *pdev) return ret; } @@ -8645,7 +8541,7 @@ index 111111111111..222222222222 100644 irq = platform_get_irq(pdev, 0); if (irq <= 0) return -ENXIO; -@@ -1345,6 +1345,10 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1336,6 +1348,10 @@ static int rkvdec_probe(struct platform_device *pdev) return ret; } @@ -8656,7 +8552,7 @@ index 111111111111..222222222222 100644 pm_runtime_set_autosuspend_delay(&pdev->dev, 100); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); -@@ -1355,7 +1355,8 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1344,7 +1360,8 @@ static int rkvdec_probe(struct platform_device *pdev) if (ret) goto err_disable_runtime_pm; @@ -8666,7 +8562,7 @@ index 111111111111..222222222222 100644 rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev); if (IS_ERR(rkvdec->empty_domain)) { -@@ -1360,6 +1360,10 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1358,6 +1375,10 @@ static int rkvdec_probe(struct platform_device *pdev) err_disable_runtime_pm: pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -8723,8 +8619,8 @@ index 111111111111..222222222222 100644 void *priv; }; -@@ -150,10 +157,16 @@ static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh) - return container_of(fh, struct rkvdec_ctx, fh); +@@ -150,10 +157,16 @@ static inline struct rkvdec_ctx *file_to_rkvdec_ctx(struct file *filp) + return container_of(file_to_v4l2_fh(filp), struct rkvdec_ctx, fh); } +enum rkvdec_alloc_type { @@ -8761,7 +8657,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -@@ -1207,10 +1207,9 @@ static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec) +@@ -1205,10 +1205,9 @@ static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec) } } @@ -8774,7 +8670,7 @@ index 111111111111..222222222222 100644 enum vb2_buffer_state state; u32 status; -@@ -1231,6 +1230,15 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) +@@ -1229,6 +1228,15 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) return IRQ_HANDLED; } @@ -8790,7 +8686,7 @@ index 111111111111..222222222222 100644 static void rkvdec_watchdog_func(struct work_struct *work) { struct rkvdec_dev *rkvdec; -@@ -1249,6 +1257,7 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1247,6 +1255,7 @@ static void rkvdec_watchdog_func(struct work_struct *work) static const struct rkvdec_config config_rkvdec = { .coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts, .coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts), @@ -8833,7 +8729,7 @@ diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c -@@ -1297,15 +1297,10 @@ static const struct of_device_id of_rkvdec_match[] = { +@@ -1295,15 +1295,10 @@ static const struct of_device_id of_rkvdec_match[] = { }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); @@ -8849,7 +8745,7 @@ index 111111111111..222222222222 100644 int ret, irq; variant = of_device_get_match_data(&pdev->dev); -@@ -1324,19 +1319,12 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1322,19 +1317,12 @@ static int rkvdec_probe(struct platform_device *pdev) mutex_init(&rkvdec->vdev_lock); INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); @@ -9971,7 +9867,7 @@ index 111111111111..222222222222 100644 static bool rkvdec_is_capable(struct rkvdec_ctx *ctx, unsigned int capability) { return (ctx->dev->capabilities & capability) == capability; -@@ -1230,6 +1290,35 @@ static irqreturn_t rk3399_irq_handler(struct rkvdec_ctx *ctx) +@@ -1228,6 +1288,35 @@ static irqreturn_t rk3399_irq_handler(struct rkvdec_ctx *ctx) return IRQ_HANDLED; } @@ -10007,7 +9903,7 @@ index 111111111111..222222222222 100644 static irqreturn_t rkvdec_irq_handler(int irq, void *priv) { struct rkvdec_dev *rkvdec = priv; -@@ -1254,10 +1343,76 @@ static void rkvdec_watchdog_func(struct work_struct *work) +@@ -1252,10 +1341,76 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } @@ -10084,7 +9980,7 @@ index 111111111111..222222222222 100644 }; static const struct rkvdec_variant rk3288_rkvdec_variant = { -@@ -1280,6 +1435,11 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { +@@ -1278,6 +1433,11 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { RKVDEC_CAPABILITY_VP9, }; @@ -10096,7 +9992,7 @@ index 111111111111..222222222222 100644 static const struct of_device_id of_rkvdec_match[] = { { .compatible = "rockchip,rk3288-vdec", -@@ -1293,6 +1453,10 @@ static const struct of_device_id of_rkvdec_match[] = { +@@ -1291,6 +1451,10 @@ static const struct of_device_id of_rkvdec_match[] = { .compatible = "rockchip,rk3399-vdec", .data = &rk3399_rkvdec_variant, }, @@ -10107,7 +10003,7 @@ index 111111111111..222222222222 100644 { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); -@@ -1319,11 +1483,16 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1317,11 +1481,16 @@ static int rkvdec_probe(struct platform_device *pdev) mutex_init(&rkvdec->vdev_lock); INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); @@ -12510,7 +12406,7 @@ index 111111111111..222222222222 100644 }; static bool rkvdec_is_capable(struct rkvdec_ctx *ctx, unsigned int capability) -@@ -1319,6 +1420,35 @@ static irqreturn_t vdpu381_irq_handler(struct rkvdec_ctx *ctx) +@@ -1317,6 +1418,35 @@ static irqreturn_t vdpu381_irq_handler(struct rkvdec_ctx *ctx) return IRQ_HANDLED; } @@ -12546,7 +12442,7 @@ index 111111111111..222222222222 100644 static irqreturn_t rkvdec_irq_handler(int irq, void *priv) { struct rkvdec_dev *rkvdec = priv; -@@ -1391,6 +1521,7 @@ static const struct rkvdec_config config_rkvdec = { +@@ -1389,6 +1519,7 @@ static const struct rkvdec_config config_rkvdec = { .coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts), .irq_handler = rk3399_irq_handler, .fill_pixfmt_mp = v4l2_fill_pixfmt_mp, @@ -12554,7 +12450,7 @@ index 111111111111..222222222222 100644 }; static struct rcb_size_info vdpu381_rcb_sizes[] = { -@@ -1413,6 +1544,33 @@ static const struct rkvdec_config config_vdpu381 = { +@@ -1411,6 +1542,33 @@ static const struct rkvdec_config config_vdpu381 = { .rcb_num = ARRAY_SIZE(vdpu381_rcb_sizes), .irq_handler = vdpu381_irq_handler, .fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp, @@ -12588,7 +12484,7 @@ index 111111111111..222222222222 100644 }; static const struct rkvdec_variant rk3288_rkvdec_variant = { -@@ -1437,6 +1595,12 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { +@@ -1435,6 +1593,12 @@ static const struct rkvdec_variant rk3399_rkvdec_variant = { static const struct rkvdec_variant rk3588_vdpu381_variant = { .config = &config_vdpu381, @@ -12601,7 +12497,7 @@ index 111111111111..222222222222 100644 .capabilities = RKVDEC_CAPABILITY_H264, }; -@@ -1457,6 +1621,10 @@ static const struct of_device_id of_rkvdec_match[] = { +@@ -1455,6 +1619,10 @@ static const struct of_device_id of_rkvdec_match[] = { .compatible = "rockchip,rk3588-vdec", .data = &rk3588_vdpu381_variant, }, @@ -12612,7 +12508,7 @@ index 111111111111..222222222222 100644 { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match); -@@ -1494,9 +1662,19 @@ static int rkvdec_probe(struct platform_device *pdev) +@@ -1492,9 +1660,19 @@ static int rkvdec_probe(struct platform_device *pdev) rkvdec->clk_count = ret; rkvdec->axi_clk = devm_clk_get(&pdev->dev, "axi"); @@ -13492,7 +13388,7 @@ index 111111111111..222222222222 100644 }; static bool rkvdec_is_capable(struct rkvdec_ctx *ctx, unsigned int capability) -@@ -1458,6 +1474,78 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) +@@ -1456,6 +1472,78 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) return cfg->irq_handler(ctx); } @@ -13571,7 +13467,7 @@ index 111111111111..222222222222 100644 static void rkvdec_watchdog_func(struct work_struct *work) { struct rkvdec_dev *rkvdec; -@@ -1521,6 +1609,7 @@ static const struct rkvdec_config config_rkvdec = { +@@ -1519,6 +1607,7 @@ static const struct rkvdec_config config_rkvdec = { .coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts), .irq_handler = rk3399_irq_handler, .fill_pixfmt_mp = v4l2_fill_pixfmt_mp, @@ -13579,7 +13475,7 @@ index 111111111111..222222222222 100644 .colmv_size = rkvdec_colmv_size, }; -@@ -1545,6 +1634,7 @@ static const struct rkvdec_config config_vdpu381 = { +@@ -1543,6 +1632,7 @@ static const struct rkvdec_config config_vdpu381 = { .irq_handler = vdpu381_irq_handler, .fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp, .colmv_size = rkvdec_colmv_size, @@ -13587,7 +13483,7 @@ index 111111111111..222222222222 100644 .named_regs = true, }; -@@ -1570,6 +1660,7 @@ const struct rkvdec_config config_vdpu383 = { +@@ -1568,6 +1658,7 @@ const struct rkvdec_config config_vdpu383 = { .fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp, .colmv_size = rkvdec_vdpu383_colmv_size, .fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp, @@ -13595,7 +13491,7 @@ index 111111111111..222222222222 100644 .named_regs = true, }; -@@ -1601,7 +1692,8 @@ static const struct rkvdec_variant rk3588_vdpu381_variant = { +@@ -1599,7 +1690,8 @@ static const struct rkvdec_variant rk3588_vdpu381_variant = { static const struct rkvdec_variant rk3576_vdpu383_variant = { .config = &config_vdpu383, diff --git a/patch/kernel/archive/rockchip64-6.17/media-0002-media-rkvdec-remove-vb2_is_busy-check-in-rkvdec_s_ct.patch b/patch/kernel/archive/rockchip64-6.18/media-0002-media-rkvdec-remove-vb2_is_busy-check-in-rkvdec_s_ct.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/media-0002-media-rkvdec-remove-vb2_is_busy-check-in-rkvdec_s_ct.patch rename to patch/kernel/archive/rockchip64-6.18/media-0002-media-rkvdec-remove-vb2_is_busy-check-in-rkvdec_s_ct.patch diff --git a/patch/kernel/archive/rockchip64-6.17/media-0002-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch b/patch/kernel/archive/rockchip64-6.18/media-0002-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/media-0002-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch rename to patch/kernel/archive/rockchip64-6.18/media-0002-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch diff --git a/patch/kernel/archive/rockchip64-6.17/media-0003-rk3568-disable-hantro-h264.patch b/patch/kernel/archive/rockchip64-6.18/media-0003-rk3568-disable-hantro-h264.patch similarity index 94% rename from patch/kernel/archive/rockchip64-6.17/media-0003-rk3568-disable-hantro-h264.patch rename to patch/kernel/archive/rockchip64-6.18/media-0003-rk3568-disable-hantro-h264.patch index 5cd53cb8c..2e49355b9 100644 --- a/patch/kernel/archive/rockchip64-6.17/media-0003-rk3568-disable-hantro-h264.patch +++ b/patch/kernel/archive/rockchip64-6.18/media-0003-rk3568-disable-hantro-h264.patch @@ -20,7 +20,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1141,7 +1141,7 @@ power-domain@RK3588_PD_SDMMC { +@@ -1242,7 +1242,7 @@ rknn_mmu_2: iommu@fdad9000 { }; vpu121: video-codec@fdb50000 { @@ -33,7 +33,7 @@ diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/pla index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c -@@ -721,7 +721,6 @@ static const struct of_device_id of_hantro_match[] = { +@@ -718,7 +718,6 @@ static const struct of_device_id of_hantro_match[] = { { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, { .compatible = "rockchip,rk3568-vepu", .data = &rk3568_vepu_variant, }, @@ -57,7 +57,7 @@ diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c b/drivers/medi index 111111111111..222222222222 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c -@@ -740,10 +740,9 @@ const struct hantro_variant rk3288_vpu_variant = { +@@ -724,10 +724,9 @@ const struct hantro_variant rk3288_vpu_variant = { const struct hantro_variant rk3328_vpu_variant = { .dec_offset = 0x400, @@ -71,7 +71,7 @@ index 111111111111..222222222222 100644 .codec_ops = rk3399_vpu_codec_ops, .irqs = rockchip_vdpu2_irqs, .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs), -@@ -787,20 +786,6 @@ const struct hantro_variant rk3568_vepu_variant = { +@@ -771,20 +770,6 @@ const struct hantro_variant rk3568_vepu_variant = { .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) }; diff --git a/patch/kernel/archive/rockchip64-6.17/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch b/patch/kernel/archive/rockchip64-6.18/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch similarity index 75% rename from patch/kernel/archive/rockchip64-6.17/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch rename to patch/kernel/archive/rockchip64-6.18/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch index ef193cd84..5e6dbad6f 100644 --- a/patch/kernel/archive/rockchip64-6.17/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch +++ b/patch/kernel/archive/rockchip64-6.18/net-ethernet-realtek-add-r8169-LED-configuration-from-OF.patch @@ -1,16 +1,15 @@ -From cde62ca7cdeeba96ca67bb02f40cbfce61515cd8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 30 Aug 2025 14:20:46 +0800 -Subject: [PATCH 2/3] net: ethernet: realtek: add r8169 LED configuration from - OF +Subject: net: ethernet: realtek: add r8169 LED configuration from OF Signed-off-by: retro98boy --- - drivers/net/ethernet/realtek/r8169_main.c | 11 +++++++++++ + drivers/net/ethernet/realtek/r8169_main.c | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 43170500d..973934934 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -21,6 +21,7 @@ @@ -21,7 +20,7 @@ index 43170500d..973934934 100644 #include #include #include -@@ -2375,6 +2376,15 @@ void r8169_apply_firmware(struct rtl8169_private *tp) +@@ -2373,6 +2374,15 @@ void r8169_apply_firmware(struct rtl8169_private *tp) } } @@ -37,7 +36,7 @@ index 43170500d..973934934 100644 static void rtl8168_config_eee_mac(struct rtl8169_private *tp) { /* Adjust EEE LED frequency */ -@@ -3392,6 +3402,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) +@@ -3390,6 +3400,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); rtl8168_config_eee_mac(tp); @@ -46,5 +45,5 @@ index 43170500d..973934934 100644 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); -- -2.51.0 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch b/patch/kernel/archive/rockchip64-6.18/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch similarity index 55% rename from patch/kernel/archive/rockchip64-6.17/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch rename to patch/kernel/archive/rockchip64-6.18/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch index 896ae0939..324bae621 100644 --- a/patch/kernel/archive/rockchip64-6.17/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch +++ b/patch/kernel/archive/rockchip64-6.18/net-phy-realtek-add-rtl8211x-LED-configuration-from-OF.patch @@ -1,18 +1,18 @@ -From cf497ba4b9e7986f5f7ce6466dc960f964a0719b Mon Sep 17 00:00:00 2001 -From: John Doe -Date: Sat, 30 Aug 2025 14:20:58 +0800 -Subject: [PATCH 3/3] net: phy: realtek: add rtl8211x LED configuration from OF +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Mon, 20 Oct 2025 21:42:28 +0200 +Subject: net: phy: realtek: add rtl8211x LED configuration from OF Signed-off-by: retro98boy --- - drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++ + drivers/net/phy/realtek/realtek_main.c | 11 ++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index dd0d67514..4743f99b3 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -215,6 +215,15 @@ static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page, +@@ -214,6 +214,15 @@ static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page, return phy_restore_page(phydev, oldpage, ret); } @@ -28,15 +28,15 @@ index dd0d67514..4743f99b3 100644 static int rtl821x_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; -@@ -595,6 +604,8 @@ static int rtl8211f_config_init(struct phy_device *phydev) - if (ret) +@@ -263,6 +272,8 @@ static int rtl8211f_probe(struct phy_device *phydev) + if (ret < 0) return ret; + rtl821x_led_of_init(phydev); + - if (priv->has_phycr2) { - ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, - RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, + /* Disable all PME events */ + ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE, + RTL8211F_WOL_SETTINGS_EVENTS, 0); -- -2.51.0 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/net-usb-r8152-add-LED-configuration-from-OF.patch b/patch/kernel/archive/rockchip64-6.18/net-usb-r8152-add-LED-configuration-from-OF.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/net-usb-r8152-add-LED-configuration-from-OF.patch rename to patch/kernel/archive/rockchip64-6.18/net-usb-r8152-add-LED-configuration-from-OF.patch diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/Makefile b/patch/kernel/archive/rockchip64-6.18/overlay/Makefile similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/overlay/Makefile rename to patch/kernel/archive/rockchip64-6.18/overlay/Makefile index 29d3f6168..dd6db7aab 100644 --- a/patch/kernel/archive/rockchip64-6.17/overlay/Makefile +++ b/patch/kernel/archive/rockchip64-6.18/overlay/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ hinlink-h88k-240x135-lcd.dtbo \ - rk3308-otg-host.dtbo \ + rk35xx-radxa-zero-3w-ext-ant.dtbo \ + rk3308-otg-host.dtbo \ rk3308-s0-ext-antenna.dtbo \ rk3308-b@1.3ghz.dtbo \ rk3308-bs.dtbo rk3308-bs@1.3ghz.dtbo \ @@ -18,6 +19,8 @@ dtbo-$(CONFIG_ARCH_ROCKCHIP) += \ rockchip-rk3318-box-led-conf3.dtbo \ rockchip-rk3318-box-led-conf4.dtbo \ rockchip-rk3318-box-led-conf5.dtbo \ + rockchip-rk3318-box-led-conf6.dtbo \ + rockchip-rk3318-box-led-conf7.dtbo \ rockchip-rk3318-box-wlan-ap6330.dtbo \ rockchip-rk3318-box-wlan-ap6334.dtbo \ rockchip-rk3318-box-wlan-ext.dtbo \ diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/README.rockchip-overlays b/patch/kernel/archive/rockchip64-6.18/overlay/README.rockchip-overlays similarity index 93% rename from patch/kernel/archive/rockchip64-6.17/overlay/README.rockchip-overlays rename to patch/kernel/archive/rockchip64-6.18/overlay/README.rockchip-overlays index 45b05f6a6..e13c3ca18 100644 --- a/patch/kernel/archive/rockchip64-6.17/overlay/README.rockchip-overlays +++ b/patch/kernel/archive/rockchip64-6.18/overlay/README.rockchip-overlays @@ -146,8 +146,8 @@ or enabling the internal pull-up ### rk3318-box-led-conf1 -Activates led/gpio configuration for rk3318 tv box boards with signature -YX_RK3328 and clones +Generic default led/gpio configuration for rk3318 tv box boards. +Does not enable any specific or peculiar hardware. ### rk3318-box-led-conf2 @@ -165,6 +165,20 @@ system. Also enables gpio leds and keys. Generic rk3318-box configuration but with sdio chip on sdmmc-ext connector +### rk3318-box-led-conf5 + +Configuration for rk3318 boards with with signature YX_RK3328 and clones. + +### rk3318-box-led-conf6 + +Configuration for rk3318 boards with with signature T98_RK3318 and clones. +Seen in commercial tv boxes like Hongtop H50. + +### rk3318-box-led-conf7 + +Configuration for rk3318 boards with with signature T9_RK3318 and clones. +Seen in commercial tv boxes like T9 Sunwell 3318. + ### rk3318-box-emmc-ddr Activates eMMC DDR capability for rk3318 tv box boards. Probably all the eMMC chips diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/hinlink-h88k-240x135-lcd.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/hinlink-h88k-240x135-lcd.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/hinlink-h88k-240x135-lcd.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/hinlink-h88k-240x135-lcd.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-b@1.3ghz.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-b@1.3ghz.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-b@1.3ghz.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-b@1.3ghz.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-bs.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-bs.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-bs.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-bs.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-bs@1.3ghz.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-bs@1.3ghz.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-bs@1.3ghz.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-bs@1.3ghz.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-otg-host.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-otg-host.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-otg-host.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-otg-host.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-pcm5102a.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-pcm5102a.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-pcm5102a.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-pcm5102a.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rk3308-s0-ext-antenna.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk3308-s0-ext-antenna.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rk3308-s0-ext-antenna.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rk3308-s0-ext-antenna.dtso diff --git a/patch/kernel/archive/rockchip64-6.18/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso new file mode 100644 index 000000000..7a32b8fe5 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/overlay/rk35xx-radxa-zero-3w-ext-ant.dtso @@ -0,0 +1,37 @@ +/dts-v1/; +/plugin/; + +#include +#include + +/ { + compatible = "radxa,zero-3w", "rockchip,rk3566"; + + fragment@0 { + target-path = "/"; + __overlay__ { + board_antenna: board-antenna { + compatible = "regulator-fixed"; + enable-active-low; + gpio = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&ant_1>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-name = "board-antenna"; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&pinctrl>; + __overlay__ { + antenna { + ant_1: ant-1 { + rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + }; + }; +}; diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-dusun-010r-rp3328b.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-dusun-010r-rp3328b.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-dusun-010r-rp3328b.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-dusun-010r-rp3328b.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-fixup.scr-cmd b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-fixup.scr-cmd similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-fixup.scr-cmd rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-fixup.scr-cmd diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-cpu-hs.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-cpu-hs.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-cpu-hs.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-cpu-hs.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-emmc-ddr.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-emmc-ddr.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-emmc-ddr.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-emmc-ddr.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-emmc-hs200.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-emmc-hs200.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-emmc-hs200.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-emmc-hs200.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf3.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf3.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf3.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf3.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf4.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf4.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf4.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf4.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf5.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf5.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-led-conf5.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf5.dtso diff --git a/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf6.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf6.dtso new file mode 100644 index 000000000..0860836d9 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf6.dtso @@ -0,0 +1,88 @@ +/dts-v1/; +/plugin/; + +#include +#include +#include + +/** + * T98_RK3318 (Hongtop H50) + */ + +&{/} { + + i2c_aux_display: i2c-aux-display { + + compatible = "i2c-gpio"; + sda-gpios = <&gpio1 RK_PD1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio1 RK_PD0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <5>; + i2c-gpio,sda-output-only; + i2c-gpio,scl-output-only; + #address-cells = <1>; + #size-cells = <0>; + + display@24 { + compatible = "fdhisi,fd650"; + reg = <0x24>; + + digits { + #address-cells = <1>; + #size-cells = <0>; + + digit@0 { + reg = <0>; + segments = <1 3>, <1 4>, <1 5>, <1 0>, <1 1>, <1 2>, <1 6>; + }; + + digit@1 { + reg = <1>; + segments = <2 3>, <2 4>, <2 5>, <2 0>, <2 1>, <2 2>, <2 6>; + }; + + digit@2 { + reg = <2>; + segments = <3 3>, <3 4>, <3 5>, <3 0>, <3 1>, <3 2>, <3 6>; + }; + + digit@3{ + reg = <3>; + segments = <4 3>, <4 4>, <4 5>, <4 0>, <4 1>, <4 2>, <4 6>; + }; + + }; + + leds { + #address-cells = <2>; + #size-cells = <0>; + + led@1,7 { + reg = <1 7>; + function = "usb"; + linux,default-trigger = "usb-host"; + }; + + led@2,7 { + reg = <2 7>; + function = "colon"; + }; + + led@3,7 { + reg = <3 7>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "stmmac-0:00:link"; + }; + + led@4,7 { + reg = <4 7>; + function = LED_FUNCTION_WLAN; + linux,default-trigger = "mmc1"; + }; + + }; + + }; + + }; + +}; diff --git a/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf7.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf7.dtso new file mode 100644 index 000000000..a38abec05 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-led-conf7.dtso @@ -0,0 +1,100 @@ +/dts-v1/; +/plugin/; + +#include +#include +#include + +/** + * T9_RK3318 (T9 Sunwell 3318) + */ + +&{/} { + + i2c_aux_display: i2c-aux-display { + + compatible = "i2c-gpio"; + sda-gpios = <&gpio2 RK_PC6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio2 RK_PC3 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <5>; + i2c-gpio,sda-output-only; + i2c-gpio,scl-output-only; + #address-cells = <1>; + #size-cells = <0>; + + display@24 { + compatible = "fdhisi,fd655"; + reg = <0x24>; + + digits { + #address-cells = <1>; + #size-cells = <0>; + + digit@0 { + reg = <0>; + segments = <4 3>, <4 4>, <4 5>, <4 0>, <4 1>, <4 2>, <4 6>; + }; + + digit@1 { + reg = <1>; + segments = <3 3>, <3 4>, <3 5>, <3 0>, <3 1>, <3 2>, <3 6>; + }; + + digit@2 { + reg = <2>; + segments = <2 3>, <2 4>, <2 5>, <2 0>, <2 1>, <2 2>, <2 6>; + }; + + digit@3{ + reg = <3>; + segments = <1 3>, <1 4>, <1 5>, <1 0>, <1 1>, <1 2>, <1 6>; + }; + + }; + + leds { + #address-cells = <2>; + #size-cells = <0>; + + led@0,0 { + reg = <0 0>; + function = LED_FUNCTION_ALARM; + }; + + led@0,1 { + reg = <0 1>; + function = LED_FUNCTION_USB; + }; + + led@0,2 { + reg = <0 2>; + function = "play"; + }; + + led@0,3 { + reg = <0 3>; + function = "pause"; + }; + + led@0,4 { + reg = <0 4>; + function = "colon"; + }; + + led@0,5 { + reg = <0 5>; + function = LED_FUNCTION_LAN; + }; + + led@0,6 { + reg = <0 6>; + function = LED_FUNCTION_WLAN; + }; + + }; + + }; + + }; + +}; diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ap6330.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ap6330.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ap6330.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ap6330.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ap6334.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ap6334.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ap6334.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ap6334.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ext.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ext.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3318-box-wlan-ext.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3318-box-wlan-ext.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-i2c0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-i2c0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-i2c0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-i2c0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-i2s1-pcm5102.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-i2s1-pcm5102.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-i2s1-pcm5102.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-i2s1-pcm5102.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mksklipad50-enable-rtc-end1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mksklipad50-enable-rtc-end1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mksklipad50-enable-rtc-end1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mksklipad50-enable-rtc-end1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mksklipad50-enable-v4l2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mksklipad50-enable-v4l2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mksklipad50-enable-v4l2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mksklipad50-enable-v4l2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mkspi-disable-lcd-spi.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mkspi-disable-lcd-spi.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-mkspi-disable-lcd-spi.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-mkspi-disable-lcd-spi.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-opp-1.4ghz.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-opp-1.4ghz.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-opp-1.4ghz.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-opp-1.4ghz.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-opp-1.5ghz.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-opp-1.5ghz.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-opp-1.5ghz.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-opp-1.5ghz.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-spi-spidev.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-spi-spidev.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-spi-spidev.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-spi-spidev.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-uart1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-uart1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3328-uart1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3328-uart1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-dwc3-0-host.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-dwc3-0-host.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-dwc3-0-host.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-dwc3-0-host.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-i2c7.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-i2c7.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-i2c7.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-i2c7.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-i2c8.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-i2c8.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-i2c8.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-i2c8.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-opp-2ghz.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-opp-2ghz.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-opp-2ghz.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-opp-2ghz.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-pcie-gen2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-pcie-gen2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-pcie-gen2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-pcie-gen2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-spi-jedec-nor.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-spi-jedec-nor.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-spi-jedec-nor.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-spi-jedec-nor.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-spi-spidev.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-spi-spidev.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-spi-spidev.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-spi-spidev.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-uart4.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-uart4.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-uart4.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-uart4.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-w1-gpio.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-w1-gpio.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3399-w1-gpio.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3399-w1-gpio.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3566-sata2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3566-sata2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3566-sata2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3566-sata2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-i2c0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-i2c0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-i2c0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-i2c0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-i2c1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-i2c1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-i2c1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-i2c1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm9.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm9.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-pwm9.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-pwm9.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-spi-spidev.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-spi-spidev.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-spi-spidev.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-spi-spidev.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart0-rts_cts.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart0-rts_cts.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart0-rts_cts.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart0-rts_cts.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-hk-uart1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-hk-uart1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-nanopi-r5c-leds.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-nanopi-r5c-leds.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-nanopi-r5c-leds.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-nanopi-r5c-leds.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-nanopi-r5s-leds.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-nanopi-r5s-leds.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-nanopi-r5s-leds.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-nanopi-r5s-leds.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-rock-3a-disable-uart2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-rock-3a-disable-uart2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3568-rock-3a-disable-uart2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3568-rock-3a-disable-uart2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-fanctrl.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-fanctrl.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-fanctrl.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-fanctrl.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-hdmirx.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-hdmirx.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-hdmirx.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-hdmirx.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-i2c8-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-i2c8-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-i2c8-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-i2c8-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopc-t6-mmc-frequency.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopc-t6-mmc-frequency.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopc-t6-mmc-frequency.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopc-t6-mmc-frequency.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopi-m6-display-dsi1-yx35.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopi-m6-display-dsi1-yx35.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopi-m6-display-dsi1-yx35.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopi-m6-display-dsi1-yx35.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopi-m6-spi-nor-flash.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopi-m6-spi-nor-flash.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-nanopi-m6-spi-nor-flash.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-nanopi-m6-spi-nor-flash.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm0-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm0-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm1-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm1-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm10-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm10-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm10-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm10-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm11-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm11-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm11-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm11-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm11-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm11-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm11-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm11-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm12-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm12-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm12-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm12-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm13-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm13-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm13-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm13-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm13-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm13-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm13-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm13-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm14-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm14-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m3.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m3.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm15-m3.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm15-m3.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm2-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm2-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm2-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm2-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m3.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m3.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm3-m3.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm3-m3.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm5-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm5-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm5-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm5-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm6-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm6-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm6-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm6-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm6-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm6-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm6-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm6-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm7-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm7-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm7-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm7-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm7-m3.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm7-m3.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm7-m3.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm7-m3.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm8-m0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm8-m0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-pwm8-m0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-pwm8-m0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-rkvenc-overlay.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-rkvenc-overlay.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-rkvenc-overlay.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-rkvenc-overlay.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata0.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata0.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata0.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata0.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-sata2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-sata2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart1-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart1-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart1-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart1-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart3-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart3-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart3-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart3-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart4-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart4-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart4-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart4-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart6-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart6-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart6-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart6-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart7-m2.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart7-m2.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart7-m2.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart7-m2.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart8-m1.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart8-m1.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rk3588-uart8-m1.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rk3588-uart8-m1.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rockpi4cplus-usb-host.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rockpi4cplus-usb-host.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rockpi4cplus-usb-host.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rockpi4cplus-usb-host.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rockpro64-lcd.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rockpro64-lcd.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-rockpro64-lcd.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-rockpro64-lcd.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-sakurapi-rk3308b-pcm5102a.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-sakurapi-rk3308b-pcm5102a.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-sakurapi-rk3308b-pcm5102a.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-sakurapi-rk3308b-pcm5102a.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/overlay/rockchip-sakurapi-rk3308b-ws2812.dtso b/patch/kernel/archive/rockchip64-6.18/overlay/rockchip-sakurapi-rk3308b-ws2812.dtso similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/overlay/rockchip-sakurapi-rk3308b-ws2812.dtso rename to patch/kernel/archive/rockchip64-6.18/overlay/rockchip-sakurapi-rk3308b-ws2812.dtso diff --git a/patch/kernel/archive/rockchip64-6.17/regulator-add-fan53200-driver.patch b/patch/kernel/archive/rockchip64-6.18/regulator-add-fan53200-driver.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/regulator-add-fan53200-driver.patch rename to patch/kernel/archive/rockchip64-6.18/regulator-add-fan53200-driver.patch index e1c116edc..a117ae994 100644 --- a/patch/kernel/archive/rockchip64-6.17/regulator-add-fan53200-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/regulator-add-fan53200-driver.patch @@ -24,7 +24,7 @@ diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 111111111111..222222222222 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig -@@ -792,6 +792,7 @@ CONFIG_REGULATOR_BD9571MWV=y +@@ -810,6 +810,7 @@ CONFIG_REGULATOR_BD9571MWV=y CONFIG_REGULATOR_CROS_EC=y CONFIG_REGULATOR_DA9211=m CONFIG_REGULATOR_FAN53555=y @@ -36,7 +36,7 @@ diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 111111111111..222222222222 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig -@@ -432,6 +432,17 @@ config REGULATOR_FAN53880 +@@ -440,6 +440,17 @@ config REGULATOR_FAN53880 (PMIC), it is controlled by I2C and provides one BUCK, one BOOST and four LDO outputs. @@ -58,7 +58,7 @@ diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 111111111111..222222222222 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile -@@ -51,6 +51,7 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o +@@ -52,6 +52,7 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o obj-$(CONFIG_REGULATOR_FAN53880) += fan53880.o diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-0001-pinctrl-slew-mux.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-0001-pinctrl-slew-mux.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/rk3308-0001-pinctrl-slew-mux.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-0001-pinctrl-slew-mux.patch index 2605c1e60..bff0a0340 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3308-0001-pinctrl-slew-mux.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3308-0001-pinctrl-slew-mux.patch @@ -244,7 +244,7 @@ diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pin index 111111111111..222222222222 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h -@@ -145,6 +145,7 @@ enum pin_config_param { +@@ -149,6 +149,7 @@ enum pin_config_param { PIN_CONFIG_SKEW_DELAY, PIN_CONFIG_SLEEP_HARDWARE_STATE, PIN_CONFIG_SLEW_RATE, diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-acodec-vendor-driver.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-acodec-vendor-driver.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-acodec-vendor-driver.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-acodec-vendor-driver.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-add-gmac-alias.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-add-gmac-alias.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-add-gmac-alias.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-add-gmac-alias.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-add-missing-i2s-controllers.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-add-missing-i2s-controllers.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-add-missing-i2s-controllers.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-add-missing-i2s-controllers.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-add-tsadc-driver.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-add-tsadc-driver.patch similarity index 91% rename from patch/kernel/archive/rockchip64-6.17/rk3308-add-tsadc-driver.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-add-tsadc-driver.patch index ed8f6d73d..3e18a75f4 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3308-add-tsadc-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3308-add-tsadc-driver.patch @@ -26,8 +26,8 @@ diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_therm index 111111111111..222222222222 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c -@@ -1061,6 +1061,28 @@ static void rk_tsadcv3_tshut_mode(int chn, void __iomem *regs, - writel_relaxed(val_cru, regs + TSADCV3_HSHUT_CRU_INT_EN); +@@ -1098,6 +1098,28 @@ static int rk_tsadcv2_get_trim_code(const struct chip_tsadc_table *table, + return code - base_code; } +static const struct rockchip_tsadc_chip rk3308_tsadc_data = { @@ -55,7 +55,7 @@ index 111111111111..222222222222 100644 static const struct rockchip_tsadc_chip px30_tsadc_data = { /* cpu, gpu */ .chn_offset = 0, -@@ -1322,6 +1344,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { +@@ -1367,6 +1389,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3288-tsadc", .data = (void *)&rk3288_tsadc_data, }, diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-dts-legacy-cryptov2.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-dts-legacy-cryptov2.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-dts-legacy-cryptov2.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-dts-legacy-cryptov2.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-dts-thermal-zones.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-dts-thermal-zones.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-dts-thermal-zones.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-dts-thermal-zones.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-fix-10mbit-ethernet.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-fix-10mbit-ethernet.patch similarity index 61% rename from patch/kernel/archive/rockchip64-6.17/rk3308-fix-10mbit-ethernet.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-fix-10mbit-ethernet.patch index cfdeb5627..6c1a7798e 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3308-fix-10mbit-ethernet.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3308-fix-10mbit-ethernet.patch @@ -1,8 +1,7 @@ -From 545ae14ee0159a449e6e0f2f1f54b8c5cc6023ef Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: chillymattster <106633144+chillymattster@users.noreply.github.com> -From: Brent Roman Date: Wed, 3 Sep 2025 18:29:16 +0200 -Subject: [PATCH] rk3308: Fix 10Mbit Ethernet +Subject: rk3308: Fix 10Mbit Ethernet Origin: https://github.com/armbian/build/pull/6117 Bug-armbian: https://github.com/armbian/build/pull/8575 @@ -11,26 +10,11 @@ Bug-armbian: https://forum.armbian.com/topic/30235-rockpi-s-ethernet-10mbps-not- Signed-off-by: chillymattster <106633144+chillymattster@users.noreply.github.com> Last-Update: 2025-09-06 --- - This fixes bug AR-1904. - The original fix was only for current and not for edge kernel which caused - the patch being lost and made the problem reoccur. - . - According to the original PR#6117 the problem of 10mbps ethernot not working - has first been seen in the 5.15 armbian kernel caused by a rewrite of speed - setting for rk3308 in dwmc-rk.c that for unknown reasons completely omitted - the code needed to reprogram the MAC clock as appropriate for the selected - ethernet speed. - . - This patch corrects RK3308_GMAC_FLOW_CTRL and RK3308_GMAC_FLOW_CTRL_CLR to use - the correct bits for MAC onfiguration and restores the missing code needed for - setting the MAC clock required to match the selected ethernet speed. - . - - drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) + drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 11 ++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c -index f6687c2f30f6..45dab3b5680f 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -503,8 +503,8 @@ static const struct rk_gmac_ops rk3288_ops = { @@ -58,7 +42,6 @@ index f6687c2f30f6..45dab3b5680f 100644 return rk_set_reg_speed(bsp_priv, &rk3308_reg_speed_data, RK3308_GRF_MAC_CON0, interface, speed); } - -- -2.39.5 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-fix-uart-dma.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-fix-uart-dma.patch similarity index 93% rename from patch/kernel/archive/rockchip64-6.17/rk3308-fix-uart-dma.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-fix-uart-dma.patch index a6b17d1b7..ad1546e36 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3308-fix-uart-dma.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3308-fix-uart-dma.patch @@ -62,14 +62,14 @@ diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index 111111111111..222222222222 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c -@@ -88,6 +88,17 @@ static const struct rockchip_grf_info rk3328_grf __initconst = { +@@ -87,6 +87,17 @@ static const struct rockchip_grf_info rk3328_grf __initconst = { .num_values = ARRAY_SIZE(rk3328_defaults), }; +#define RK3308_GRF_SOC_CON3 0x30c + +static const struct rockchip_grf_value rk3308_defaults[] __initconst = { -+ { "uart dma mask", RK3308_GRF_SOC_CON3, HIWORD_UPDATE(0, 0x1f, 10) }, ++ { "uart dma mask", RK3308_GRF_SOC_CON3, FIELD_PREP_WM16_CONST(GENMASK(14, 10), 0) }, +}; + +static const struct rockchip_grf_info rk3308_grf __initconst = { @@ -80,7 +80,7 @@ index 111111111111..222222222222 100644 #define RK3368_GRF_SOC_CON15 0x43c static const struct rockchip_grf_value rk3368_defaults[] __initconst = { -@@ -173,6 +184,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = { +@@ -172,6 +183,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = { }, { .compatible = "rockchip,rk3328-grf", .data = (void *)&rk3328_grf, diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-i2s-default-rate.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-i2s-default-rate.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-i2s-default-rate.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-i2s-default-rate.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-internal-rgb-lcdc.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-internal-rgb-lcdc.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-internal-rgb-lcdc.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-internal-rgb-lcdc.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3308-vop-output.patch b/patch/kernel/archive/rockchip64-6.18/rk3308-vop-output.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3308-vop-output.patch rename to patch/kernel/archive/rockchip64-6.18/rk3308-vop-output.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-add-dmc-driver.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-add-dmc-driver.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/rk3328-add-dmc-driver.patch rename to patch/kernel/archive/rockchip64-6.18/rk3328-add-dmc-driver.patch index 050bc73a7..e5492f5b7 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-add-dmc-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-add-dmc-driver.patch @@ -341,7 +341,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -595,6 +595,67 @@ tsadc: tsadc@ff250000 { +@@ -604,6 +604,67 @@ tsadc: tsadc@ff250000 { status = "disabled"; }; @@ -413,7 +413,7 @@ diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 111111111111..222222222222 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c -@@ -87,6 +87,134 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = { +@@ -88,6 +88,134 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = { .get_parent = rockchip_ddrclk_get_parent, }; @@ -548,7 +548,7 @@ index 111111111111..222222222222 100644 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, const char *const *parent_names, u8 num_parents, int mux_offset, -@@ -114,6 +242,9 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, +@@ -115,6 +243,9 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, case ROCKCHIP_DDRCLK_SIP: init.ops = &rockchip_ddrclk_sip_ops; break; @@ -602,7 +602,7 @@ diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 111111111111..222222222222 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig -@@ -129,6 +129,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ +@@ -140,6 +140,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ buck voltages and update a proper CCI frequency. Use the notification to get the regulator status. @@ -625,7 +625,7 @@ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 111111111111..222222222222 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o +@@ -14,6 +14,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o @@ -637,7 +637,7 @@ diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockch index 111111111111..222222222222 100644 --- a/drivers/devfreq/event/rockchip-dfi.c +++ b/drivers/devfreq/event/rockchip-dfi.c -@@ -24,6 +24,8 @@ +@@ -25,6 +25,8 @@ #include #include @@ -646,7 +646,7 @@ index 111111111111..222222222222 100644 #include #include #include -@@ -99,6 +101,7 @@ struct rockchip_dfi { +@@ -97,6 +99,7 @@ struct rockchip_dfi { struct device *dev; void __iomem *regs; @@ -654,7 +654,7 @@ index 111111111111..222222222222 100644 struct regmap *regmap_pmu; struct clk *clk; int usecount; -@@ -668,6 +671,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) +@@ -711,6 +714,46 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi) } #endif @@ -701,7 +701,7 @@ index 111111111111..222222222222 100644 static int rk3399_dfi_init(struct rockchip_dfi *dfi) { struct regmap *regmap_pmu = dfi->regmap_pmu; -@@ -756,6 +799,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) +@@ -808,6 +851,8 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi) }; static const struct of_device_id rockchip_dfi_id_match[] = { @@ -710,7 +710,7 @@ index 111111111111..222222222222 100644 { .compatible = "rockchip,rk3399-dfi", .data = rk3399_dfi_init }, { .compatible = "rockchip,rk3568-dfi", .data = rk3568_dfi_init }, { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init }, -@@ -785,14 +830,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -837,14 +882,30 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (IS_ERR(dfi->regs)) return PTR_ERR(dfi->regs); @@ -748,7 +748,7 @@ index 111111111111..222222222222 100644 dfi->dev = dev; mutex_init(&dfi->mutex); -@@ -817,6 +878,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) +@@ -869,6 +930,8 @@ static int rockchip_dfi_probe(struct platform_device *pdev) if (ret) return ret; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-add-rga-node.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-add-rga-node.patch similarity index 95% rename from patch/kernel/archive/rockchip64-6.17/rk3328-add-rga-node.patch rename to patch/kernel/archive/rockchip64-6.18/rk3328-add-rga-node.patch index a1fc378f8..267cd1203 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-add-rga-node.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-add-rga-node.patch @@ -11,7 +11,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -817,6 +817,20 @@ vop_mmu: iommu@ff373f00 { +@@ -846,6 +846,20 @@ vop_mmu: iommu@ff373f00 { status = "disabled"; }; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-spdif.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-spdif.patch similarity index 87% rename from patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-spdif.patch rename to patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-spdif.patch index 3549f0f59..e5228cbc9 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-spdif.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-spdif.patch @@ -54,8 +54,8 @@ Subject: [ARCHEOLOGY] rockchip64: tidy up rk3328 patches > X-Git-Archeology: Subject: bump rockchip64 edge to v6.3 > X-Git-Archeology: --- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 27 ++++++++++ - 1 file changed, 27 insertions(+) + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 22 ++++++++++ + 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 111111111111..222222222222 100644 @@ -88,26 +88,7 @@ index 111111111111..222222222222 100644 timer { compatible = "arm,armv8-timer"; interrupts = , -@@ -331,6 +351,10 @@ power: power-controller { - #address-cells = <1>; - #size-cells = <0>; - -+ power-domain@RK3328_PD_GPU { -+ reg = ; -+ clocks = <&cru ACLK_GPU>; -+ }; - power-domain@RK3328_PD_HEVC { - reg = ; - clocks = <&cru SCLK_VENC_CORE>; -@@ -712,6 +736,7 @@ gpu: gpu@ff300000 { - "ppmmu1"; - clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; - clock-names = "bus", "core"; -+ power-domains = <&power RK3328_PD_GPU>; - resets = <&cru SRST_GPU_A>; - operating-points-v2 = <&gpu_opp_table>; - }; -@@ -969,6 +994,7 @@ cru: clock-controller@ff440000 { +@@ -973,6 +993,7 @@ cru: clock-controller@ff440000 { <&cru ACLK_BUS_PRE>, <&cru HCLK_BUS_PRE>, <&cru PCLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, <&cru HCLK_PERI>, <&cru PCLK_PERI>, @@ -115,7 +96,7 @@ index 111111111111..222222222222 100644 <&cru SCLK_RTC32K>; assigned-clock-parents = <&cru HDMIPHY>, <&cru PLL_APLL>, -@@ -990,6 +1016,7 @@ cru: clock-controller@ff440000 { +@@ -994,6 +1015,7 @@ cru: clock-controller@ff440000 { <150000000>, <75000000>, <75000000>, <150000000>, <75000000>, <75000000>, diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-usb3-reset-properties.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-usb3-reset-properties.patch similarity index 94% rename from patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-usb3-reset-properties.patch rename to patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-usb3-reset-properties.patch index 1be6463d3..18d46b85b 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-dtsi-usb3-reset-properties.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-dtsi-usb3-reset-properties.patch @@ -11,7 +11,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rock index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -1220,6 +1220,8 @@ usbdrd3: usb@ff600000 { +@@ -1219,6 +1219,8 @@ usbdrd3: usb@ff600000 { <&cru ACLK_USB3OTG>; clock-names = "ref_clk", "suspend_clk", "bus_clk"; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3328-inno-usb3phy-driver.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-inno-usb3phy-driver.patch similarity index 97% rename from patch/kernel/archive/rockchip64-6.17/rk3328-inno-usb3phy-driver.patch rename to patch/kernel/archive/rockchip64-6.18/rk3328-inno-usb3phy-driver.patch index b3d0b594c..80c7710dd 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3328-inno-usb3phy-driver.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-inno-usb3phy-driver.patch @@ -1,22 +1,20 @@ -From 460b224602414d5a3935663ac57fd891a0d8d576 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Tue, 12 Aug 2025 20:08:01 +0200 -Subject: [PATCH] Add rockchip Innosilicon USB3 phy driver +Subject: Add rockchip Innosilicon USB3 phy driver source: https://patchwork.kernel.org/project/linux-rockchip/cover/20250115012628.1035928-1-pgwipeout@gmail.com/ --- - .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++ - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 + - drivers/phy/rockchip/Kconfig | 10 + - drivers/phy/rockchip/Makefile | 1 + - drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++ - 5 files changed, 1085 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml - create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c + Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++ + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 + + drivers/phy/rockchip/Kconfig | 10 + + drivers/phy/rockchip/Makefile | 1 + + drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 870 ++++++++++ + 5 files changed, 1086 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml new file mode 100644 -index 000000000000..cde489ca87ab +index 000000000000..111111111111 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml @@ -0,0 +1,166 @@ @@ -187,10 +185,10 @@ index 000000000000..cde489ca87ab + }; + }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 7d992c3c01ce..181a900d41f9 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -903,6 +903,43 @@ u2phy_host: host-port { +@@ -1056,6 +1056,43 @@ u2phy_host: host-port { }; }; @@ -234,9 +232,9 @@ index 7d992c3c01ce..181a900d41f9 100644 sdmmc: mmc@ff500000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff500000 0x0 0x4000>; -@@ -1067,6 +1104,8 @@ usbdrd3: usb@ff600000 { - clock-names = "ref_clk", "suspend_clk", - "bus_clk"; +@@ -1222,6 +1259,8 @@ usbdrd3: usb@ff600000 { + resets = <&cru SRST_USB3OTG>; + reset-names = "usb3-otg"; dr_mode = "otg"; + phys = <&usb3phy_utmi>, <&usb3phy_pipe>; + phy-names = "usb2-phy", "usb3-phy"; @@ -244,7 +242,7 @@ index 7d992c3c01ce..181a900d41f9 100644 snps,dis-del-phy-power-chg-quirk; snps,dis_enblslpm_quirk; diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig -index 14698571b607..858e451edc5a 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2 @@ -265,7 +263,7 @@ index 14698571b607..858e451edc5a 100644 tristate "Rockchip Innosilicon MIPI CSI PHY driver" depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile -index 117aaffd037d..d7b7b090b1e2 100644 +index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/Makefile +++ b/drivers/phy/rockchip/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o @@ -278,10 +276,10 @@ index 117aaffd037d..d7b7b090b1e2 100644 obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_DCPHY) += phy-rockchip-samsung-dcphy.o diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c new file mode 100644 -index 000000000000..51b9f3b7fbfa +index 000000000000..111111111111 --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c -@@ -0,0 +1,869 @@ +@@ -0,0 +1,870 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* @@ -1134,6 +1132,7 @@ index 000000000000..51b9f3b7fbfa + +static const struct of_device_id rockchip_usb3phy_dt_ids[] = { + { .compatible = "rockchip,rk3328-usb3phy", }, ++ { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, rockchip_usb3phy_dt_ids); @@ -1152,5 +1151,5 @@ index 000000000000..51b9f3b7fbfa +MODULE_DESCRIPTION("Rockchip Innosilicon USB3PHY driver"); +MODULE_LICENSE("GPL"); -- -2.43.0 +Armbian diff --git a/patch/kernel/archive/rockchip64-6.18/rk3328-roc-cc-add-missing-nodes.patch b/patch/kernel/archive/rockchip64-6.18/rk3328-roc-cc-add-missing-nodes.patch new file mode 100644 index 000000000..61461a145 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/rk3328-roc-cc-add-missing-nodes.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: tonymac32 +Date: Sat, 28 Jan 2023 17:07:35 -0500 +Subject: rk3328-roc-cc add missing nodes + +Signed-off-by: tonymac32 +--- + arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 13 ++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi +old mode 100644 +new mode 100755 +index 111111111111..222222222222 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi +@@ -385,6 +385,19 @@ &sdmmc { + status = "okay"; + }; + ++&spdif { ++ pinctrl-0 = <&spdifm0_tx>; ++ status = "okay"; ++}; ++ ++&spdif_out { ++ status = "okay"; ++}; ++ ++&spdif_sound { ++ status = "okay"; ++}; ++ + &tsadc { + status = "okay"; + }; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-add-sclk-i2sout-src-clock.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-add-sclk-i2sout-src-clock.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-add-sclk-i2sout-src-clock.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-add-sclk-i2sout-src-clock.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-dmc-polling-rate.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-dmc-polling-rate.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-dmc-polling-rate.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-dmc-polling-rate.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-enable-dwc3-xhci-usb-trb-quirk.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-enable-dwc3-xhci-usb-trb-quirk.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-enable-dwc3-xhci-usb-trb-quirk.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-enable-dwc3-xhci-usb-trb-quirk.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-fix-pci-phy.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-fix-pci-phy.patch similarity index 78% rename from patch/kernel/archive/rockchip64-6.17/rk3399-fix-pci-phy.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-fix-pci-phy.patch index f5c7d1c4e..a26aa2c04 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-fix-pci-phy.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-fix-pci-phy.patch @@ -5,14 +5,14 @@ Subject: rk3399 PCIE PHY reset on probe Signed-off-by: Andrey Safonov --- - drivers/phy/rockchip/phy-rockchip-pcie.c | 16 ++++++++++ - 1 file changed, 16 insertions(+) + drivers/phy/rockchip/phy-rockchip-pcie.c | 15 ++++++++++ + 1 file changed, 15 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c index 111111111111..222222222222 100644 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c -@@ -293,6 +293,20 @@ static const struct of_device_id rockchip_pcie_phy_dt_ids[] = { +@@ -262,6 +262,19 @@ static const struct of_device_id rockchip_pcie_phy_dt_ids[] = { MODULE_DEVICE_TABLE(of, rockchip_pcie_phy_dt_ids); @@ -23,9 +23,8 @@ index 111111111111..222222222222 100644 + for (i = 0; i < PHY_MAX_LANE_NUM; i++) + regmap_write(rk_phy->reg_base, + rk_phy->phy_data->pcie_laneoff, -+ HIWORD_UPDATE(PHY_LANE_IDLE_OFF, -+ PHY_LANE_IDLE_MASK, -+ PHY_LANE_IDLE_A_SHIFT + i)); ++ FIELD_PREP_WM16(PHY_LANE_IDLE_MASK, ++ PHY_LANE_IDLE_OFF) << i); + + reset_control_assert(rk_phy->phy_rst); +} @@ -33,7 +32,7 @@ index 111111111111..222222222222 100644 static int rockchip_pcie_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; -@@ -337,6 +351,8 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev) +@@ -306,6 +319,8 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev) phy_num = (phy_num == 0) ? 1 : PHY_MAX_LANE_NUM; dev_dbg(dev, "phy number is %d\n", phy_num); diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-fix-usb-phy.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-fix-usb-phy.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-fix-usb-phy.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-fix-usb-phy.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch similarity index 95% rename from patch/kernel/archive/rockchip64-6.17/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch index b98656907..557e203cd 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch @@ -20,7 +20,7 @@ diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/adm index 111111111111..222222222222 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -4967,6 +4967,14 @@ +@@ -5087,6 +5087,14 @@ nomsi Do not use MSI for native PCIe PME signaling (this makes all PCIe root ports use INTx for all services). @@ -36,7 +36,7 @@ index 111111111111..222222222222 100644 pd_ignore_unused diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c -index 6a6da404c664..c7d586556eeb 100644 +index 111111111111..222222222222 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -24,10 +24,14 @@ @@ -44,17 +44,17 @@ index 6a6da404c664..c7d586556eeb 100644 #include #include +#include - + #include "../pci.h" #include "pcie-rockchip.h" - + +static int bus_scan_delay = -1; +module_param_named(bus_scan_delay, bus_scan_delay, int, S_IRUGO); + static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip) { u32 status; -@@ -933,6 +937,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) +@@ -929,6 +933,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct pci_host_bridge *bridge; int err; @@ -62,7 +62,7 @@ index 6a6da404c664..c7d586556eeb 100644 if (!dev->of_node) return -ENODEV; -@@ -982,6 +987,26 @@ static int rockchip_pcie_probe(struct platform_device *pdev) +@@ -978,6 +983,26 @@ static int rockchip_pcie_probe(struct platform_device *pdev) bridge->sysdata = rockchip; bridge->ops = &rockchip_pcie_ops; @@ -110,7 +110,7 @@ diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pci index 111111111111..222222222222 100644 --- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h -@@ -351,6 +351,8 @@ struct rockchip_pcie { +@@ -328,6 +328,8 @@ struct rockchip_pcie { phys_addr_t msg_bus_addr; bool is_rc; struct resource *mem_res; @@ -121,3 +121,4 @@ index 111111111111..222222222222 100644 static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) -- Armbian + diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-sd-drive-level-8ma.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-sd-drive-level-8ma.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/rk3399-sd-drive-level-8ma.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-sd-drive-level-8ma.patch index 4f2a66e23..b4a57ad16 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-sd-drive-level-8ma.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-sd-drive-level-8ma.patch @@ -112,7 +112,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -2662,25 +2662,25 @@ sdio0_int: sdio0-int { +@@ -2658,25 +2658,25 @@ sdio0_int: sdio0-int { sdmmc { sdmmc_bus1: sdmmc-bus1 { rockchip,pins = @@ -145,7 +145,7 @@ index 111111111111..222222222222 100644 }; sdmmc_cd: sdmmc-cd { -@@ -2690,7 +2690,7 @@ sdmmc_cd: sdmmc-cd { +@@ -2686,7 +2686,7 @@ sdmmc_cd: sdmmc-cd { sdmmc_wp: sdmmc-wp { rockchip,pins = diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-sd-pwr-pinctrl.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-sd-pwr-pinctrl.patch similarity index 94% rename from patch/kernel/archive/rockchip64-6.17/rk3399-sd-pwr-pinctrl.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-sd-pwr-pinctrl.patch index 55a8f2d61..e8ee76d83 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-sd-pwr-pinctrl.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-sd-pwr-pinctrl.patch @@ -11,7 +11,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi -@@ -2657,6 +2657,11 @@ sdio0_int: sdio0-int { +@@ -2653,6 +2653,11 @@ sdio0_int: sdio0-int { rockchip,pins = <0 RK_PA4 1 &pcfg_pull_up>; }; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-unlock-temperature.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-unlock-temperature.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-unlock-temperature.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-unlock-temperature.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch similarity index 91% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch index c970d2a6a..c65c38a34 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-Revert-usb-typec-tcpm-unregister-existing-source-cap.patch @@ -13,7 +13,7 @@ diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 111111111111..222222222222 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -3110,7 +3110,7 @@ static int tcpm_register_source_caps(struct tcpm_port *port) +@@ -3114,7 +3114,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 = { }; @@ -22,7 +22,7 @@ index 111111111111..222222222222 100644 if (!port->partner_pd) port->partner_pd = usb_power_delivery_register(NULL, &desc); -@@ -3120,11 +3120,6 @@ static int tcpm_register_source_caps(struct tcpm_port *port) +@@ -3124,11 +3124,6 @@ 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; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch similarity index 92% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch index c11b8ca48..3e4e9f011 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-notify-typec-dp-hpd-state-through-extcon.patch @@ -24,7 +24,7 @@ index 111111111111..222222222222 100644 #include #include #include -@@ -74,6 +77,57 @@ struct dp_altmode { +@@ -81,6 +84,57 @@ struct dp_altmode { struct typec_altmode *plug_prime; }; @@ -82,7 +82,7 @@ index 111111111111..222222222222 100644 static int dp_altmode_notify(struct dp_altmode *dp) { unsigned long conf; -@@ -167,6 +221,7 @@ static int dp_altmode_status_update(struct dp_altmode *dp) +@@ -175,6 +229,7 @@ static int dp_altmode_status_update(struct dp_altmode *dp) dp->state = dp->plug_prime ? DP_STATE_CONFIGURE_PRIME : DP_STATE_CONFIGURE; if (dp->hpd != hpd) { @@ -90,15 +90,15 @@ index 111111111111..222222222222 100644 dp->hpd = hpd; dp->pending_hpd = true; } -@@ -175,6 +230,7 @@ static int dp_altmode_status_update(struct dp_altmode *dp) +@@ -185,6 +240,7 @@ static int dp_altmode_status_update(struct dp_altmode *dp) drm_connector_oob_hotplug_event(dp->connector_fwnode, hpd ? connector_status_connected : connector_status_disconnected); + dp_altmode_update_extcon_hpd_status(dp, hpd); dp->hpd = hpd; sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd"); - } -@@ -374,6 +430,7 @@ static int dp_altmode_vdm(struct typec_altmode *alt, + if (hpd && irq_hpd) { +@@ -393,6 +449,7 @@ static int dp_altmode_vdm(struct typec_altmode *alt, if (dp->hpd) { drm_connector_oob_hotplug_event(dp->connector_fwnode, connector_status_disconnected); diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-phy-rockchip-inno-usb2-Decrease-delay-between-po.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-phy-rockchip-inno-usb2-Decrease-delay-between-po.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-phy-rockchip-inno-usb2-Decrease-delay-between-po.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-phy-rockchip-inno-usb2-Decrease-delay-between-po.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-rockchip-inno-usb2-More-robust-charger-detection.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-rockchip-inno-usb2-More-robust-charger-detection.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-rockchip-inno-usb2-More-robust-charger-detection.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-rockchip-inno-usb2-More-robust-charger-detection.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch similarity index 91% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch index f6e0e1ce0..04b824064 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-phy-rockchip-naneng-Add-fallback-for-old-DTs.patch @@ -25,7 +25,7 @@ index 111111111111..222222222222 100644 dwc3_writel(dwc->regs, DWC3_GCTL, reg); dwc->current_dr_role = mode; -@@ -191,6 +191,7 @@ static void __dwc3_set_mode(struct work_struct *work) +@@ -192,6 +192,7 @@ static void __dwc3_set_mode(struct work_struct *work) dwc3_host_exit(dwc); break; case DWC3_GCTL_PRTCAP_DEVICE: @@ -33,7 +33,7 @@ index 111111111111..222222222222 100644 dwc3_gadget_exit(dwc); dwc3_event_buffers_cleanup(dwc); break; -@@ -210,12 +211,43 @@ static void __dwc3_set_mode(struct work_struct *work) +@@ -211,12 +212,43 @@ static void __dwc3_set_mode(struct work_struct *work) * Only perform GCTL.CoreSoftReset when there's DRD role switching. */ if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || @@ -78,7 +78,7 @@ index 111111111111..222222222222 100644 /* * Wait for internal clocks to synchronized. DWC_usb31 and * DWC_usb32 may need at least 50ms (less for DWC_usb3). To -@@ -257,6 +289,7 @@ static void __dwc3_set_mode(struct work_struct *work) +@@ -258,6 +290,7 @@ static void __dwc3_set_mode(struct work_struct *work) } break; case DWC3_GCTL_PRTCAP_DEVICE: @@ -86,7 +86,7 @@ index 111111111111..222222222222 100644 dwc3_core_soft_reset(dwc); dwc3_event_buffers_setup(dwc); -@@ -1844,6 +1877,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) +@@ -1845,6 +1878,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->dis_split_quirk = device_property_read_bool(dev, "snps,dis-split-quirk"); @@ -95,7 +95,7 @@ index 111111111111..222222222222 100644 dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; -@@ -2439,6 +2474,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) +@@ -2441,6 +2476,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -103,7 +103,7 @@ index 111111111111..222222222222 100644 if (pm_runtime_suspended(dwc->dev)) break; ret = dwc3_gadget_suspend(dwc); -@@ -2503,11 +2539,12 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) +@@ -2505,11 +2541,12 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -117,7 +117,7 @@ index 111111111111..222222222222 100644 dwc3_gadget_resume(dwc); break; case DWC3_GCTL_PRTCAP_HOST: -@@ -2571,6 +2608,7 @@ static int dwc3_runtime_checks(struct dwc3 *dwc) +@@ -2573,6 +2610,7 @@ static int dwc3_runtime_checks(struct dwc3 *dwc) { switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -125,7 +125,7 @@ index 111111111111..222222222222 100644 if (dwc->connected) return -EBUSY; break; -@@ -2609,6 +2647,7 @@ int dwc3_runtime_resume(struct dwc3 *dwc) +@@ -2611,6 +2649,7 @@ int dwc3_runtime_resume(struct dwc3 *dwc) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -133,7 +133,7 @@ index 111111111111..222222222222 100644 if (dwc->pending_events) { pm_runtime_put(dev); dwc->pending_events = false; -@@ -2633,6 +2672,7 @@ int dwc3_runtime_idle(struct dwc3 *dwc) +@@ -2635,6 +2674,7 @@ int dwc3_runtime_idle(struct dwc3 *dwc) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -158,7 +158,7 @@ index 111111111111..222222222222 100644 #define DWC3_GCTL_CORESOFTRESET BIT(11) #define DWC3_GCTL_SOFITPSYNC BIT(10) -@@ -1152,6 +1158,10 @@ struct dwc3_scratchpad_array { +@@ -1164,6 +1170,10 @@ struct dwc3_glue_ops { * @sys_wakeup: set if the device may do system wakeup. * @wakeup_configured: set if the device is configured for remote wakeup. * @suspended: set to track suspend event due to U3/L2. @@ -169,7 +169,7 @@ index 111111111111..222222222222 100644 * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY * before PM suspend. * @imod_interval: set the interrupt moderation interval in 250ns -@@ -1392,6 +1402,8 @@ struct dwc3 { +@@ -1406,6 +1416,8 @@ struct dwc3 { unsigned suspended:1; unsigned susphy_state:1; @@ -229,7 +229,7 @@ index 111111111111..222222222222 100644 return NOTIFY_DONE; } -@@ -547,8 +558,7 @@ int dwc3_drd_init(struct dwc3 *dwc) +@@ -548,8 +559,7 @@ int dwc3_drd_init(struct dwc3 *dwc) if (dwc->edev) { dwc->edev_nb.notifier_call = dwc3_drd_notifier; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch similarity index 92% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch index 82c665cb1..faec9829e 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Extend-reset-quirk-support-to-include-role-.patch @@ -33,7 +33,7 @@ index 111111111111..222222222222 100644 if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) mode = DWC3_GCTL_PRTCAP_HOST; else -@@ -487,6 +489,9 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) +@@ -488,6 +490,9 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) spin_lock_irqsave(&dwc->lock, flags); switch (dwc->current_dr_role) { @@ -43,7 +43,7 @@ index 111111111111..222222222222 100644 case DWC3_GCTL_PRTCAP_HOST: role = USB_ROLE_HOST; break; -@@ -518,6 +523,8 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc) +@@ -519,6 +524,8 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc) } else { dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL; mode = DWC3_GCTL_PRTCAP_DEVICE; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch similarity index 90% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch index c6c998415..d007db458 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-dwc3-Track-the-power-state-of-usb3_generic_phy.patch @@ -18,7 +18,7 @@ diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 111111111111..222222222222 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -931,6 +931,7 @@ static int dwc3_phy_power_on(struct dwc3 *dwc) +@@ -932,6 +932,7 @@ static int dwc3_phy_power_on(struct dwc3 *dwc) goto err_power_off_usb3_phy; } @@ -26,7 +26,7 @@ index 111111111111..222222222222 100644 return 0; err_power_off_usb3_phy: -@@ -951,8 +952,10 @@ static void dwc3_phy_power_off(struct dwc3 *dwc) +@@ -952,8 +953,10 @@ static void dwc3_phy_power_off(struct dwc3 *dwc) { int i; @@ -43,7 +43,7 @@ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 111111111111..222222222222 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h -@@ -1224,6 +1224,8 @@ struct dwc3 { +@@ -1238,6 +1238,8 @@ struct dwc3 { u8 num_usb2_ports; u8 num_usb3_ports; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch similarity index 96% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch index eb05df54c..a5e87e6ba 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-altmodes-displayport-Respect-DP_CAP_RECEPT.patch @@ -21,7 +21,7 @@ diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmod index 111111111111..222222222222 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c -@@ -170,11 +170,29 @@ static int dp_altmode_configure(struct dp_altmode *dp, u8 con) +@@ -177,11 +177,29 @@ static int dp_altmode_configure(struct dp_altmode *dp, u8 con) /* Account for active cable capabilities */ if (dp->plug_prime) pin_assign &= DP_CAP_UFP_D_PIN_ASSIGN(dp->plug_prime->vdo); @@ -51,7 +51,7 @@ index 111111111111..222222222222 100644 /* Determining the initial pin assignment. */ if (!DP_CONF_GET_PIN_ASSIGN(dp->data.conf)) { /* Is USB together with DP preferred */ -@@ -786,15 +804,37 @@ int dp_altmode_probe(struct typec_altmode *alt) +@@ -814,15 +832,37 @@ int dp_altmode_probe(struct typec_altmode *alt) struct typec_altmode *plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P); struct fwnode_handle *fwnode; struct dp_altmode *dp; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch similarity index 94% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch index dcaf37392..d22c84c4a 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-tcpm-Fix-PD-devices-capabilities-registrat.patch @@ -18,7 +18,7 @@ diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 111111111111..222222222222 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -3111,15 +3111,22 @@ static int tcpm_register_source_caps(struct tcpm_port *port) +@@ -3115,15 +3115,22 @@ 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; @@ -45,7 +45,7 @@ index 111111111111..222222222222 100644 cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps); if (IS_ERR(cap)) return PTR_ERR(cap); -@@ -3134,15 +3141,22 @@ static int tcpm_register_sink_caps(struct tcpm_port *port) +@@ -3138,15 +3145,22 @@ static int tcpm_register_sink_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; @@ -72,7 +72,7 @@ index 111111111111..222222222222 100644 cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps); if (IS_ERR(cap)) return PTR_ERR(cap); -@@ -7205,10 +7219,17 @@ static int tcpm_port_register_pd(struct tcpm_port *port) +@@ -7209,10 +7223,17 @@ static int tcpm_port_register_pd(struct tcpm_port *port) port->pds[i] = usb_power_delivery_register(port->dev, &desc); if (IS_ERR(port->pds[i])) { ret = PTR_ERR(port->pds[i]); diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-tcpm-Unregister-altmodes-before-registerin.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-tcpm-Unregister-altmodes-before-registerin.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-tcpm-Unregister-altmodes-before-registerin.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-tcpm-Unregister-altmodes-before-registerin.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch b/patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3399-usbc-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch rename to patch/kernel/archive/rockchip64-6.18/rk3399-usbc-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk356x-add-rkvdec2-support.patch b/patch/kernel/archive/rockchip64-6.18/rk356x-add-rkvdec2-support.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk356x-add-rkvdec2-support.patch rename to patch/kernel/archive/rockchip64-6.18/rk356x-add-rkvdec2-support.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch b/patch/kernel/archive/rockchip64-6.18/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch similarity index 87% rename from patch/kernel/archive/rockchip64-6.17/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch rename to patch/kernel/archive/rockchip64-6.18/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch index 0dee57e9e..87b520437 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3576-0004-arch-arm64-dts-rockchip-remove-overclocked-CPU-OPP-t.patch @@ -1,17 +1,18 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jianfeng Liu Date: Wed, 1 Oct 2025 20:59:28 +0800 -Subject: arch: arm64: dts: rockchip: remove overclocked CPU OPP table on rk3576 +Subject: arch: arm64: dts: rockchip: remove overclocked CPU OPP table on + rk3576 --- - arch/arm64/boot/dts/rockchip/rk3576.dtsi | 12 ------ + arch/arm64/boot/dts/rockchip/rk3576.dtsi | 12 ---------- 1 file changed, 12 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi -@@ -269,12 +269,6 @@ opp-2016000000 { +@@ -276,12 +276,6 @@ opp-2016000000 { opp-microvolt = <900000 900000 950000>; clock-latency-ns = <40000>; }; @@ -24,7 +25,7 @@ index 111111111111..222222222222 100644 }; cluster1_opp_table: opp-table-cluster1 { -@@ -341,12 +335,6 @@ opp-2208000000 { +@@ -348,12 +342,6 @@ opp-2208000000 { opp-microvolt = <925000 925000 950000>; clock-latency-ns = <40000>; }; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-0010-fix-clk-divisions.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-0010-fix-clk-divisions.patch similarity index 98% rename from patch/kernel/archive/rockchip64-6.17/rk3588-0010-fix-clk-divisions.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-0010-fix-clk-divisions.patch index 21d5f10f0..b328fd720 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-0010-fix-clk-divisions.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-0010-fix-clk-divisions.patch @@ -88,7 +88,7 @@ index 111111111111..222222222222 100644 down = parent_rate / rate; if (flags & CLK_DIVIDER_POWER_OF_TWO) { -@@ -479,7 +479,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, +@@ -458,7 +458,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, { unsigned int div, value; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-0011-irqchip-fix-its-timeout-issue.patch.bak b/patch/kernel/archive/rockchip64-6.18/rk3588-0011-irqchip-fix-its-timeout-issue.patch.bak similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-0011-irqchip-fix-its-timeout-issue.patch.bak rename to patch/kernel/archive/rockchip64-6.18/rk3588-0011-irqchip-fix-its-timeout-issue.patch.bak diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-0025-add-missing-op-nodes.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-0025-add-missing-op-nodes.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-0025-add-missing-op-nodes.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-0025-add-missing-op-nodes.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch similarity index 83% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch index e82c84e48..507834b0d 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200.patch @@ -4,14 +4,14 @@ Date: Wed, 27 Dec 2023 15:03:57 +0800 Subject: arm64: dts: rock-5b: Slow down emmc freq and add tsadc node --- - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi | 1 + + arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi -index 973d39a7e0e0..0510d63f1b3a 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi -@@ -434,6 +434,7 @@ &sdhci { +@@ -584,6 +584,7 @@ &sdhci { no-sdio; no-sd; non-removable; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1040-board-khadas-edge2-add-nodes.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1040-board-khadas-edge2-add-nodes.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1040-board-khadas-edge2-add-nodes.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1040-board-khadas-edge2-add-nodes.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1041-board-khadas-edge2-mcu.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1041-board-khadas-edge2-mcu.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1041-board-khadas-edge2-mcu.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1041-board-khadas-edge2-mcu.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1051-board-nanopc-t6-fan-support.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1051-board-nanopc-t6-fan-support.patch similarity index 97% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1051-board-nanopc-t6-fan-support.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1051-board-nanopc-t6-fan-support.patch index 196a70a34..ff751d66b 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1051-board-nanopc-t6-fan-support.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-1051-board-nanopc-t6-fan-support.patch @@ -27,7 +27,7 @@ index 111111111111..222222222222 100644 sound { compatible = "simple-audio-card"; pinctrl-names = "default"; -@@ -580,6 +588,34 @@ &i2s6_8ch { +@@ -591,6 +599,34 @@ &i2s6_8ch { status = "okay"; }; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch similarity index 89% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch index 86f8b40c6..0f200ea88 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-1052-board-nanopc-t6-fix-usb3-a.patch @@ -12,7 +12,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boo index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -@@ -1109,6 +1109,7 @@ &u2phy0 { +@@ -1127,6 +1127,7 @@ &u2phy0 { }; &u2phy0_otg { @@ -20,7 +20,7 @@ index 111111111111..222222222222 100644 status = "okay"; }; -@@ -1185,6 +1186,7 @@ usb_host0_xhci_drd_sw: endpoint { +@@ -1203,6 +1204,7 @@ usb_host0_xhci_drd_sw: endpoint { &usb_host1_xhci { dr_mode = "host"; diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1063-arm64-dts-rockchip-Enable-automatic-fan-control-on-t.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1063-arm64-dts-rockchip-Enable-automatic-fan-control-on-t.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1063-arm64-dts-rockchip-Enable-automatic-fan-control-on-t.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1063-arm64-dts-rockchip-Enable-automatic-fan-control-on-t.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1064-arm64-dts-rockchip-Add-missing-hym8563-clock-frequen.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1064-arm64-dts-rockchip-Add-missing-hym8563-clock-frequen.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1064-arm64-dts-rockchip-Add-missing-hym8563-clock-frequen.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1064-arm64-dts-rockchip-Add-missing-hym8563-clock-frequen.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1072-arm64-dts-rockchip-add-AP6275P-wifi-to-Orange-Pi-5B.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1072-arm64-dts-rockchip-add-AP6275P-wifi-to-Orange-Pi-5B.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1072-arm64-dts-rockchip-add-AP6275P-wifi-to-Orange-Pi-5B.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1072-arm64-dts-rockchip-add-AP6275P-wifi-to-Orange-Pi-5B.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1100-arm64-dts-rockchip-opi5-max-add-2nd-hdmi.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1100-arm64-dts-rockchip-opi5-max-add-2nd-hdmi.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1100-arm64-dts-rockchip-opi5-max-add-2nd-hdmi.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1100-arm64-dts-rockchip-opi5-max-add-2nd-hdmi.patch diff --git a/patch/kernel/archive/rockchip64-6.17/rk3588-1101-arm64-dts-rockchip-opi5-max-add-hdmi-sound.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1101-arm64-dts-rockchip-opi5-max-add-hdmi-sound.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/rk3588-1101-arm64-dts-rockchip-opi5-max-add-hdmi-sound.patch rename to patch/kernel/archive/rockchip64-6.18/rk3588-1101-arm64-dts-rockchip-opi5-max-add-hdmi-sound.patch diff --git a/patch/kernel/archive/rockchip64-6.18/rk3588-1200-arm64-dts-rockchip-Enable-the-NPU-on-NanoPC-T6-LTS.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1200-arm64-dts-rockchip-Enable-the-NPU-on-NanoPC-T6-LTS.patch new file mode 100644 index 000000000..7432e8129 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-1200-arm64-dts-rockchip-Enable-the-NPU-on-NanoPC-T6-LTS.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Mon, 20 Oct 2025 21:25:02 +0200 +Subject: arm64: dts: rockchip: Enable the NPU on NanoPC T6(-LTS) + +Enable the NPU on FriendlyElec NanoPC T6/T6-LTS boards; +vdd_npu_s0 was already in place. + +Signed-off-by: Ricardo Pardini +--- + arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 35 ++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi +@@ -665,6 +665,10 @@ &pd_gpu { + domain-supply = <&vdd_gpu_s0>; + }; + ++&pd_npu { ++ domain-supply = <&vdd_npu_s0>; ++}; ++ + &pinctrl { + gpio-leds { + sys_led_pin: sys-led-pin { +@@ -742,6 +746,37 @@ &pwm1 { + status = "okay"; + }; + ++&rknn_core_0 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_core_1 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_core_2 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_mmu_0 { ++ status = "okay"; ++}; ++ ++&rknn_mmu_1 { ++ status = "okay"; ++}; ++ ++&rknn_mmu_2 { ++ status = "okay"; ++}; ++ ++ + &saradc { + vref-supply = <&avcc_1v8_s0>; + status = "okay"; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip64-6.18/rk3588-1201-arm64-dts-rockchip-Enable-the-NPU-on-CM3588.patch b/patch/kernel/archive/rockchip64-6.18/rk3588-1201-arm64-dts-rockchip-Enable-the-NPU-on-CM3588.patch new file mode 100644 index 000000000..dfba7e066 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.18/rk3588-1201-arm64-dts-rockchip-Enable-the-NPU-on-CM3588.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Mon, 20 Oct 2025 21:29:13 +0200 +Subject: arm64: dts: rockchip: Enable the NPU on CM3588 + +Enable the NPU on FriendlyElec CM3588; +vdd_npu_s0 was already in place. + +Signed-off-by: Ricardo Pardini +--- + arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi | 34 ++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi +@@ -264,6 +264,10 @@ &pd_gpu { + domain-supply = <&vdd_gpu_s0>; + }; + ++&pd_npu { ++ domain-supply = <&vdd_npu_s0>; ++}; ++ + &pinctrl { + gpio-leds { + led_sys_pin: led-sys-pin { +@@ -294,6 +298,36 @@ sd_s0_pwr: sd-s0-pwr { + }; + }; + ++&rknn_core_0 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_core_1 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_core_2 { ++ npu-supply = <&vdd_npu_s0>; ++ sram-supply = <&vdd_npu_s0>; ++ status = "okay"; ++}; ++ ++&rknn_mmu_0 { ++ status = "okay"; ++}; ++ ++&rknn_mmu_1 { ++ status = "okay"; ++}; ++ ++&rknn_mmu_2 { ++ status = "okay"; ++}; ++ + &saradc { + vref-supply = <&avcc_1v8_s0>; + status = "okay"; +-- +Armbian + diff --git a/patch/kernel/archive/rockchip64-6.17/rk35xx-montjoie-crypto-v2-rk35xx.patch b/patch/kernel/archive/rockchip64-6.18/rk35xx-montjoie-crypto-v2-rk35xx.patch similarity index 99% rename from patch/kernel/archive/rockchip64-6.17/rk35xx-montjoie-crypto-v2-rk35xx.patch rename to patch/kernel/archive/rockchip64-6.18/rk35xx-montjoie-crypto-v2-rk35xx.patch index eb3a47c12..84d4ca364 100644 --- a/patch/kernel/archive/rockchip64-6.17/rk35xx-montjoie-crypto-v2-rk35xx.patch +++ b/patch/kernel/archive/rockchip64-6.18/rk35xx-montjoie-crypto-v2-rk35xx.patch @@ -102,7 +102,7 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -2061,6 +2061,18 @@ rng@fe378000 { +@@ -2256,6 +2256,18 @@ rng@fe378000 { resets = <&scmi_reset SCMI_SRST_H_TRNG_NS>; }; @@ -345,9 +345,9 @@ diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 111111111111..222222222222 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig -@@ -720,6 +720,35 @@ config CRYPTO_DEV_TEGRA - Select this to enable Tegra Security Engine which accelerates various - AES encryption/decryption and HASH algorithms. +@@ -745,6 +745,35 @@ config CRYPTO_DEV_XILINX_TRNG + To compile this driver as a module, choose M here: the module + will be called xilinx-trng. +config CRYPTO_DEV_ROCKCHIP2 + tristate "Rockchip's cryptographic offloader V2" diff --git a/patch/kernel/archive/rockchip64-6.17/temporary-workaround-dma-reset.patch b/patch/kernel/archive/rockchip64-6.18/temporary-workaround-dma-reset.patch similarity index 60% rename from patch/kernel/archive/rockchip64-6.17/temporary-workaround-dma-reset.patch rename to patch/kernel/archive/rockchip64-6.18/temporary-workaround-dma-reset.patch index 5a7958751..24af5b543 100644 --- a/patch/kernel/archive/rockchip64-6.17/temporary-workaround-dma-reset.patch +++ b/patch/kernel/archive/rockchip64-6.18/temporary-workaround-dma-reset.patch @@ -1,14 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Wed, 20 Aug 2025 21:40:48 +0200 +Subject: [ARCHEOLOGY] workaround for rockchip gigabit ethernet not able to + init dma + Temporary patch to workaround a DMA reset issue with rockchip devices experienced at least on rk3288 and rk3328 with a message like this: rk_gmac-dwmac ff290000.ethernet end0: Failed to reset the dma +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index e0fb06af1f94..156a5d25d1fd 100644 +index 111111111111..222222222222 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3133,8 +3133,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) +@@ -3057,8 +3057,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) ret = stmmac_reset(priv, priv->ioaddr); if (ret) { @@ -19,3 +28,6 @@ index e0fb06af1f94..156a5d25d1fd 100644 } /* DMA Configuration */ +-- +Armbian + diff --git a/patch/kernel/archive/rockchip64-6.17/wifi-4003-add-bcm43342-chip.patch b/patch/kernel/archive/rockchip64-6.18/wifi-4003-add-bcm43342-chip.patch similarity index 100% rename from patch/kernel/archive/rockchip64-6.17/wifi-4003-add-bcm43342-chip.patch rename to patch/kernel/archive/rockchip64-6.18/wifi-4003-add-bcm43342-chip.patch diff --git a/patch/kernel/archive/qcs6490-6.16/0011-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch b/patch/kernel/archive/sm8250-6.12/0043-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch similarity index 80% rename from patch/kernel/archive/qcs6490-6.16/0011-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch rename to patch/kernel/archive/sm8250-6.12/0043-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch index dad2f46b2..895cbed5b 100644 --- a/patch/kernel/archive/qcs6490-6.16/0011-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch +++ b/patch/kernel/archive/sm8250-6.12/0043-dt-bindings-qcom-se-common-Add-QUP-Peripheral-specif.patch @@ -1,8 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 606555515f0395b4da4043add31fc54fb7c920a6 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya -Date: Tue, 24 Jun 2025 15:20:58 +0530 -Subject: dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties - for I2C, SPI, and SERIAL bus +Date: Thu, 11 Sep 2025 10:02:51 +0530 +Subject: [PATCH 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific + properties for I2C, SPI, and SERIAL bus Introduce a new YAML schema for QUP-supported peripherals. Define common properties used across QUP-supported peripherals. @@ -17,15 +17,18 @@ Reviewed-by: Krzysztof Kozlowski Co-developed-by: Mukesh Kumar Savaliya Signed-off-by: Mukesh Kumar Savaliya Signed-off-by: Viken Dadhaniya +Link: https://lore.kernel.org/r/20250911043256.3523057-2-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson --- - Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml | 1 + - Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml | 1 + - Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml | 26 ++++++++++ - Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml | 1 + + .../bindings/i2c/qcom,i2c-geni-qcom.yaml | 1 + + .../serial/qcom,serial-geni-qcom.yaml | 1 + + .../soc/qcom/qcom,se-common-props.yaml | 26 +++++++++++++++++++ + .../bindings/spi/qcom,spi-geni-qcom.yaml | 1 + 4 files changed, 29 insertions(+) + create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml -index 111111111111..222222222222 100644 +index 9f66a3bb1..51534953a 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml @@ -75,6 +75,7 @@ required: @@ -37,7 +40,7 @@ index 111111111111..222222222222 100644 properties: compatible: diff --git a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml -index 111111111111..222222222222 100644 +index dd33794b3..ed7b3909d 100644 --- a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml @@ -12,6 +12,7 @@ maintainers: @@ -50,7 +53,7 @@ index 111111111111..222222222222 100644 compatible: diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml new file mode 100644 -index 000000000000..111111111111 +index 000000000..6a34f05a0 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml @@ -0,0 +1,26 @@ @@ -81,7 +84,7 @@ index 000000000000..111111111111 + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml -index 111111111111..222222222222 100644 +index 2e20ca313..d12c5a060 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml @@ -25,6 +25,7 @@ description: @@ -93,5 +96,5 @@ index 111111111111..222222222222 100644 properties: compatible: -- -Armbian +2.51.1 diff --git a/patch/kernel/archive/sm8250-6.12/0044-soc-qcom-geni-se-Cleanup-register-defines-and-update.patch b/patch/kernel/archive/sm8250-6.12/0044-soc-qcom-geni-se-Cleanup-register-defines-and-update.patch new file mode 100644 index 000000000..e238f3d11 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.12/0044-soc-qcom-geni-se-Cleanup-register-defines-and-update.patch @@ -0,0 +1,106 @@ +From babd3ec5f5172902e08b801efc2cbd6cdd8e2430 Mon Sep 17 00:00:00 2001 +From: Viken Dadhaniya +Date: Thu, 11 Sep 2025 10:02:52 +0530 +Subject: [PATCH 2/5] soc: qcom: geni-se: Cleanup register defines and update + copyright + +Refactor register macros for consistency and clarity and remove redundant +definitions and update naming for better alignment. +Update copyright to include Qualcomm Technologies, Inc. + +Signed-off-by: Viken Dadhaniya +Link: https://lore.kernel.org/r/20250911043256.3523057-3-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +--- + drivers/soc/qcom/qcom-geni-se.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c +index 4cb959106..4968173e1 100644 +--- a/drivers/soc/qcom/qcom-geni-se.c ++++ b/drivers/soc/qcom/qcom-geni-se.c +@@ -1,5 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. ++/* ++ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. ++ */ + + /* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */ + #define __DISABLE_TRACE_MMIO__ +@@ -110,22 +113,20 @@ struct geni_se_desc { + static const char * const icc_path_names[] = {"qup-core", "qup-config", + "qup-memory"}; + +-#define QUP_HW_VER_REG 0x4 ++/* Common QUPV3 registers */ ++#define QUPV3_HW_VER_REG 0x4 + + /* Common SE registers */ +-#define GENI_INIT_CFG_REVISION 0x0 +-#define GENI_S_INIT_CFG_REVISION 0x4 +-#define GENI_OUTPUT_CTRL 0x24 +-#define GENI_CGC_CTRL 0x28 +-#define GENI_CLK_CTRL_RO 0x60 +-#define GENI_FW_S_REVISION_RO 0x6c ++#define SE_GENI_INIT_CFG_REVISION 0x0 ++#define SE_GENI_S_INIT_CFG_REVISION 0x4 ++#define SE_GENI_CGC_CTRL 0x28 ++#define SE_GENI_CLK_CTRL_RO 0x60 ++#define SE_GENI_FW_S_REVISION_RO 0x6c + #define SE_GENI_BYTE_GRAN 0x254 + #define SE_GENI_TX_PACKING_CFG0 0x260 + #define SE_GENI_TX_PACKING_CFG1 0x264 + #define SE_GENI_RX_PACKING_CFG0 0x284 + #define SE_GENI_RX_PACKING_CFG1 0x288 +-#define SE_GENI_M_GP_LENGTH 0x910 +-#define SE_GENI_S_GP_LENGTH 0x914 + #define SE_DMA_TX_PTR_L 0xc30 + #define SE_DMA_TX_PTR_H 0xc34 + #define SE_DMA_TX_ATTR 0xc38 +@@ -142,7 +143,6 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", + #define SE_DMA_RX_IRQ_EN 0xd48 + #define SE_DMA_RX_IRQ_EN_SET 0xd4c + #define SE_DMA_RX_IRQ_EN_CLR 0xd50 +-#define SE_DMA_RX_LEN_IN 0xd54 + #define SE_DMA_RX_MAX_BURST 0xd5c + #define SE_DMA_RX_FLUSH 0xd60 + #define SE_GSI_EVENT_EN 0xe18 +@@ -179,7 +179,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", + /* SE_DMA_GENERAL_CFG */ + #define DMA_RX_CLK_CGC_ON BIT(0) + #define DMA_TX_CLK_CGC_ON BIT(1) +-#define DMA_AHB_SLV_CFG_ON BIT(2) ++#define DMA_AHB_SLV_CLK_CGC_ON BIT(2) + #define AHB_SEC_SLV_CLK_CGC_ON BIT(3) + #define DUMMY_RX_NON_BUFFERABLE BIT(4) + #define RX_DMA_ZERO_PADDING_EN BIT(5) +@@ -196,7 +196,7 @@ u32 geni_se_get_qup_hw_version(struct geni_se *se) + { + struct geni_wrapper *wrapper = se->wrapper; + +- return readl_relaxed(wrapper->base + QUP_HW_VER_REG); ++ return readl_relaxed(wrapper->base + QUPV3_HW_VER_REG); + } + EXPORT_SYMBOL_GPL(geni_se_get_qup_hw_version); + +@@ -220,12 +220,12 @@ static void geni_se_io_init(void __iomem *base) + { + u32 val; + +- val = readl_relaxed(base + GENI_CGC_CTRL); ++ val = readl_relaxed(base + SE_GENI_CGC_CTRL); + val |= DEFAULT_CGC_EN; +- writel_relaxed(val, base + GENI_CGC_CTRL); ++ writel_relaxed(val, base + SE_GENI_CGC_CTRL); + + val = readl_relaxed(base + SE_DMA_GENERAL_CFG); +- val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON; ++ val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON; + val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; + writel_relaxed(val, base + SE_DMA_GENERAL_CFG); + +-- +2.51.1 + diff --git a/patch/kernel/archive/sm8250-6.12/0045-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch b/patch/kernel/archive/sm8250-6.12/0045-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch new file mode 100644 index 000000000..1d419fbda --- /dev/null +++ b/patch/kernel/archive/sm8250-6.12/0045-soc-qcom-geni-se-Add-support-to-load-QUP-SE-Firmware.patch @@ -0,0 +1,591 @@ +From d5b72435dcb07b2dab4e4be8459b27c71d7e267b Mon Sep 17 00:00:00 2001 +From: Viken Dadhaniya +Date: Thu, 11 Sep 2025 10:02:53 +0530 +Subject: [PATCH 3/5] soc: qcom: geni-se: Add support to load QUP SE Firmware + via Linux subsystem + +In Qualcomm SoCs, firmware loading for Serial Engines (SE) within the QUP +hardware has traditionally been managed by TrustZone (TZ). This restriction +poses a significant challenge for developers, as it limits their ability to +enable various protocols on any of the SEs from the Linux side, reducing +flexibility. + +Load the firmware to QUP SE based on the 'firmware-name' property specified +in devicetree at bootup time. + +Co-developed-by: Mukesh Kumar Savaliya +Signed-off-by: Mukesh Kumar Savaliya +Signed-off-by: Viken Dadhaniya +Link: https://lore.kernel.org/r/20250911043256.3523057-4-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +--- + drivers/soc/qcom/qcom-geni-se.c | 474 ++++++++++++++++++++++++++++++- + include/linux/soc/qcom/geni-se.h | 4 + + 2 files changed, 475 insertions(+), 3 deletions(-) + +diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c +index 4968173e1..359593c8d 100644 +--- a/drivers/soc/qcom/qcom-geni-se.c ++++ b/drivers/soc/qcom/qcom-geni-se.c +@@ -8,7 +8,9 @@ + #define __DISABLE_TRACE_MMIO__ + + #include ++#include + #include ++#include + #include + #include + #include +@@ -113,8 +115,80 @@ struct geni_se_desc { + static const char * const icc_path_names[] = {"qup-core", "qup-config", + "qup-memory"}; + ++static const char * const protocol_name[] = { "None", "SPI", "UART", "I2C", "I3C", "SPI SLAVE" }; ++ ++/** ++ * struct se_fw_hdr - Serial Engine firmware configuration header ++ * ++ * This structure defines the SE firmware header, which together with the ++ * firmware payload is stored in individual ELF segments. ++ * ++ * @magic: Set to 'SEFW'. ++ * @version: Structure version number. ++ * @core_version: QUPV3 hardware version. ++ * @serial_protocol: Encoded in GENI_FW_REVISION. ++ * @fw_version: Firmware version, from GENI_FW_REVISION. ++ * @cfg_version: Configuration version, from GENI_INIT_CFG_REVISION. ++ * @fw_size_in_items: Number of 32-bit words in GENI_FW_RAM. ++ * @fw_offset: Byte offset to GENI_FW_RAM array. ++ * @cfg_size_in_items: Number of GENI_FW_CFG index/value pairs. ++ * @cfg_idx_offset: Byte offset to GENI_FW_CFG index array. ++ * @cfg_val_offset: Byte offset to GENI_FW_CFG values array. ++ */ ++struct se_fw_hdr { ++ __le32 magic; ++ __le32 version; ++ __le32 core_version; ++ __le16 serial_protocol; ++ __le16 fw_version; ++ __le16 cfg_version; ++ __le16 fw_size_in_items; ++ __le16 fw_offset; ++ __le16 cfg_size_in_items; ++ __le16 cfg_idx_offset; ++ __le16 cfg_val_offset; ++}; ++ ++/*Magic numbers*/ ++#define SE_MAGIC_NUM 0x57464553 ++ ++#define MAX_GENI_CFG_RAMn_CNT 455 ++ ++#define MI_PBT_NON_PAGED_SEGMENT 0x0 ++#define MI_PBT_HASH_SEGMENT 0x2 ++#define MI_PBT_NOTUSED_SEGMENT 0x3 ++#define MI_PBT_SHARED_SEGMENT 0x4 ++ ++#define MI_PBT_FLAG_PAGE_MODE BIT(20) ++#define MI_PBT_FLAG_SEGMENT_TYPE GENMASK(26, 24) ++#define MI_PBT_FLAG_ACCESS_TYPE GENMASK(23, 21) ++ ++#define MI_PBT_PAGE_MODE_VALUE(x) FIELD_GET(MI_PBT_FLAG_PAGE_MODE, x) ++ ++#define MI_PBT_SEGMENT_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_SEGMENT_TYPE, x) ++ ++#define MI_PBT_ACCESS_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_ACCESS_TYPE, x) ++ ++#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \ ++ M_IO_DATA_DEASSERT_EN | \ ++ M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \ ++ M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \ ++ M_TX_FIFO_WR_ERR_EN) ++ + /* Common QUPV3 registers */ + #define QUPV3_HW_VER_REG 0x4 ++#define QUPV3_SE_AHB_M_CFG 0x118 ++#define QUPV3_COMMON_CFG 0x120 ++#define QUPV3_COMMON_CGC_CTRL 0x21c ++ ++/* QUPV3_COMMON_CFG fields */ ++#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0) ++ ++/* QUPV3_SE_AHB_M_CFG fields */ ++#define AHB_M_CLK_CGC_ON BIT(0) ++ ++/* QUPV3_COMMON_CGC_CTRL fields */ ++#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0) + + /* Common SE registers */ + #define SE_GENI_INIT_CFG_REVISION 0x0 +@@ -122,11 +196,13 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", + #define SE_GENI_CGC_CTRL 0x28 + #define SE_GENI_CLK_CTRL_RO 0x60 + #define SE_GENI_FW_S_REVISION_RO 0x6c ++#define SE_GENI_CFG_REG0 0x100 + #define SE_GENI_BYTE_GRAN 0x254 + #define SE_GENI_TX_PACKING_CFG0 0x260 + #define SE_GENI_TX_PACKING_CFG1 0x264 + #define SE_GENI_RX_PACKING_CFG0 0x284 + #define SE_GENI_RX_PACKING_CFG1 0x288 ++#define SE_GENI_S_IRQ_ENABLE 0x644 + #define SE_DMA_TX_PTR_L 0xc30 + #define SE_DMA_TX_PTR_H 0xc34 + #define SE_DMA_TX_ATTR 0xc38 +@@ -148,6 +224,15 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", + #define SE_GSI_EVENT_EN 0xe18 + #define SE_IRQ_EN 0xe1c + #define SE_DMA_GENERAL_CFG 0xe30 ++#define SE_GENI_FW_REVISION 0x1000 ++#define SE_GENI_S_FW_REVISION 0x1004 ++#define SE_GENI_CFG_RAMN 0x1010 ++#define SE_GENI_CLK_CTRL 0x2000 ++#define SE_DMA_IF_EN 0x2004 ++#define SE_FIFO_IF_DISABLE 0x2008 ++ ++/* GENI_FW_REVISION_RO fields */ ++#define FW_REV_VERSION_MSK GENMASK(7, 0) + + /* GENI_OUTPUT_CTRL fields */ + #define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0) +@@ -186,6 +271,15 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", + #define RX_DMA_IRQ_DELAY_MSK GENMASK(8, 6) + #define RX_DMA_IRQ_DELAY_SHFT 6 + ++/* GENI_CLK_CTRL fields */ ++#define SER_CLK_SEL BIT(0) ++ ++/* GENI_DMA_IF_EN fields */ ++#define DMA_IF_EN BIT(0) ++ ++#define geni_setbits32(_addr, _v) writel(readl(_addr) | (_v), _addr) ++#define geni_clrbits32(_addr, _v) writel(readl(_addr) & ~(_v), _addr) ++ + /** + * geni_se_get_qup_hw_version() - Read the QUP wrapper Hardware version + * @se: Pointer to the corresponding serial engine. +@@ -658,9 +752,12 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq, + } + EXPORT_SYMBOL_GPL(geni_se_clk_freq_match); + +-#define GENI_SE_DMA_DONE_EN BIT(0) +-#define GENI_SE_DMA_EOT_EN BIT(1) +-#define GENI_SE_DMA_AHB_ERR_EN BIT(2) ++#define GENI_SE_DMA_DONE_EN BIT(0) ++#define GENI_SE_DMA_EOT_EN BIT(1) ++#define GENI_SE_DMA_AHB_ERR_EN BIT(2) ++#define GENI_SE_DMA_RESET_DONE_EN BIT(3) ++#define GENI_SE_DMA_FLUSH_DONE BIT(4) ++ + #define GENI_SE_DMA_EOT_BUF BIT(0) + + /** +@@ -891,6 +988,377 @@ int geni_icc_disable(struct geni_se *se) + } + EXPORT_SYMBOL_GPL(geni_icc_disable); + ++/** ++ * geni_find_protocol_fw() - Locate and validate SE firmware for a protocol. ++ * @dev: Pointer to the device structure. ++ * @fw: Pointer to the firmware image. ++ * @protocol: Expected serial engine protocol type. ++ * ++ * Identifies the appropriate firmware image or configuration required for a ++ * specific communication protocol instance running on a Qualcomm GENI ++ * controller. ++ * ++ * Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise. ++ */ ++static struct se_fw_hdr *geni_find_protocol_fw(struct device *dev, const struct firmware *fw, ++ enum geni_se_protocol_type protocol) ++{ ++ const struct elf32_hdr *ehdr; ++ const struct elf32_phdr *phdrs; ++ const struct elf32_phdr *phdr; ++ struct se_fw_hdr *sefw; ++ u32 fw_end, cfg_idx_end, cfg_val_end; ++ u16 fw_size; ++ int i; ++ ++ if (!fw || fw->size < sizeof(struct elf32_hdr)) ++ return NULL; ++ ++ ehdr = (const struct elf32_hdr *)fw->data; ++ phdrs = (const struct elf32_phdr *)(fw->data + ehdr->e_phoff); ++ ++ /* ++ * The firmware is expected to have at least two program headers (segments). ++ * One for metadata and the other for the actual protocol-specific firmware. ++ */ ++ if (ehdr->e_phnum < 2) { ++ dev_err(dev, "Invalid firmware: less than 2 program headers\n"); ++ return NULL; ++ } ++ ++ for (i = 0; i < ehdr->e_phnum; i++) { ++ phdr = &phdrs[i]; ++ ++ if (fw->size < phdr->p_offset + phdr->p_filesz) { ++ dev_err(dev, "Firmware size (%zu) < expected offset (%u) + size (%u)\n", ++ fw->size, phdr->p_offset, phdr->p_filesz); ++ return NULL; ++ } ++ ++ if (phdr->p_type != PT_LOAD || !phdr->p_memsz) ++ continue; ++ ++ if (MI_PBT_PAGE_MODE_VALUE(phdr->p_flags) != MI_PBT_NON_PAGED_SEGMENT || ++ MI_PBT_SEGMENT_TYPE_VALUE(phdr->p_flags) == MI_PBT_HASH_SEGMENT || ++ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_NOTUSED_SEGMENT || ++ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_SHARED_SEGMENT) ++ continue; ++ ++ if (phdr->p_filesz < sizeof(struct se_fw_hdr)) ++ continue; ++ ++ sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset); ++ fw_size = le16_to_cpu(sefw->fw_size_in_items); ++ fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32); ++ cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) + ++ le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8); ++ cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) + ++ le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32); ++ ++ if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1) ++ continue; ++ ++ if (le32_to_cpu(sefw->serial_protocol) != protocol) ++ continue; ++ ++ if (fw_size % 2 != 0) { ++ fw_size++; ++ sefw->fw_size_in_items = cpu_to_le16(fw_size); ++ } ++ ++ if (fw_size >= MAX_GENI_CFG_RAMn_CNT) { ++ dev_err(dev, ++ "Firmware size (%u) exceeds max allowed RAMn count (%u)\n", ++ fw_size, MAX_GENI_CFG_RAMn_CNT); ++ continue; ++ } ++ ++ if (fw_end > phdr->p_filesz || cfg_idx_end > phdr->p_filesz || ++ cfg_val_end > phdr->p_filesz) { ++ dev_err(dev, "Truncated or corrupt SE FW segment found at index %d\n", i); ++ continue; ++ } ++ ++ return sefw; ++ } ++ ++ dev_err(dev, "Failed to get %s protocol firmware\n", protocol_name[protocol]); ++ return NULL; ++} ++ ++/** ++ * geni_configure_xfer_mode() - Set the transfer mode. ++ * @se: Pointer to the concerned serial engine. ++ * @mode: SE data transfer mode. ++ * ++ * Set the transfer mode to either FIFO or DMA according to the mode specified ++ * by the protocol driver. ++ * ++ * Return: 0 if successful, otherwise return an error value. ++ */ ++static int geni_configure_xfer_mode(struct geni_se *se, enum geni_se_xfer_mode mode) ++{ ++ /* Configure SE FIFO, DMA or GSI mode. */ ++ switch (mode) { ++ case GENI_GPI_DMA: ++ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); ++ writel(0x0, se->base + SE_IRQ_EN); ++ writel(DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | GENI_M_EVENT_EN | GENI_S_EVENT_EN, ++ se->base + SE_GSI_EVENT_EN); ++ break; ++ ++ case GENI_SE_FIFO: ++ geni_clrbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); ++ writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, ++ se->base + SE_IRQ_EN); ++ writel(0x0, se->base + SE_GSI_EVENT_EN); ++ break; ++ ++ case GENI_SE_DMA: ++ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); ++ writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, ++ se->base + SE_IRQ_EN); ++ writel(0x0, se->base + SE_GSI_EVENT_EN); ++ break; ++ ++ default: ++ dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", mode); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++/** ++ * geni_enable_interrupts() - Enable interrupts. ++ * @se: Pointer to the concerned serial engine. ++ * ++ * Enable the required interrupts during the firmware load process. ++ */ ++static void geni_enable_interrupts(struct geni_se *se) ++{ ++ u32 val; ++ ++ /* Enable required interrupts. */ ++ writel(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN); ++ ++ val = S_CMD_OVERRUN_EN | S_ILLEGAL_CMD_EN | S_CMD_CANCEL_EN | S_CMD_ABORT_EN | ++ S_GP_IRQ_0_EN | S_GP_IRQ_1_EN | S_GP_IRQ_2_EN | S_GP_IRQ_3_EN | ++ S_RX_FIFO_WR_ERR_EN | S_RX_FIFO_RD_ERR_EN; ++ writel(val, se->base + SE_GENI_S_IRQ_ENABLE); ++ ++ /* DMA mode configuration. */ ++ val = GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN | GENI_SE_DMA_DONE_EN; ++ writel(val, se->base + SE_DMA_TX_IRQ_EN_SET); ++ val = GENI_SE_DMA_FLUSH_DONE | GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN | ++ GENI_SE_DMA_DONE_EN; ++ writel(val, se->base + SE_DMA_RX_IRQ_EN_SET); ++} ++ ++/** ++ * geni_write_fw_revision() - Write the firmware revision. ++ * @se: Pointer to the concerned serial engine. ++ * @serial_protocol: serial protocol type. ++ * @fw_version: QUP firmware version. ++ * ++ * Write the firmware revision and protocol into the respective register. ++ */ ++static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version) ++{ ++ u32 reg; ++ ++ reg = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol); ++ reg |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version); ++ ++ writel(reg, se->base + SE_GENI_FW_REVISION); ++ writel(reg, se->base + SE_GENI_S_FW_REVISION); ++} ++ ++/** ++ * geni_load_se_fw() - Load Serial Engine specific firmware. ++ * @se: Pointer to the concerned serial engine. ++ * @fw: Pointer to the firmware structure. ++ * @mode: SE data transfer mode. ++ * @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C). ++ * ++ * Load the protocol firmware into the IRAM of the Serial Engine. ++ * ++ * Return: 0 if successful, otherwise return an error value. ++ */ ++static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw, ++ enum geni_se_xfer_mode mode, enum geni_se_protocol_type protocol) ++{ ++ const u32 *fw_data, *cfg_val_arr; ++ const u8 *cfg_idx_arr; ++ u32 i, reg_value; ++ int ret; ++ struct se_fw_hdr *hdr; ++ ++ hdr = geni_find_protocol_fw(se->dev, fw, protocol); ++ if (!hdr) ++ return -EINVAL; ++ ++ fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset)); ++ cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset); ++ cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset)); ++ ++ ret = geni_icc_set_bw(se); ++ if (ret) ++ return ret; ++ ++ ret = geni_icc_enable(se); ++ if (ret) ++ return ret; ++ ++ ret = geni_se_resources_on(se); ++ if (ret) ++ goto out_icc_disable; ++ ++ /* ++ * Disable high-priority interrupts until all currently executing ++ * low-priority interrupts have been fully handled. ++ */ ++ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE); ++ ++ /* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */ ++ geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON); ++ ++ /* Let hardware to control common cgc. */ ++ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON); ++ ++ /* ++ * Setting individual bits in GENI_OUTPUT_CTRL activates corresponding output lines, ++ * allowing the hardware to drive data as configured. ++ */ ++ writel(0x0, se->base + GENI_OUTPUT_CTRL); ++ ++ /* Set SCLK and HCLK to program RAM */ ++ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); ++ writel(0x0, se->base + SE_GENI_CLK_CTRL); ++ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); ++ ++ /* Enable required clocks for DMA CSR, TX and RX. */ ++ reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON | ++ DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; ++ geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value); ++ ++ /* Let hardware control CGC by default. */ ++ writel(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL); ++ ++ /* Set version of the configuration register part of firmware. */ ++ writel(le16_to_cpu(hdr->cfg_version), se->base + SE_GENI_INIT_CFG_REVISION); ++ writel(le16_to_cpu(hdr->cfg_version), se->base + SE_GENI_S_INIT_CFG_REVISION); ++ ++ /* Configure GENI primitive table. */ ++ for (i = 0; i < le16_to_cpu(hdr->cfg_size_in_items); i++) ++ writel(cfg_val_arr[i], ++ se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32))); ++ ++ /* Configure condition for assertion of RX_RFR_WATERMARK condition. */ ++ reg_value = geni_se_get_rx_fifo_depth(se); ++ writel(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG); ++ ++ /* Let hardware control CGC */ ++ geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK); ++ ++ ret = geni_configure_xfer_mode(se, mode); ++ if (ret) ++ goto out_resources_off; ++ ++ geni_enable_interrupts(se); ++ ++ geni_write_fw_revision(se, le16_to_cpu(hdr->serial_protocol), le16_to_cpu(hdr->fw_version)); ++ ++ /* Program RAM address space. */ ++ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, ++ le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32)); ++ ++ /* Put default values on GENI's output pads. */ ++ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG); ++ ++ /* Toggle SCLK/HCLK from high to low to finalize RAM programming and apply config. */ ++ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); ++ geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL); ++ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); ++ ++ /* Serial engine DMA interface is enabled. */ ++ geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN); ++ ++ /* Enable or disable FIFO interface of the serial engine. */ ++ if (mode == GENI_SE_FIFO) ++ geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); ++ else ++ geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); ++ ++out_resources_off: ++ geni_se_resources_off(se); ++ ++out_icc_disable: ++ geni_icc_disable(se); ++ return ret; ++} ++ ++/** ++ * geni_load_se_firmware() - Load firmware for SE based on protocol ++ * @se: Pointer to the concerned serial engine. ++ * @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C). ++ * ++ * Retrieves the firmware name from device properties and sets the transfer mode ++ * (FIFO or GSI DMA) based on device tree configuration. Enforces FIFO mode for ++ * UART protocol due to lack of GSI DMA support. Requests the firmware and loads ++ * it into the SE. ++ * ++ * Return: 0 on success, negative error code on failure. ++ */ ++int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol) ++{ ++ const char *fw_name; ++ const struct firmware *fw; ++ enum geni_se_xfer_mode mode = GENI_SE_FIFO; ++ int ret; ++ ++ if (protocol >= ARRAY_SIZE(protocol_name)) { ++ dev_err(se->dev, "Invalid geni-se protocol: %d", protocol); ++ return -EINVAL; ++ } ++ ++ ret = device_property_read_string(se->wrapper->dev, "firmware-name", &fw_name); ++ if (ret) { ++ dev_err(se->dev, "Failed to read firmware-name property: %d\n", ret); ++ return -EINVAL; ++ } ++ ++ if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma")) ++ mode = GENI_GPI_DMA; ++ ++ /* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */ ++ if (protocol == GENI_SE_UART) ++ mode = GENI_SE_FIFO; ++ ++ ret = request_firmware(&fw, fw_name, se->dev); ++ if (ret) { ++ if (ret == -ENOENT) ++ return -EPROBE_DEFER; ++ ++ dev_err(se->dev, "Failed to request firmware '%s' for protocol %d: ret: %d\n", ++ fw_name, protocol, ret); ++ return ret; ++ } ++ ++ ret = geni_load_se_fw(se, fw, mode, protocol); ++ release_firmware(fw); ++ ++ if (ret) { ++ dev_err(se->dev, "Failed to load SE firmware for protocol %d: ret: %d\n", ++ protocol, ret); ++ return ret; ++ } ++ ++ dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode: %d\n", ++ protocol_name[protocol], mode); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(geni_load_se_firmware); ++ + static int geni_se_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h +index 2996a3c28..0a984e257 100644 +--- a/include/linux/soc/qcom/geni-se.h ++++ b/include/linux/soc/qcom/geni-se.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #ifndef _LINUX_QCOM_GENI_SE +@@ -36,6 +37,7 @@ enum geni_se_protocol_type { + GENI_SE_I2C, + GENI_SE_I3C, + GENI_SE_SPI_SLAVE, ++ GENI_SE_INVALID_PROTO = 255, + }; + + struct geni_wrapper; +@@ -531,5 +533,7 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag); + int geni_icc_enable(struct geni_se *se); + + int geni_icc_disable(struct geni_se *se); ++ ++int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol); + #endif + #endif +-- +2.51.1 + diff --git a/patch/kernel/archive/qcs6490-6.16/0013-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch b/patch/kernel/archive/sm8250-6.12/0046-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch similarity index 55% rename from patch/kernel/archive/qcs6490-6.16/0013-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch rename to patch/kernel/archive/sm8250-6.12/0046-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch index 4c1c38c85..5d9e3ef68 100644 --- a/patch/kernel/archive/qcs6490-6.16/0013-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch +++ b/patch/kernel/archive/sm8250-6.12/0046-i2c-qcom-geni-Load-i2c-qup-Firmware-from-linux-side.patch @@ -1,25 +1,27 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 6b62f495aa3d5e6c17b61bc27f2f8673b4e4c829 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya -Date: Tue, 24 Jun 2025 15:21:00 +0530 -Subject: i2c: qcom-geni: Load i2c qup Firmware from linux side +Date: Thu, 11 Sep 2025 10:02:54 +0530 +Subject: [PATCH 4/5] i2c: qcom-geni: Load i2c qup Firmware from linux side Add provision to load firmware of Serial engine for I2C protocol from Linux Execution Environment on running on APPS processor. +Acked-by: Andi Shyti Co-developed-by: Mukesh Kumar Savaliya Signed-off-by: Mukesh Kumar Savaliya Signed-off-by: Viken Dadhaniya -Acked-by: Andi Shyti +Link: https://lore.kernel.org/r/20250911043256.3523057-5-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson --- - drivers/i2c/busses/i2c-qcom-geni.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) + drivers/i2c/busses/i2c-qcom-geni.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index 111111111111..222222222222 100644 +index 212336f72..f307aa2ac 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -870,7 +870,13 @@ static int geni_i2c_probe(struct platform_device *pdev) - goto err_clk; +@@ -858,7 +858,15 @@ static int geni_i2c_probe(struct platform_device *pdev) + return ret; } proto = geni_se_read_proto(&gi2c->se); - if (proto != GENI_SE_I2C) { @@ -27,12 +29,14 @@ index 111111111111..222222222222 100644 + ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C); + if (ret) { + dev_err_probe(dev, ret, "i2c firmware load failed ret: %d\n", ret); -+ goto err_resources; ++ geni_se_resources_off(&gi2c->se); ++ clk_disable_unprepare(gi2c->core_clk); ++ return ret; + } + } else if (proto != GENI_SE_I2C) { - ret = dev_err_probe(dev, -ENXIO, "Invalid proto %d\n", proto); - goto err_resources; - } + dev_err(dev, "Invalid proto %d\n", proto); + geni_se_resources_off(&gi2c->se); + clk_disable_unprepare(gi2c->core_clk); -- -Armbian +2.51.1 diff --git a/patch/kernel/archive/qcs6490-6.16/0014-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch b/patch/kernel/archive/sm8250-6.12/0047-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch similarity index 72% rename from patch/kernel/archive/qcs6490-6.16/0014-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch rename to patch/kernel/archive/sm8250-6.12/0047-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch index 03957fd8d..a39a9e5c9 100644 --- a/patch/kernel/archive/qcs6490-6.16/0014-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch +++ b/patch/kernel/archive/sm8250-6.12/0047-spi-geni-qcom-Load-spi-qup-Firmware-from-linux-side.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From effd812be82787c08b63254bff71f11bb1b01b55 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya -Date: Tue, 24 Jun 2025 15:21:01 +0530 -Subject: spi: geni-qcom: Load spi qup Firmware from linux side +Date: Thu, 11 Sep 2025 10:02:55 +0530 +Subject: [PATCH 5/5] spi: geni-qcom: Load spi qup Firmware from linux side Add provision to load firmware of Serial engine for SPI protocol from Linux Execution Environment on running on APPS processor. @@ -9,12 +9,15 @@ Linux Execution Environment on running on APPS processor. Co-developed-by: Mukesh Kumar Savaliya Signed-off-by: Mukesh Kumar Savaliya Signed-off-by: Viken Dadhaniya +Acked-by: Mark Brown +Link: https://lore.kernel.org/r/20250911043256.3523057-6-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson --- drivers/spi/spi-geni-qcom.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c -index 111111111111..222222222222 100644 +index 768d74821..a0d8d3425 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -671,6 +671,12 @@ static int spi_geni_init(struct spi_geni_master *mas) @@ -31,5 +34,5 @@ index 111111111111..222222222222 100644 dev_err(mas->dev, "Invalid proto %d\n", proto); goto out_pm; -- -Armbian +2.51.1 diff --git a/patch/kernel/archive/qcs6490-6.16/0015-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch b/patch/kernel/archive/sm8250-6.12/0048-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch similarity index 72% rename from patch/kernel/archive/qcs6490-6.16/0015-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch rename to patch/kernel/archive/sm8250-6.12/0048-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch index d6d5fe487..c45eab1c6 100644 --- a/patch/kernel/archive/qcs6490-6.16/0015-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch +++ b/patch/kernel/archive/sm8250-6.12/0048-serial-qcom-geni-Load-UART-qup-Firmware-from-linux-s.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From d00c7f54a14f2d1557dc1213f9d11eea1e33dcec Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya -Date: Tue, 24 Jun 2025 15:21:02 +0530 -Subject: serial: qcom-geni: Load UART qup Firmware from linux side +Date: Thu, 11 Sep 2025 10:02:56 +0530 +Subject: [PATCH] serial: qcom-geni: Load UART qup Firmware from linux side Add provision to load firmware of Serial engine for UART protocol from Linux Execution Environment on running on APPS processor. @@ -9,15 +9,17 @@ Linux Execution Environment on running on APPS processor. Co-developed-by: Mukesh Kumar Savaliya Signed-off-by: Mukesh Kumar Savaliya Signed-off-by: Viken Dadhaniya +Link: https://lore.kernel.org/r/20250911043256.3523057-7-viken.dadhaniya@oss.qualcomm.com +Signed-off-by: Bjorn Andersson --- drivers/tty/serial/qcom_geni_serial.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c -index 111111111111..222222222222 100644 +index 5dfe4e599..e7e1291e0 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c -@@ -1161,7 +1161,13 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) +@@ -1145,7 +1145,13 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) int ret; proto = geni_se_read_proto(&port->se); @@ -33,5 +35,5 @@ index 111111111111..222222222222 100644 return -ENXIO; } -- -Armbian +2.51.1 diff --git a/patch/kernel/archive/sm8550-6.12/0042_mmc--sdhci-msm--Enable-tuning-for-SDR50-mode-for-S.patch b/patch/kernel/archive/sm8550-6.12/0042_mmc--sdhci-msm--Enable-tuning-for-SDR50-mode-for-S.patch deleted file mode 100644 index 212584b5b..000000000 --- a/patch/kernel/archive/sm8550-6.12/0042_mmc--sdhci-msm--Enable-tuning-for-SDR50-mode-for-S.patch +++ /dev/null @@ -1,67 +0,0 @@ -From a655571f7eac983ad53b3f30f75270fb81aadb88 Mon Sep 17 00:00:00 2001 -From: Sarthak Garg -Date: Thu, 7 Nov 2024 13:35:04 +0530 -Subject: [PATCH] mmc: sdhci-msm: Enable tuning for SDR50 mode for SD card - -For Qualcomm SoCs which needs level shifter for SD card, extra delay is -seen on receiver data path. - -To compensate this delay enable tuning for SDR50 mode for targets which -has level shifter. - -Signed-off-by: Sarthak Garg ---- - drivers/mmc/host/sdhci-msm.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c -index 1fcaaf683d68..a6c9e9b60812 100644 ---- a/drivers/mmc/host/sdhci-msm.c -+++ b/drivers/mmc/host/sdhci-msm.c -@@ -81,6 +81,7 @@ - #define CORE_IO_PAD_PWR_SWITCH_EN BIT(15) - #define CORE_IO_PAD_PWR_SWITCH BIT(16) - #define CORE_HC_SELECT_IN_EN BIT(18) -+#define CORE_HC_SELECT_IN_SDR50 (4 << 19) - #define CORE_HC_SELECT_IN_HS400 (6 << 19) - #define CORE_HC_SELECT_IN_MASK (7 << 19) - -@@ -1133,6 +1134,10 @@ static bool sdhci_msm_is_tuning_needed(struct sdhci_host *host) - { - struct mmc_ios *ios = &host->mmc->ios; - -+ if (ios->timing == MMC_TIMING_UHS_SDR50 && -+ host->flags & SDHCI_SDR50_NEEDS_TUNING) -+ return true; -+ - /* - * Tuning is required for SDR104, HS200 and HS400 cards and - * if clock frequency is greater than 100MHz in these modes. -@@ -1201,6 +1206,8 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) - struct mmc_ios ios = host->mmc->ios; - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); -+ const struct sdhci_msm_offset *msm_offset = msm_host->offset; -+ u32 config; - - if (!sdhci_msm_is_tuning_needed(host)) { - msm_host->use_cdr = false; -@@ -1217,6 +1224,15 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) - */ - msm_host->tuning_done = 0; - -+ if (ios.timing == MMC_TIMING_UHS_SDR50 && -+ host->flags & SDHCI_SDR50_NEEDS_TUNING) { -+ config = readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec); -+ config |= CORE_HC_SELECT_IN_EN; -+ config &= ~CORE_HC_SELECT_IN_MASK; -+ config |= CORE_HC_SELECT_IN_SDR50; -+ writel_relaxed(config, host->ioaddr + msm_offset->core_vendor_spec); -+ } -+ - /* - * For HS400 tuning in HS200 timing requires: - * - select MCLK/2 in VENDOR_SPEC --- -2.34.1 - diff --git a/patch/kernel/archive/spacemit-6.17/0000.patching_config.yaml b/patch/kernel/archive/spacemit-6.17/0000.patching_config.yaml new file mode 100644 index 000000000..ac1da4ec6 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/0000.patching_config.yaml @@ -0,0 +1,45 @@ +config: # This is file 'patch/kernel/spacemit-legacy-6.1/0000.patching_config.yaml' + + # PATCH NUMBERING INFO + # + # Patches should be ordered in such a way that general kernel patches are applied first, then SoC-related patches and at last board-specific patches + # + # Patch numbers in this folder are sorted by category: + # + # 000* for general patches + # 0** for Bianbu-Linux-related patches + # 1** for other SoC-related patches + # 5** for board specific patches + + # Just some info stuff; not used by the patching scripts + name: spacemit-6.16 + kind: kernel + type: vendor # or: edge + branch: linux-6.16.y + last-known-good-tag: v6.16 + maintainers: + - { github: none, name: none, email: none, armbian-forum: none } + + # .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones. + # This is meant to provide a way to "add a board DTS" without having to null-patch them in. + dts-directories: + - { source: "dt", target: "arch/riscv/boot/dts/spacemit" } + + # Every file in these directories will be copied as-is to the build tree; later ones overwrite earlier ones + # This is meant as a way to have overlays, bare, in a directory, without having to null-patch them in. + # @TODO need a solution to auto-Makefile the overlays as well + overlay-directories: + - { source: "overlay", target: "arch/riscv/boot/dts/spacemit/overlay" } + + # The Makefile in each of these directories will be magically patched to include the dts files copied + # or patched-in; overlay subdir will be included "-y" if it exists. + # No more Makefile patching needed, yay! + #auto-patch-dt-makefile: + # - { directory: "arch/riscv/boot/dts/spacemit", config-var: "CONFIG_SOC_SPACEMIT_K1X" } + + # Configuration for when applying patches to git / auto-rewriting patches (development cycle helpers) + patches-to-git: + do-not-commit-files: + - "MAINTAINERS" # constant churn, drop them. sorry. + do-not-commit-regexes: # Python-style regexes + - "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now diff --git a/patch/kernel/archive/spacemit-6.17/001-rtl8852bs-Turn-off-DEBUG-and-remove-RTW_WARN_LM.patch b/patch/kernel/archive/spacemit-6.17/001-rtl8852bs-Turn-off-DEBUG-and-remove-RTW_WARN_LM.patch new file mode 100644 index 000000000..c430d4e8d --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/001-rtl8852bs-Turn-off-DEBUG-and-remove-RTW_WARN_LM.patch @@ -0,0 +1,40 @@ +From 5e370980eaf7c4f6aa64bb27e755e57b9220212d Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Mon, 20 Oct 2025 08:07:16 -0400 +Subject: [PATCH] rtl8852bs: Turn off DEBUG and remove RTW_WARN_LM + +Signed-off-by: Patrick Yavitz +--- + drivers/net/wireless/realtek/rtl8852bs/Makefile | 2 +- + drivers/net/wireless/realtek/rtl8852bs/core/rtw_xmit.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8852bs/Makefile b/drivers/net/wireless/realtek/rtl8852bs/Makefile +index bdaf0097d..c2f8aeca9 100644 +--- a/drivers/net/wireless/realtek/rtl8852bs/Makefile ++++ b/drivers/net/wireless/realtek/rtl8852bs/Makefile +@@ -142,7 +142,7 @@ ccflags-y += -DCONFIG_RTW_ANDROID=$(CONFIG_RTW_ANDROID) + endif + + ########################## Debug ########################### +-CONFIG_RTW_DEBUG = y ++CONFIG_RTW_DEBUG = n + # default log level is _DRV_INFO_ = 4, + # please refer to "How_to_set_driver_debug_log_level.doc" to set the available level. + CONFIG_RTW_LOG_LEVEL = 2 +diff --git a/drivers/net/wireless/realtek/rtl8852bs/core/rtw_xmit.c b/drivers/net/wireless/realtek/rtl8852bs/core/rtw_xmit.c +index 5d41dc48f..dab9ac8ce 100644 +--- a/drivers/net/wireless/realtek/rtl8852bs/core/rtw_xmit.c ++++ b/drivers/net/wireless/realtek/rtl8852bs/core/rtw_xmit.c +@@ -6681,7 +6681,7 @@ static void fill_txreq_list_skb(_adapter *padapter, + + if (skb_total_frag_nr(head_skb) > NUM_PKT_LIST_PER_TXREQ - 2) { + rtw_skb_linearize(head_skb); +- RTW_WARN_LMT("skb total frag nr over %d\n", NUM_PKT_LIST_PER_TXREQ - 2); ++ //RTW_WARN_LMT("skb total frag nr over %d\n", NUM_PKT_LIST_PER_TXREQ - 2); + } + + _fill_txreq_list_skb(padapter, txreq, pkt_list, head_skb, &req_sz, &offset); +-- +2.43.0 + diff --git a/patch/kernel/archive/spacemit-6.17/002-Max-freq-limitation-1.8GHz.patch b/patch/kernel/archive/spacemit-6.17/002-Max-freq-limitation-1.8GHz.patch new file mode 100644 index 000000000..ed85b07c5 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/002-Max-freq-limitation-1.8GHz.patch @@ -0,0 +1,58 @@ +From 1abbdfc943e3bf7f1827c8bb092410342a5940ad Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Mon, 20 Oct 2025 08:08:50 -0400 +Subject: [PATCH] Max freq limitation 1.8GHz + +Signed-off-by: Patrick Yavitz +--- + drivers/cpufreq/spacemit-cpufreq.c | 20 ++++---------------- + 1 file changed, 4 insertions(+), 16 deletions(-) + +diff --git a/drivers/cpufreq/spacemit-cpufreq.c b/drivers/cpufreq/spacemit-cpufreq.c +index 7b4df5fb7..69a712d36 100644 +--- a/drivers/cpufreq/spacemit-cpufreq.c ++++ b/drivers/cpufreq/spacemit-cpufreq.c +@@ -51,7 +51,7 @@ of_hotplug_cooling_register(struct cpufreq_policy *policy); + #define FILTER_POINTS_0 (135) + #define FILTER_POINTS_1 (142) + +-#define K1_MAX_FREQ_LIMITATION (1600000) ++#define K1_MAX_FREQ_LIMITATION (1800000) + #define M1_MAX_FREQ_LIMITATION (1800000) + + #endif +@@ -429,18 +429,8 @@ int spacmeit_cpufreq_veritfy(struct cpufreq_policy_data *policy) + if (!policy->freq_table) + return -ENODEV; + +- if ((wafer_prop << 16 | product_prop) == PRODUCT_ID_M1) { +- /* M1 */ +- /* can update to 1.8G */ +- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, +- policy->cpuinfo.max_freq); +- } else { +- /* K1 */ +- /* only 1.6G allowed max */ +- policy->max = policy->max > K1_MAX_FREQ_LIMITATION ? K1_MAX_FREQ_LIMITATION : policy->max; +- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, +- K1_MAX_FREQ_LIMITATION); +- } ++ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, ++ policy->cpuinfo.max_freq); + + cpufreq_for_each_valid_entry(pos, policy->freq_table) { + freq = pos->frequency; +@@ -469,9 +459,7 @@ void spacemit_cpufreq_ready(struct cpufreq_policy *policy) + if ((wafer_prop << 16 | product_prop) == PRODUCT_ID_M1) { + /* M1 */ + } else { +- /* K1 or other */ +- remove_policy_boost_sysfs_file(policy); +- remove_boost_sysfs_file(); ++ /* K1 */ + } + } + +-- +2.43.0 + diff --git a/patch/kernel/archive/spacemit-6.17/003-Add-spacemit-k1x-spi-support.patch b/patch/kernel/archive/spacemit-6.17/003-Add-spacemit-k1x-spi-support.patch new file mode 100644 index 000000000..1eec543d8 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/003-Add-spacemit-k1x-spi-support.patch @@ -0,0 +1,33 @@ +From 7ab21f462be1275af4552df2bd3e87607fab1957 Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Mon, 20 Oct 2025 08:09:31 -0400 +Subject: [PATCH] Add spacemit k1x-spi support + +Signed-off-by: Patrick Yavitz +--- + drivers/spi/spidev.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index 5300c942a..6375c5cf9 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -718,6 +718,7 @@ static const struct spi_device_id spidev_spi_ids[] = { + { .name = /* semtech */ "sx1301" }, + { .name = /* silabs */ "em3581" }, + { .name = /* silabs */ "si3210" }, ++ { .name = /* spacemit */ "k1x-spi" }, + {}, + }; + MODULE_DEVICE_TABLE(spi, spidev_spi_ids); +@@ -751,6 +752,7 @@ static const struct of_device_id spidev_dt_ids[] = { + { .compatible = "semtech,sx1301", .data = &spidev_of_check }, + { .compatible = "silabs,em3581", .data = &spidev_of_check }, + { .compatible = "silabs,si3210", .data = &spidev_of_check }, ++ { .compatible = "spacemit,k1x-spi", .data = &spidev_of_check }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); +-- +2.43.0 + diff --git a/patch/kernel/archive/spacemit-6.17/004-SpacemiT-K1-X-Forward-port-6.6.y-DTSI.patch b/patch/kernel/archive/spacemit-6.17/004-SpacemiT-K1-X-Forward-port-6.6.y-DTSI.patch new file mode 100644 index 000000000..636612e78 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/004-SpacemiT-K1-X-Forward-port-6.6.y-DTSI.patch @@ -0,0 +1,158 @@ +From e2ac8e7fddb7ca0a18a7466bf2dc37547ec72d30 Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Fri, 3 Oct 2025 15:54:47 -0400 +Subject: [PATCH] SpacemiT: K1-X: Forward port 6.6.y DTSI + +Signed-off-by: Patrick Yavitz +--- + arch/riscv/boot/dts/spacemit/k1-x.dtsi | 66 ++++++++++++++++++++++---- + 1 file changed, 58 insertions(+), 8 deletions(-) + +diff --git a/arch/riscv/boot/dts/spacemit/k1-x.dtsi b/arch/riscv/boot/dts/spacemit/k1-x.dtsi +index 8f411e7f01f3..24366372e064 100644 +--- a/arch/riscv/boot/dts/spacemit/k1-x.dtsi ++++ b/arch/riscv/boot/dts/spacemit/k1-x.dtsi +@@ -430,7 +430,7 @@ rcpu_mem_0: mem@c0800000 { + }; + + /* rcpu's heap */ +- rcpu_mem_1: mem@30000000 { ++ rcpu_mem_heap: rcpu_mem_heap@30000000 { + reg = <0x0 0x30000000 0x0 0x200000>; + no-map; + }; +@@ -465,6 +465,12 @@ rcpu_mem_snapshots: rcpu_mem_snapshots@30300000 { + reg = <0x0 0x30300000 0x0 0x40000>; + no-map; + }; ++ ++ /* the dtb file of rcpu */ ++ rcpu_mem_dtb: rcpu_mem_dtb@30300000 { ++ reg = <0x0 0x30340000 0x0 0x40000>; ++ no-map; ++ }; + }; + + soc: soc { +@@ -495,13 +501,13 @@ dram_range1: dram_range@1 { + status = "okay"; + }; + +- /* dram mapping for pcie for ex. */ ++ /* dram mapping for pcie0 for ex. */ + dram_range2: dram_range@2 { + compatible = "spacemit-dram-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, +- <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>; ++ <0x0 0x90000000 0x1 0x10000000 0x3 0x70000000>; + #interconnect-cells = <0>; + status = "okay"; + }; +@@ -539,6 +545,30 @@ dram_range5: dram_range@5 { + status = "okay"; + }; + ++ /* dram mapping for pcie1 for ex. */ ++ dram_range6: dram_range@6 { ++ compatible = "spacemit-dram-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, ++ <0x0 0x80000000 0x1 0x00000000 0x0 0x10000000>, ++ <0x0 0xa0000000 0x1 0x20000000 0x3 0x60000000>; ++ #interconnect-cells = <0>; ++ status = "okay"; ++ }; ++ ++ /* dram mapping for pcie2 for ex. */ ++ dram_range7: dram_range@7 { ++ compatible = "spacemit-dram-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, ++ <0x0 0x80000000 0x1 0x00000000 0x0 0x20000000>, ++ <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>; ++ #interconnect-cells = <0>; ++ status = "okay"; ++ }; ++ + clint0: clint@e4000000 { + compatible = "riscv,clint0"; + interrupts-extended = < +@@ -615,7 +645,8 @@ &cpu7_intc 11 &cpu7_intc 9 + pinctrl: pinctrl@d401e000 { + compatible = "pinconf-single-aib"; + reg = <0x0 0xd401e000 0x0 0x250>, +- <0x0 0xd4019800 0x0 0x10>; ++ <0x0 0xd4019800 0x0 0x10>, ++ <0x0 0xd4019000 0x0 0x800>; + #address-cells = <1>; + #size-cells = <1>; + #pinctrl-cells = <2>; +@@ -1398,8 +1429,8 @@ ri2c0: ri2c@c0887000 { + spacemit,i2c-wcr = <0x142a>; + /* apb clock: 26MHz or 52MHz */ + spacemit,apb_clock = <52000000>; +- power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; +- cpuidle,pm-runtime,sleep; ++ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; ++ cpuidle,pm-runtime,sleep; + interconnects = <&dram_range4>; + interconnect-names = "dma-mem"; + status = "okay"; +@@ -1865,6 +1896,17 @@ gcb3: gpio3 { + }; + }; + ++ ec_master: ethercat_master { ++ compatible = "igh,k1x-ec-master"; ++ run-on-cpu = <1>; ++ debug-level = <0>; ++ master-count = <1>; ++ ec-devices = <ð0>,<ð1>; ++ master-indexes = <0>,<0>; ++ modes = "ec_main","ec_backup"; ++ status = "disable"; ++ }; ++ + eth0: ethernet@cac80000 { + compatible = "spacemit,k1x-emac"; + reg = <0x00000000 0xCAC80000 0x00000000 0x00000420>; +@@ -2239,7 +2281,7 @@ pcie1_rc: pcie@ca400000 { + #size-cells = <2>; + ranges = <0x01000000 0x0 0x9f002000 0 0x9f002000 0x0 0x100000>, + <0x02000000 0x0 0x90000000 0 0x90000000 0x0 0x0f000000>; +- interconnects = <&dram_range2>; ++ interconnects = <&dram_range6>; + interconnect-names = "dma-mem"; + + interrupts = <142>, <146>; +@@ -2289,7 +2331,7 @@ pcie2_rc: pcie@ca800000 { + ranges = <0x01000000 0x0 0xb7002000 0 0xb7002000 0x0 0x100000>, + <0x42000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000>, + <0x02000000 0x0 0xb0000000 0 0xb0000000 0x0 0x7000000>; +- interconnects = <&dram_range2>; ++ interconnects = <&dram_range7>; + interconnect-names = "dma-mem"; + + interrupts = <143>, <147>; +@@ -2486,6 +2528,14 @@ spacemit_crypto_engine@d8600000 { + status = "okay"; + }; + ++ crng: crng@f0703800 { ++ compatible = "spacemit,hw_crng"; ++ reg = <0x0 0xf0703800 0x0 0x100>; ++ clocks = <&ccu CLK_AES>; ++ resets = <&reset RESET_AES>; ++ status = "okay"; ++ }; ++ + efuse: fuse@f0702800 { + compatible = "simple-mfd"; + #address-cells = <1>; +-- +2.43.0 + diff --git a/patch/kernel/archive/spacemit-6.17/dt/k1-bananapi-f3.dts b/patch/kernel/archive/spacemit-6.17/dt/k1-bananapi-f3.dts new file mode 100644 index 000000000..cdd22e101 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.17/dt/k1-bananapi-f3.dts @@ -0,0 +1,1175 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; + +#include "k1-x.dtsi" +#include "k1-x-efuse.dtsi" +#include "k1-x_pinctrl.dtsi" +#include "lcd/lcd_gx09inx101_mipi.dtsi" +#include "k1-x-hdmi.dtsi" +#include "k1-x-lcd.dtsi" +#include "k1-x-camera-sdk.dtsi" +#include "k1-x_opp_table.dtsi" +#include "k1-x_thermal_cooling.dtsi" + +/ { + model = "BananaPi BPI-F3"; + + chosen { + bootargs = "earlycon=sbi console=ttyS0,115200n8 swiotlb=65536 rdinit=/init"; + stdout-path = "serial0:115200n8"; + }; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <24000000>; + + cpu_0: cpu@0 { + cpu-ai = "true"; + }; + + cpu_1: cpu@1 { + cpu-ai = "true"; + }; + + cpu_2: cpu@2 { + reg = <2>; + cpu-ai = "true"; + }; + + cpu_3: cpu@3 { + reg = <3>; + cpu-ai = "true"; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu_0>; + }; + + core1 { + cpu = <&cpu_1>; + }; + + core2 { + cpu = <&cpu_2>; + }; + + core3 { + cpu = <&cpu_3>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu_4>; + }; + + core1 { + cpu = <&cpu_5>; + }; + + core2 { + cpu = <&cpu_6>; + }; + + core3 { + cpu = <&cpu_7>; + }; + }; + }; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + pwms = <&rpwm2 10000>; + #cooling-cells = <2>; + cooling-levels = <0 64 128 192 255>; + status = "okay"; + }; + + leds { + compatible = "gpio-leds"; + + led1 { + label = "sys-led"; + gpios = <&gpio 96 0>; + linux,default-trigger = "heartbeat"; + default-state = "on"; + status = "okay"; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>; + }; + + memory@100000000 { + device_type = "memory"; + reg = <0x1 0x00000000 0x0 0x80000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + /* alloc memory from 0x40000000~0x80000000 */ + alloc-ranges = <0 0x40000000 0 0x40000000>; + /* size of cma buffer is 384MByte */ + size = <0 0x18000000>; + /* start address is 1Mbyte aligned */ + alignment = <0x0 0x100000>; + linux,cma-default; + /* besides hardware, dma for ex. buffer can be used by memory management */ + reusable; + }; + + /* reserved 384K for dpu, including mmu table(256K) and cmdlist(128K) */ + dpu_resv: dpu_reserved@2ff40000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x2ff40000 0x0 0x000C0000>; + no-map; + }; + }; + + rf_pwrseq: rf-pwrseq { + compatible = "spacemit,rf-pwrseq"; + //vdd-supply = <&ldo_7>; + //vdd_voltage = <3300000>; + io-supply = <&dcdc_3>; + io_voltage = <1800000>; + pwr-gpios = <&gpio 67 0>; + status = "okay"; + + wlan_pwrseq: wlan-pwrseq { + compatible = "spacemit,wlan-pwrseq"; + regon-gpios = <&gpio 116 0>; + interrupt-parent = <&pinctrl>; + interrupts = <268>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wlan_wakeup>; + }; + + bt_pwrseq: bt-pwrseq { + compatible = "spacemit,bt-pwrseq"; + reset-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>; + }; + }; + + vcc4v0_baseboard: vcc4v0-baseboard { + compatible = "regulator-fixed"; + regulator-name = "vcc4v0_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <4000000>; + vin-supply = <&dc_12v>; + }; +}; + +/* ov16a10 */ +&backsensor { + af_2v8-supply = <&ldo_3>; + avdd_2v8-supply = <&ldo_2>; + dovdd_1v8-supply = <&ldo_7>; + dvdd_1v2-supply = <&ldo_6>; + + pwdn-gpios = <&gpio 113 0>; + reset-gpios = <&gpio 111 0>; + + status = "okay"; +}; + +&backsensor_aux { + avdd_2v8-supply = <&ldo_2>; + dovdd_1v8-supply = <&ldo_7>; + + status = "disabled"; +}; + +&ccic0 { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; + + status = "okay"; +}; + +&ccic1 { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; + + status = "okay"; +}; + +&ccic2 { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; + + status = "okay"; +}; + +&csiphy0 { + + status = "okay"; +}; + +&combphy { + status = "okay"; +}; + +&csiphy1 { + + status = "disabled"; +}; + +&csiphy2 { + spacemit,bifmode-enable; + + status = "okay"; +}; + +&cpp { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; +}; + +&dpu_online2_dsi { + memory-region = <&dpu_resv>; + spacemit-dpu-bitclk = <1000000000>; + spacemit-dpu-escclk = <76800000>; + dsi_1v2-supply = <&ldo_5>; + vin-supply-names = "dsi_1v2"; + status = "disabled"; +}; + +&dpu_online2_hdmi { + memory-region = <&dpu_resv>; + status = "okay"; +}; + +&dsi2 { + status = "disabled"; + + panel2: panel2@0 { + status = "ok"; + compatible = "spacemit,mipi-panel2"; + reg = <0>; + + gpios-reset = <81>; + gpios-dc = <82 83>; + id = <2>; + delay-after-reset = <10>; + force-attached = "lcd_gx09inx101_mipi"; + }; +}; + +&hdmiaudio { + status = "okay"; +}; + +&hdmi{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmi_0>; + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0>; + spacemit,i2c-fast-mode; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2_0>; + spacemit,i2c-fast-mode; + status = "okay"; + + eeprom@50{ + compatible = "atmel,24c02"; + reg = <0x50>; + #address-cells = <1>; + #size-cells = <1>; + + power-domains = <&power K1X_PMU_DUMMY_PWR_DOMAIN>; + status = "disabled"; + + mac_address0: mac_address0@0 { + reg = <0x0 6>; + }; + + mac_address1: mac_address1@6 { + reg = <0x6 6>; + }; + }; + + es8326: es8326@19{ + compatible = "everest,es8326"; + reg = <0x19>; + #sound-dai-cells = <0>; + interrupt-parent = <&gpio>; + interrupts = <126 1>; + spk-ctl-gpio = <&gpio 127 0>; + everest,mic1-src = [44]; + everest,mic2-src = [66]; + status = "okay"; + }; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_2>; + status = "disabled"; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4_2>; + status = "disabled"; +}; + +&i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c6_2>; + status = "disabled"; + + gt9xx@5d { + compatible = "goodix,gt9xx"; + reg = <0x5d>; + + reset-gpios = <&gpio 114 GPIO_ACTIVE_HIGH>; + irq-gpios = <&gpio 58 GPIO_ACTIVE_HIGH>; + irq-flags = <2>; + + touchscreen-max-id = <11>; + touchscreen-size-x = <1200>; + touchscreen-size-y = <1920>; + touchscreen-max-w = <512>; + touchscreen-max-p = <512>; + + goodix,int-sync = <1>; + status = "disabled"; + }; + +}; + +&i2c7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c7>; + status = "disabled"; +}; + +&i2c8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c8>; + status = "okay"; + + spm8821@41 { + compatible = "spacemit,spm8821"; + reg = <0x41>; + interrupt-parent = <&intc>; + interrupts = <64>; + status = "okay"; + + vcc_sys-supply = <&vcc4v0_baseboard>; + dcdc5-supply = <&dcdc_5>; + + regulators { + compatible = "pmic,regulator,spm8821"; + + /* buck */ + dcdc_1: DCDC_REG1 { + regulator-name = "dcdc1"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <650000>; + }; + }; + + dcdc_2: DCDC_REG2 { + regulator-name = "dcdc2"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + dcdc_3: DCDC_REG3 { + regulator-name = "dcdc3"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + dcdc_4: DCDC_REG4 { + regulator-name = "dcdc4"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + dcdc_5: DCDC_REG5 { + regulator-name = "dcdc5"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + dcdc_6: DCDC_REG6 { + regulator-name = "dcdc6"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + /* aldo */ + ldo_1: LDO_REG1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_2: LDO_REG2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_3: LDO_REG3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_4: LDO_REG4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + /* dldo */ + ldo_5: LDO_REG5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_6: LDO_REG6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_7: LDO_REG7 { + regulator-name = "ldo7"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <500000>; + }; + }; + + ldo_8: LDO_REG8 { + regulator-name = "ldo8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-always-on; + }; + + ldo_9: LDO_REG9 { + regulator-name = "ldo9"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + ldo_10: LDO_REG10 { + regulator-name = "ldo10"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-always-on; + }; + + ldo_11: LDO_REG11 { + regulator-name = "ldo11"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + sw_1: SWITCH_REG1 { + regulator-name = "switch1"; + }; + }; + + pmic_pinctrl: pinctrl { + compatible = "pmic,pinctrl,spm8821"; + gpio-controller; + #gpio-cells = <2>; + spacemit,npins = <6>; +/** + * led_pins: led-pins { + * pins = "PIN3"; + * function = "sleep"; + * bias-disable = <0>; + * drive-open-drain = <0x1>; + * }; + */ + }; + + pwr_key: key { + compatible = "pmic,pwrkey,spm8821"; + }; + + ext_rtc: rtc { + compatible = "pmic,rtc,spm8821"; + }; + + ext_adc: adc { + compatible = "pmic,adc,spm8821"; + }; + }; +}; + +&i2s0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sspa0_0>; + status = "okay"; +}; + +&ehci { + spacemit,reset-on-resume; + spacemit,udc-mode = ; + status = "disabled"; +}; + +&ehci1 { + /*spacemit,udc-mode = ;*/ + spacemit,reset-on-resume; + status = "okay"; +}; + +ð0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac0>; + + emac,reset-gpio = <&gpio 110 0>; + emac,reset-active-low; + emac,reset-delays-us = <0 10000 100000>; + + /* store forward mode */ + tx-threshold = <1518>; + rx-threshold = <12>; + tx-ring-num = <1024>; + rx-ring-num = <1024>; + dma-burst-len = <5>; + + ref-clock-from-phy; + + clk-tuning-enable; + clk-tuning-by-delayline; + tx-phase = <60>; + rx-phase = <73>; + + nvmem-cells = <&mac_address0>; + nvmem-cell-names = "mac-address"; + + phy-handle = <&rgmii0>; + + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + rgmii0: phy@0 { + compatible = "ethernet-phy-id001c.c916"; + device_type = "ethernet-phy"; + reg = <0x1>; + phy-mode = "rgmii"; + }; + }; +}; + +ð1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac1>; + + emac,reset-gpio = <&gpio 115 0>; + emac,reset-active-low; + emac,reset-delays-us = <0 10000 100000>; + + /* store forward mode */ + tx-threshold = <1518>; + rx-threshold = <12>; + tx-ring-num = <1024>; + rx-ring-num = <1024>; + dma-burst-len = <5>; + + ref-clock-from-phy; + + clk-tuning-enable; + clk-tuning-by-delayline; + tx-phase = <90>; + rx-phase = <73>; + nvmem-cells = <&mac_address1>; + nvmem-cell-names = "mac-address"; + + phy-handle = <&rgmii1>; + + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + rgmii1: phy@1 { + compatible = "ethernet-phy-id001c.c916"; + device_type = "ethernet-phy"; + reg = <0x1>; + phy-mode = "rgmii"; + }; + }; +}; + +&frontsensor { + af_2v8-supply = <&ldo_3>; + avdd_2v8-supply = <&ldo_2>; + dovdd_1v8-supply = <&ldo_7>; + dvdd_1v2-supply = <&ldo_6>; + + clocks = <&ccu CLK_CAMM1>; + clock-names = "cam_mclk1"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_camera1>; + + pwdn-gpios = <&gpio 114 0>; + reset-gpios = <&gpio 112 0>; + + status = "disabled"; +}; + +&gpio{ + gpio-ranges = < + &pinctrl 49 GPIO_49 2 + &pinctrl 58 GPIO_58 1 + &pinctrl 63 GPIO_63 3 + &pinctrl 67 GPIO_67 1 + &pinctrl 70 PRI_TDI 4 + &pinctrl 74 GPIO_74 1 + &pinctrl 80 GPIO_80 4 + &pinctrl 90 GPIO_90 3 + &pinctrl 96 DVL0 2 + &pinctrl 110 GPIO_110 1 + &pinctrl 111 GPIO_111 1 + &pinctrl 113 GPIO_113 1 + &pinctrl 114 GPIO_114 3 + &pinctrl 118 GPIO_118 1 + &pinctrl 123 GPIO_123 5 + >; +}; + +&imggpu { + status = "okay"; +}; + +&isp { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; +}; + +&lcds { + status = "disabled"; +}; + +&otg { + usb-role-switch; + role-switch-user-control; + spacemit,reset-on-resume; + role-switch-default-mode = "peripheral"; + vbus-gpios = <&gpio 123 0>; + status = "disabled"; +}; + +&otg1 { + usb-role-switch; + role-switch-user-control; + spacemit,reset-on-resume; + role-switch-default-mode = "host"; + vbus-gpios = <&gpio 123 0>; + status = "disabled"; +}; + +&pcie1_rc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie1_3>; + status = "okay"; +}; + +&pcie2_rc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie2_4>; + num-lanes = <1>; + status = "okay"; +}; + +&pinctrl { + pinctrl-single,gpio-range = < + &range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) + &range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_63 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_64 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_67 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) + &range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) + &range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range DVL0 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range DVL1 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS0) + &range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_111 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_113 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_115 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + &range GPIO_116 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_118 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS0) + &range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) + &range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) + >; + + pinctrl_rcpu: pinctrl_rcpu_grp { + pinctrl-single,pins = < + K1X_PADCONF(GPIO_47, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* r_uart0_tx */ + K1X_PADCONF(GPIO_48, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* r_uart0_rx */ + >; + }; + + pinctrl_gmac0: gmac0_grp { + pinctrl-single,pins =< + K1X_PADCONF(GPIO_00, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rxdv */ + K1X_PADCONF(GPIO_01, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rx_d0 */ + K1X_PADCONF(GPIO_02, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rx_d1 */ + K1X_PADCONF(GPIO_03, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rx_clk */ + K1X_PADCONF(GPIO_04, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rx_d2 */ + K1X_PADCONF(GPIO_05, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_rx_d3 */ + K1X_PADCONF(GPIO_06, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx_d0 */ + K1X_PADCONF(GPIO_07, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx_d1 */ + K1X_PADCONF(GPIO_08, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx */ + K1X_PADCONF(GPIO_09, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx_d2 */ + K1X_PADCONF(GPIO_10, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx_d3 */ + K1X_PADCONF(GPIO_11, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_tx_en */ + K1X_PADCONF(GPIO_12, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac0_mdc */ + K1X_PADCONF(GPIO_13, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac0_mdio */ + K1X_PADCONF(GPIO_14, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_int_n */ + K1X_PADCONF(GPIO_45, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac0_clk_ref */ + >; + }; + + pinctrl_gmac1: gmac1_grp { + pinctrl-single,pins =< + K1X_PADCONF(GPIO_29, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rxdv */ + K1X_PADCONF(GPIO_30, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rx_d0 */ + K1X_PADCONF(GPIO_31, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rx_d1 */ + K1X_PADCONF(GPIO_32, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rx_clk */ + K1X_PADCONF(GPIO_33, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rx_d2 */ + K1X_PADCONF(GPIO_34, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_rx_d3 */ + K1X_PADCONF(GPIO_35, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_tx_d0 */ + K1X_PADCONF(GPIO_36, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_tx_d1 */ + K1X_PADCONF(GPIO_37, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_tx */ + K1X_PADCONF(GPIO_38, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_tx_d2 */ + K1X_PADCONF(GPIO_39, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_tx_d3 */ + K1X_PADCONF(GPIO_40, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_tx_en */ + K1X_PADCONF(GPIO_41, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_mdc */ + K1X_PADCONF(GPIO_42, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS0)) /* gmac1_mdio */ + K1X_PADCONF(GPIO_43, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_int_n */ + K1X_PADCONF(GPIO_46, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_clk_ref */ + >; + }; + + pinctrl_wlan_wakeup: wlan_wakeup_grp { + pinctrl-single,pins =< + K1X_PADCONF(GPIO_66, MUX_MODE0, (EDGE_FALL | PULL_DOWN | PAD_3V_DS2)) /* wifi edge detect */ + >; + }; +}; + +&pwm7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm7_0>; + status = "disabled"; +}; + +&pwm14 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm14_1>; + status = "okay"; +}; + +&pwm_bl { + pwms = <&pwm14 2000>; + brightness-levels = < + 0 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 + 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 + 40 40 40 40 40 40 40 40 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <100>; + + status = "okay"; +}; + +&qspi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qspi>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <26500000>; + m25p,fast-read; + broken-flash-reset; + status = "okay"; + }; +}; + +&rcpu { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rcpu>; + mboxes = <&mailbox 0>, <&mailbox 1>; + mbox-names = "vq0", "vq1"; + memory-region = <&rcpu_mem_0>, <&rcpu_mem_heap>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>, <&rsc_table>, <&rcpu_mem_snapshots>; + status = "okay"; +}; + +&rpwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rpwm2_0>; + status = "okay"; +}; + +/* SD */ +&sdhci0 { + pinctrl-names = "default","fast"; + pinctrl-0 = <&pinctrl_mmc1>; + pinctrl-1 = <&pinctrl_mmc1_fast>; + bus-width = <4>; + cd-gpios = <&gpio 80 0>; + cd-inverted; + vmmc-supply = <&dcdc_4>; + vqmmc-supply = <&ldo_1>; + no-mmc; + no-sdio; + spacemit,sdh-host-caps-disable = <( + MMC_CAP_UHS_SDR12 | + MMC_CAP_UHS_SDR25 + )>; + spacemit,sdh-quirks = <( + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_INVERTED_WRITE_PROTECT | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL + )>; + spacemit,sdh-quirks2 = <( + SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_BROKEN_PHY_MODULE | + SDHCI_QUIRK2_SET_AIB_MMC + )>; + spacemit,aib_mmc1_io_reg = <0xD401E81C>; + spacemit,apbc_asfar_reg = <0xD4015050>; + spacemit,apbc_assar_reg = <0xD4015054>; + spacemit,rx_dline_reg = <0x0>; + spacemit,tx_dline_reg = <0x0>; + spacemit,tx_delaycode = <0x5f>; + spacemit,rx_tuning_limit = <50>; + spacemit,sdh-freq = <204800000>; + status = "okay"; +}; + +/* SDIO */ +&sdhci1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc2>; + bus-width = <4>; + non-removable; + vqmmc-supply = <&dcdc_3>; + no-mmc; + no-sd; + keep-power-in-suspend; + /* bcmdhd use private oob solution rather than dat1/standard wakeup */ + /delete-property/ enable-sdio-wakeup; + spacemit,sdh-host-caps-disable = <( + MMC_CAP_UHS_DDR50 | + MMC_CAP_NEEDS_POLL + )>; + spacemit,sdh-quirks = <( + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL + )>; + spacemit,sdh-quirks2 = <( + SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_BROKEN_PHY_MODULE + )>; + spacemit,rx_dline_reg = <0x0>; + spacemit,tx_delaycode = <0x8f>; + spacemit,rx_tuning_limit = <50>; + spacemit,sdh-freq = <375000000>; + status = "okay"; +}; + +/* eMMC */ +&sdhci2 { + bus-width = <8>; + non-removable; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + no-sd; + no-sdio; + spacemit,sdh-quirks = <( + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL + )>; + spacemit,sdh-quirks2 = <( + SDHCI_QUIRK2_PRESET_VALUE_BROKEN + )>; + spacemit,sdh-freq = <375000000>; + status = "okay"; +}; + +&sound_hdmi { + status = "okay"; + simple-audio-card,cpu { + sound-dai = <&hdmiaudio>; + }; +}; + +&sound_codec { + status = "okay"; + simple-audio-card,name = "snd-es8326"; + spacemit,mclk-fs = <64>; + simple-audio-card,codec { + sound-dai = <&es8326>; + }; +}; + +&spi3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ssp3_0>; + status = "disabled"; + + spidev@0{ + compatible = "spacemit,k1x-spi"; + reg = <0>; + }; +}; + +&thermal { + sensor_range = <0x1 0x4>; +}; + +&thermal_zones { + top_thermal { + polling-delay = <0>; + polling-delay-passive = <0>; + thermal-sensors = <&thermal 1>; + + trips { + top_trip0: top-trip0 { + temperature = <40000>; + hysteresis = <5000>; + type = "passive"; + }; + + top_trip1: top-trip1 { + temperature = <55000>; + hysteresis = <5000>; + type = "passive"; + }; + + top_trip2: top-trip2 { + temperature = <70000>; + hysteresis = <5000>; + type = "passive"; + }; + + top_trip3: top-trip3 { + temperature = <85000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&top_trip0>; + cooling-device = <&fan 0 1>; + }; + + map1 { + trip = <&top_trip1>; + cooling-device = <&fan 1 2>; + }; + + map2 { + trip = <&top_trip2>; + cooling-device = <&fan 2 3>; + }; + + map3 { + trip = <&top_trip3>; + cooling-device = <&fan 3 4>; + }; + }; + }; + + gpu_thermal { + polling-delay = <0>; + polling-delay-passive = <0>; + thermal-sensors = <&thermal 2>; + + /* Just a placeholder */ + trips { + gpu_trip0: gpu-trip0 { + temperature = <40000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0_2>; + status = "okay"; +}; + +/* Bluetooth */ +&uart2 { + status = "okay"; + pinctrl-0 = <&pinctrl_uart2>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "realtek,rtl8723ds-bt"; + device-wake-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio 65 GPIO_ACTIVE_HIGH>; + }; +}; + +&udc { + /*spacemit,udc-mode = ;*/ + spacemit,udc-mode = ; + status = "okay"; +}; + +&udc1 { + /*spacemit,udc-mode = ;*/ + spacemit,udc-mode = ; + status = "disabled"; +}; + +&usbdrd3 { + status = "okay"; + reset-on-resume; + dwc3@c0a00000 { + dr_mode = "host"; + phy_type = "utmi"; + snps,hsphy_interface = "utmi"; + snps,dis_enblslpm_quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,parkmode-disable-ss-quirk; + }; +}; + +&usb3hub { + hub-gpios = < + &gpio 123 0 /* usb3 hub en */ + &gpio 124 0>; /* usb3 hub rst*/ + vbus-gpios = <&gpio 97 0>; /* gpio_97 for usb3 hub output vbus */ + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; + +&usbphy1 { + status = "okay"; +}; + +&usb2phy { + status = "okay"; +}; + +&vi { + power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; +}; diff --git a/patch/kernel/archive/sunxi-6.12/series.armbian b/patch/kernel/archive/sunxi-6.12/series.armbian index 64e963ef9..935e9b41c 100644 --- a/patch/kernel/archive/sunxi-6.12/series.armbian +++ b/patch/kernel/archive/sunxi-6.12/series.armbian @@ -34,7 +34,7 @@ patches.armbian/drv-gpu-drm-panel-simple-Add-compability-olinuxino-lcd.patch patches.armbian/drv-input-touchscreen-sun4i-ts-Enable-parsing.patch patches.armbian/drv-mmc-host-sunxi-mmc-Disable-DDR52-mode-on-all-A20-based-boar.patch - patches.armbian/drv-usb-gadget-composite-rename-gadget-serial-console-manufactu.patch +- patches.armbian/drv-usb-gadget-composite-rename-gadget-serial-console-manufactu.patch patches.armbian/Add-FB_TFT-ST7796S-driver.patch patches.armbian/Optimize-TSC2007-touchscreen-add-polling-method.patch patches.armbian/Add-ws2812-RGB-driver-for-allwinner-H616.patch diff --git a/patch/kernel/archive/sunxi-6.12/series.conf b/patch/kernel/archive/sunxi-6.12/series.conf index b64dc7954..29d05498f 100644 --- a/patch/kernel/archive/sunxi-6.12/series.conf +++ b/patch/kernel/archive/sunxi-6.12/series.conf @@ -173,7 +173,7 @@ patches.megous/arm64-dts-allwinner-Enforce-consistent-MMC-numbering.patch patches.megous/ARM-dts-sunxi-Add-aliases-for-MMC.patch patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch - patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch +- patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch patches.megous/Revert-drm-sun4i-lvds-Invert-the-LVDS-polarity.patch patches.megous/of-property-fw_devlink-Support-allwinner-sram-links.patch diff --git a/patch/kernel/archive/sunxi-6.12/series.megous b/patch/kernel/archive/sunxi-6.12/series.megous index ee4491ed8..f8c3dbeba 100644 --- a/patch/kernel/archive/sunxi-6.12/series.megous +++ b/patch/kernel/archive/sunxi-6.12/series.megous @@ -172,7 +172,7 @@ patches.megous/arm64-dts-allwinner-Enforce-consistent-MMC-numbering.patch patches.megous/ARM-dts-sunxi-Add-aliases-for-MMC.patch patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch - patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch +- patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch patches.megous/Revert-drm-sun4i-lvds-Invert-the-LVDS-polarity.patch patches.megous/of-property-fw_devlink-Support-allwinner-sram-links.patch diff --git a/patch/kernel/archive/uefi-arm64-6.17/board-hikey960-usb.patch b/patch/kernel/archive/uefi-arm64-6.18/board-hikey960-usb.patch similarity index 100% rename from patch/kernel/archive/uefi-arm64-6.17/board-hikey960-usb.patch rename to patch/kernel/archive/uefi-arm64-6.18/board-hikey960-usb.patch diff --git a/patch/kernel/archive/uefi-arm64-6.17/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch b/patch/kernel/archive/uefi-arm64-6.18/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch similarity index 98% rename from patch/kernel/archive/uefi-arm64-6.17/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch rename to patch/kernel/archive/uefi-arm64-6.18/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch index 09ca123be..49bca4fa7 100644 --- a/patch/kernel/archive/uefi-arm64-6.17/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch +++ b/patch/kernel/archive/uefi-arm64-6.18/net-stmicro-stmmac-Phytium-onboard-ethernet-drivers-and-ACPI-glue-for-6.x.patch @@ -176,7 +176,7 @@ index 000000000000..111111111111 + np = dev_fwnode(dev); + + plat->phy_interface = fwnode_get_phy_mode(np); -+ plat->mac_interface = plat->phy_interface; ++ + + /* Get max speed of operation from properties */ + if (fwnode_property_read_u32(np, "max-speed", &plat->max_speed)) @@ -368,7 +368,7 @@ index 111111111111..222222222222 100644 #include #include #include -@@ -730,6 +733,249 @@ struct clk *stmmac_pltfr_find_clk(struct plat_stmmacenet_data *plat_dat, +@@ -734,6 +737,249 @@ struct clk *stmmac_pltfr_find_clk(struct plat_stmmacenet_data *plat_dat, } EXPORT_SYMBOL_GPL(stmmac_pltfr_find_clk); @@ -517,7 +517,7 @@ index 111111111111..222222222222 100644 + + np = dev_fwnode(&(pdev->dev)); + -+ plat->mac_interface = fw_get_phy_mode(np); ++ plat->phy_interface = fw_get_phy_mode(np); + + /* Get max speed of operation from device tree */ + if (fwnode_property_read_u32(np, "max-speed", &plat->max_speed)) @@ -618,7 +618,7 @@ index 111111111111..222222222222 100644 int stmmac_get_platform_resources(struct platform_device *pdev, struct stmmac_resources *stmmac_res) { -@@ -737,8 +983,14 @@ int stmmac_get_platform_resources(struct platform_device *pdev, +@@ -741,8 +987,14 @@ int stmmac_get_platform_resources(struct platform_device *pdev, /* Get IRQ information early to have an ability to ask for deferred * probe if needed before we went too far with resource allocation. @@ -634,7 +634,7 @@ index 111111111111..222222222222 100644 if (stmmac_res->irq < 0) return stmmac_res->irq; -@@ -756,6 +1008,7 @@ int stmmac_get_platform_resources(struct platform_device *pdev, +@@ -760,6 +1012,7 @@ int stmmac_get_platform_resources(struct platform_device *pdev, return -EPROBE_DEFER; dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n"); stmmac_res->wol_irq = stmmac_res->irq; diff --git a/patch/kernel/archive/uefi-loong64-6.17/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch b/patch/kernel/archive/uefi-loong64-6.18/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch similarity index 96% rename from patch/kernel/archive/uefi-loong64-6.17/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch rename to patch/kernel/archive/uefi-loong64-6.18/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch index 9d4ac50ed..c690085c7 100644 --- a/patch/kernel/archive/uefi-loong64-6.17/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch +++ b/patch/kernel/archive/uefi-loong64-6.18/0001-drm-xe-bo-fix-alignment-with-non-4KiB-kernel-page-si.patch @@ -95,14 +95,14 @@ Co-developed-by: Shang Yatsen <429839446@qq.com> Signed-off-by: Shang Yatsen <429839446@qq.com> Signed-off-by: Mingcong Bai --- - drivers/gpu/drm/xe/xe_bo.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) + drivers/gpu/drm/xe/xe_bo.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c -@@ -1841,9 +1841,9 @@ struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo, +@@ -2129,9 +2129,9 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo, flags |= XE_BO_FLAG_INTERNAL_64K; alignment = align >> PAGE_SHIFT; } else { @@ -114,7 +114,7 @@ index 111111111111..222222222222 100644 } if (type == ttm_bo_type_device && aligned_size != size) -@@ -1868,7 +1868,7 @@ struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo, +@@ -2155,7 +2155,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo, #endif INIT_LIST_HEAD(&bo->vram_userfault_link); diff --git a/patch/kernel/archive/uefi-loong64-6.17/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch b/patch/kernel/archive/uefi-loong64-6.18/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch similarity index 91% rename from patch/kernel/archive/uefi-loong64-6.17/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch rename to patch/kernel/archive/uefi-loong64-6.18/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch index b4271d799..bdaa8dc05 100644 --- a/patch/kernel/archive/uefi-loong64-6.17/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch +++ b/patch/kernel/archive/uefi-loong64-6.18/0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch @@ -64,7 +64,7 @@ diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c -@@ -90,7 +90,7 @@ static u32 guc_ctl_feature_flags(struct xe_guc *guc) +@@ -95,7 +95,7 @@ static u32 guc_ctl_feature_flags(struct xe_guc *guc) static u32 guc_ctl_log_params_flags(struct xe_guc *guc) { @@ -73,13 +73,13 @@ index 111111111111..222222222222 100644 u32 flags; #if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0) -@@ -143,7 +143,7 @@ static u32 guc_ctl_log_params_flags(struct xe_guc *guc) +@@ -140,7 +140,7 @@ static u32 guc_ctl_log_params_flags(struct xe_guc *guc) static u32 guc_ctl_ads_flags(struct xe_guc *guc) { - u32 ads = guc_bo_ggtt_addr(guc, guc->ads.bo) >> PAGE_SHIFT; + u32 ads = guc_bo_ggtt_addr(guc, guc->ads.bo) >> XE_PTE_SHIFT; - u32 flags = ads << GUC_ADS_ADDR_SHIFT; + u32 flags = FIELD_PREP(GUC_ADS_ADDR, ads); return flags; diff --git a/drivers/gpu/drm/xe/xe_guc.h b/drivers/gpu/drm/xe/xe_guc.h @@ -100,7 +100,7 @@ diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads.c +++ b/drivers/gpu/drm/xe/xe_guc_ads.c -@@ -143,17 +143,17 @@ static size_t guc_ads_regset_size(struct xe_guc_ads *ads) +@@ -144,17 +144,17 @@ static size_t guc_ads_regset_size(struct xe_guc_ads *ads) static size_t guc_ads_golden_lrc_size(struct xe_guc_ads *ads) { @@ -121,7 +121,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_um_queues_size(struct xe_guc_ads *ads) -@@ -168,7 +168,7 @@ static size_t guc_ads_um_queues_size(struct xe_guc_ads *ads) +@@ -169,7 +169,7 @@ static size_t guc_ads_um_queues_size(struct xe_guc_ads *ads) static size_t guc_ads_private_data_size(struct xe_guc_ads *ads) { @@ -130,7 +130,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_regset_offset(struct xe_guc_ads *ads) -@@ -183,7 +183,7 @@ static size_t guc_ads_golden_lrc_offset(struct xe_guc_ads *ads) +@@ -184,7 +184,7 @@ static size_t guc_ads_golden_lrc_offset(struct xe_guc_ads *ads) offset = guc_ads_regset_offset(ads) + guc_ads_regset_size(ads); @@ -139,7 +139,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_waklv_offset(struct xe_guc_ads *ads) -@@ -193,7 +193,7 @@ static size_t guc_ads_waklv_offset(struct xe_guc_ads *ads) +@@ -194,7 +194,7 @@ static size_t guc_ads_waklv_offset(struct xe_guc_ads *ads) offset = guc_ads_golden_lrc_offset(ads) + guc_ads_golden_lrc_size(ads); @@ -148,7 +148,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_capture_offset(struct xe_guc_ads *ads) -@@ -203,7 +203,7 @@ static size_t guc_ads_capture_offset(struct xe_guc_ads *ads) +@@ -204,7 +204,7 @@ static size_t guc_ads_capture_offset(struct xe_guc_ads *ads) offset = guc_ads_waklv_offset(ads) + guc_ads_waklv_size(ads); @@ -157,7 +157,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_um_queues_offset(struct xe_guc_ads *ads) -@@ -213,7 +213,7 @@ static size_t guc_ads_um_queues_offset(struct xe_guc_ads *ads) +@@ -214,7 +214,7 @@ static size_t guc_ads_um_queues_offset(struct xe_guc_ads *ads) offset = guc_ads_capture_offset(ads) + guc_ads_capture_size(ads); @@ -166,7 +166,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_private_data_offset(struct xe_guc_ads *ads) -@@ -223,7 +223,7 @@ static size_t guc_ads_private_data_offset(struct xe_guc_ads *ads) +@@ -224,7 +224,7 @@ static size_t guc_ads_private_data_offset(struct xe_guc_ads *ads) offset = guc_ads_um_queues_offset(ads) + guc_ads_um_queues_size(ads); @@ -175,7 +175,7 @@ index 111111111111..222222222222 100644 } static size_t guc_ads_size(struct xe_guc_ads *ads) -@@ -276,7 +276,7 @@ static size_t calculate_golden_lrc_size(struct xe_guc_ads *ads) +@@ -277,7 +277,7 @@ static size_t calculate_golden_lrc_size(struct xe_guc_ads *ads) continue; real_size = xe_gt_lrc_size(gt, class); @@ -184,7 +184,7 @@ index 111111111111..222222222222 100644 total_size += alloc_size; } -@@ -646,12 +646,12 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) +@@ -628,12 +628,12 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) offsetof(struct __guc_ads_blob, system_info)); /* first, set aside the first page for a capture_list with zero descriptors */ @@ -199,7 +199,7 @@ index 111111111111..222222222222 100644 /* * Populate capture list : at this point adps is already allocated and -@@ -715,10 +715,10 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) +@@ -697,10 +697,10 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) } } @@ -213,7 +213,7 @@ index 111111111111..222222222222 100644 } static void guc_mmio_regset_write_one(struct xe_guc_ads *ads, -@@ -966,7 +966,7 @@ static void guc_golden_lrc_populate(struct xe_guc_ads *ads) +@@ -948,7 +948,7 @@ static void guc_golden_lrc_populate(struct xe_guc_ads *ads) xe_gt_assert(gt, gt->default_lrc[class]); real_size = xe_gt_lrc_size(gt, class); @@ -259,8 +259,8 @@ diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c -@@ -214,7 +214,7 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) - struct xe_bo *bo; +@@ -224,7 +224,7 @@ int xe_guc_ct_init_noalloc(struct xe_guc_ct *ct) + struct xe_gt *gt = ct_to_gt(ct); int err; - xe_gt_assert(gt, !(guc_ct_size() % PAGE_SIZE)); @@ -302,7 +302,7 @@ diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_guc_pc.c +++ b/drivers/gpu/drm/xe/xe_guc_pc.c -@@ -1190,7 +1190,7 @@ int xe_guc_pc_start(struct xe_guc_pc *pc) +@@ -1239,7 +1239,7 @@ int xe_guc_pc_start(struct xe_guc_pc *pc) { struct xe_device *xe = pc_to_xe(pc); struct xe_gt *gt = pc_to_gt(pc); @@ -311,7 +311,7 @@ index 111111111111..222222222222 100644 unsigned int fw_ref; ktime_t earlier; int ret; -@@ -1318,7 +1318,7 @@ int xe_guc_pc_init(struct xe_guc_pc *pc) +@@ -1372,7 +1372,7 @@ int xe_guc_pc_init(struct xe_guc_pc *pc) struct xe_tile *tile = gt_to_tile(gt); struct xe_device *xe = gt_to_xe(gt); struct xe_bo *bo; diff --git a/patch/kernel/archive/uefi-loong64-6.17/0003-drm-xe-regs-fix-RING_CTL_SIZE-size-calculation.patch b/patch/kernel/archive/uefi-loong64-6.18/0003-drm-xe-regs-fix-RING_CTL_SIZE-size-calculation.patch similarity index 100% rename from patch/kernel/archive/uefi-loong64-6.17/0003-drm-xe-regs-fix-RING_CTL_SIZE-size-calculation.patch rename to patch/kernel/archive/uefi-loong64-6.18/0003-drm-xe-regs-fix-RING_CTL_SIZE-size-calculation.patch diff --git a/patch/kernel/archive/uefi-loong64-6.17/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch b/patch/kernel/archive/uefi-loong64-6.18/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch similarity index 98% rename from patch/kernel/archive/uefi-loong64-6.17/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch rename to patch/kernel/archive/uefi-loong64-6.18/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch index eb0f22d2e..a4b8eb49a 100644 --- a/patch/kernel/archive/uefi-loong64-6.17/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch +++ b/patch/kernel/archive/uefi-loong64-6.18/0004-drm-xe-use-4KiB-alignment-for-cursor-jumps.patch @@ -98,7 +98,7 @@ diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_migrate.c +++ b/drivers/gpu/drm/xe/xe_migrate.c -@@ -592,7 +592,7 @@ static void emit_pte(struct xe_migrate *m, +@@ -617,7 +617,7 @@ static void emit_pte(struct xe_migrate *m, u64 addr, flags = 0; bool devmem = false; @@ -107,7 +107,7 @@ index 111111111111..222222222222 100644 if (is_vram) { if (vm->flags & XE_VM_FLAG_64K) { u64 va = cur_ofs * XE_PAGE_SIZE / 8; -@@ -613,7 +613,7 @@ static void emit_pte(struct xe_migrate *m, +@@ -638,7 +638,7 @@ static void emit_pte(struct xe_migrate *m, bb->cs[bb->len++] = lower_32_bits(addr); bb->cs[bb->len++] = upper_32_bits(addr); diff --git a/patch/kernel/archive/uefi-loong64-6.17/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch b/patch/kernel/archive/uefi-loong64-6.18/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch similarity index 96% rename from patch/kernel/archive/uefi-loong64-6.17/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch rename to patch/kernel/archive/uefi-loong64-6.18/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch index a55a8ef73..df676a372 100644 --- a/patch/kernel/archive/uefi-loong64-6.17/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch +++ b/patch/kernel/archive/uefi-loong64-6.18/0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch @@ -31,7 +31,7 @@ diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/xe/xe_query.c +++ b/drivers/gpu/drm/xe/xe_query.c -@@ -346,7 +346,7 @@ static int query_config(struct xe_device *xe, struct drm_xe_device_query *query) +@@ -345,7 +345,7 @@ static int query_config(struct xe_device *xe, struct drm_xe_device_query *query) config->info[DRM_XE_QUERY_CONFIG_FLAGS] |= DRM_XE_QUERY_CONFIG_FLAG_HAS_LOW_LATENCY; config->info[DRM_XE_QUERY_CONFIG_MIN_ALIGNMENT] = @@ -44,7 +44,7 @@ diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 111111111111..222222222222 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h -@@ -397,8 +397,11 @@ struct drm_xe_query_mem_regions { +@@ -403,8 +403,11 @@ struct drm_xe_query_mem_regions { * has low latency hint support * - %DRM_XE_QUERY_CONFIG_FLAG_HAS_CPU_ADDR_MIRROR - Flag is set if the * device has CPU address mirroring support diff --git a/patch/kernel/archive/uefi-loong64-6.17/0006-enable-xe-on-16K-pagesize.patch b/patch/kernel/archive/uefi-loong64-6.18/0006-enable-xe-on-16K-pagesize.patch similarity index 100% rename from patch/kernel/archive/uefi-loong64-6.17/0006-enable-xe-on-16K-pagesize.patch rename to patch/kernel/archive/uefi-loong64-6.18/0006-enable-xe-on-16K-pagesize.patch diff --git a/patch/kernel/archive/uefi-x86-6.12/1001-Add-apple-bce-driver.patch b/patch/kernel/archive/uefi-x86-6.12/1001-Add-apple-bce-driver.patch new file mode 100644 index 000000000..a5d839be0 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1001-Add-apple-bce-driver.patch @@ -0,0 +1,5830 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Thu, 11 Jul 2024 10:59:04 +0000 +Subject: Add apple-bce driver + +--- + drivers/staging/apple-bce/Makefile | 28 + + drivers/staging/apple-bce/apple_bce.c | 445 ++++++ + drivers/staging/apple-bce/apple_bce.h | 38 + + drivers/staging/apple-bce/audio/audio.c | 711 +++++++++ + drivers/staging/apple-bce/audio/audio.h | 125 ++ + drivers/staging/apple-bce/audio/description.h | 42 + + drivers/staging/apple-bce/audio/pcm.c | 308 ++++ + drivers/staging/apple-bce/audio/pcm.h | 16 + + drivers/staging/apple-bce/audio/protocol.c | 347 +++++ + drivers/staging/apple-bce/audio/protocol.h | 147 ++ + drivers/staging/apple-bce/audio/protocol_bce.c | 226 +++ + drivers/staging/apple-bce/audio/protocol_bce.h | 72 + + drivers/staging/apple-bce/mailbox.c | 151 ++ + drivers/staging/apple-bce/mailbox.h | 53 + + drivers/staging/apple-bce/queue.c | 390 +++++ + drivers/staging/apple-bce/queue.h | 177 +++ + drivers/staging/apple-bce/queue_dma.c | 220 +++ + drivers/staging/apple-bce/queue_dma.h | 50 + + drivers/staging/apple-bce/vhci/command.h | 204 +++ + drivers/staging/apple-bce/vhci/queue.c | 268 ++++ + drivers/staging/apple-bce/vhci/queue.h | 76 + + drivers/staging/apple-bce/vhci/transfer.c | 661 ++++++++ + drivers/staging/apple-bce/vhci/transfer.h | 73 + + drivers/staging/apple-bce/vhci/vhci.c | 759 ++++++++++ + drivers/staging/apple-bce/vhci/vhci.h | 52 + + 25 files changed, 5639 insertions(+) + +diff --git a/drivers/staging/apple-bce/Makefile b/drivers/staging/apple-bce/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/Makefile +@@ -0,0 +1,28 @@ ++modname := apple-bce ++obj-m += $(modname).o ++ ++apple-bce-objs := apple_bce.o mailbox.o queue.o queue_dma.o vhci/vhci.o vhci/queue.o vhci/transfer.o audio/audio.o audio/protocol.o audio/protocol_bce.o audio/pcm.o ++ ++MY_CFLAGS += -DWITHOUT_NVME_PATCH ++#MY_CFLAGS += -g -DDEBUG ++ccflags-y += ${MY_CFLAGS} ++CC += ${MY_CFLAGS} ++ ++KVERSION := $(KERNELRELEASE) ++ifeq ($(origin KERNELRELEASE), undefined) ++KVERSION := $(shell uname -r) ++endif ++ ++KDIR := /lib/modules/$(KVERSION)/build ++PWD := $(shell pwd) ++ ++.PHONY: all ++ ++all: ++ $(MAKE) -C $(KDIR) M=$(PWD) modules ++ ++clean: ++ $(MAKE) -C $(KDIR) M=$(PWD) clean ++ ++install: ++ $(MAKE) -C $(KDIR) M=$(PWD) modules_install +diff --git a/drivers/staging/apple-bce/apple_bce.c b/drivers/staging/apple-bce/apple_bce.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/apple_bce.c +@@ -0,0 +1,445 @@ ++#include "apple_bce.h" ++#include ++#include ++#include "audio/audio.h" ++#include ++ ++static dev_t bce_chrdev; ++static struct class *bce_class; ++ ++struct apple_bce_device *global_bce; ++ ++static int bce_create_command_queues(struct apple_bce_device *bce); ++static void bce_free_command_queues(struct apple_bce_device *bce); ++static irqreturn_t bce_handle_mb_irq(int irq, void *dev); ++static irqreturn_t bce_handle_dma_irq(int irq, void *dev); ++static int bce_fw_version_handshake(struct apple_bce_device *bce); ++static int bce_register_command_queue(struct apple_bce_device *bce, struct bce_queue_memcfg *cfg, int is_sq); ++ ++static int apple_bce_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct apple_bce_device *bce = NULL; ++ int status = 0; ++ int nvec; ++ ++ pr_info("apple-bce: capturing our device\n"); ++ ++ if (pci_enable_device(dev)) ++ return -ENODEV; ++ if (pci_request_regions(dev, "apple-bce")) { ++ status = -ENODEV; ++ goto fail; ++ } ++ pci_set_master(dev); ++ nvec = pci_alloc_irq_vectors(dev, 1, 8, PCI_IRQ_MSI); ++ if (nvec < 5) { ++ status = -EINVAL; ++ goto fail; ++ } ++ ++ bce = kzalloc(sizeof(struct apple_bce_device), GFP_KERNEL); ++ if (!bce) { ++ status = -ENOMEM; ++ goto fail; ++ } ++ ++ bce->pci = dev; ++ pci_set_drvdata(dev, bce); ++ ++ bce->devt = bce_chrdev; ++ bce->dev = device_create(bce_class, &dev->dev, bce->devt, NULL, "apple-bce"); ++ if (IS_ERR_OR_NULL(bce->dev)) { ++ status = PTR_ERR(bce_class); ++ goto fail; ++ } ++ ++ bce->reg_mem_mb = pci_iomap(dev, 4, 0); ++ bce->reg_mem_dma = pci_iomap(dev, 2, 0); ++ ++ if (IS_ERR_OR_NULL(bce->reg_mem_mb) || IS_ERR_OR_NULL(bce->reg_mem_dma)) { ++ dev_warn(&dev->dev, "apple-bce: Failed to pci_iomap required regions\n"); ++ goto fail; ++ } ++ ++ bce_mailbox_init(&bce->mbox, bce->reg_mem_mb); ++ bce_timestamp_init(&bce->timestamp, bce->reg_mem_mb); ++ ++ spin_lock_init(&bce->queues_lock); ++ ida_init(&bce->queue_ida); ++ ++ if ((status = pci_request_irq(dev, 0, bce_handle_mb_irq, NULL, dev, "bce_mbox"))) ++ goto fail; ++ if ((status = pci_request_irq(dev, 4, NULL, bce_handle_dma_irq, dev, "bce_dma"))) ++ goto fail_interrupt_0; ++ ++ if ((status = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(37)))) { ++ dev_warn(&dev->dev, "dma: Setting mask failed\n"); ++ goto fail_interrupt; ++ } ++ ++ /* Gets the function 0's interface. This is needed because Apple only accepts DMA on our function if function 0 ++ is a bus master, so we need to work around this. */ ++ bce->pci0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); ++#ifndef WITHOUT_NVME_PATCH ++ if ((status = pci_enable_device_mem(bce->pci0))) { ++ dev_warn(&dev->dev, "apple-bce: failed to enable function 0\n"); ++ goto fail_dev0; ++ } ++#endif ++ pci_set_master(bce->pci0); ++ ++ bce_timestamp_start(&bce->timestamp, true); ++ ++ if ((status = bce_fw_version_handshake(bce))) ++ goto fail_ts; ++ pr_info("apple-bce: handshake done\n"); ++ ++ if ((status = bce_create_command_queues(bce))) { ++ pr_info("apple-bce: Creating command queues failed\n"); ++ goto fail_ts; ++ } ++ ++ global_bce = bce; ++ ++ bce_vhci_create(bce, &bce->vhci); ++ ++ return 0; ++ ++fail_ts: ++ bce_timestamp_stop(&bce->timestamp); ++#ifndef WITHOUT_NVME_PATCH ++ pci_disable_device(bce->pci0); ++fail_dev0: ++#endif ++ pci_dev_put(bce->pci0); ++fail_interrupt: ++ pci_free_irq(dev, 4, dev); ++fail_interrupt_0: ++ pci_free_irq(dev, 0, dev); ++fail: ++ if (bce && bce->dev) { ++ device_destroy(bce_class, bce->devt); ++ ++ if (!IS_ERR_OR_NULL(bce->reg_mem_mb)) ++ pci_iounmap(dev, bce->reg_mem_mb); ++ if (!IS_ERR_OR_NULL(bce->reg_mem_dma)) ++ pci_iounmap(dev, bce->reg_mem_dma); ++ ++ kfree(bce); ++ } ++ ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++static int bce_create_command_queues(struct apple_bce_device *bce) ++{ ++ int status; ++ struct bce_queue_memcfg *cfg; ++ ++ bce->cmd_cq = bce_alloc_cq(bce, 0, 0x20); ++ bce->cmd_cmdq = bce_alloc_cmdq(bce, 1, 0x20); ++ if (bce->cmd_cq == NULL || bce->cmd_cmdq == NULL) { ++ status = -ENOMEM; ++ goto err; ++ } ++ bce->queues[0] = (struct bce_queue *) bce->cmd_cq; ++ bce->queues[1] = (struct bce_queue *) bce->cmd_cmdq->sq; ++ ++ cfg = kzalloc(sizeof(struct bce_queue_memcfg), GFP_KERNEL); ++ if (!cfg) { ++ status = -ENOMEM; ++ goto err; ++ } ++ bce_get_cq_memcfg(bce->cmd_cq, cfg); ++ if ((status = bce_register_command_queue(bce, cfg, false))) ++ goto err; ++ bce_get_sq_memcfg(bce->cmd_cmdq->sq, bce->cmd_cq, cfg); ++ if ((status = bce_register_command_queue(bce, cfg, true))) ++ goto err; ++ kfree(cfg); ++ ++ return 0; ++ ++err: ++ if (bce->cmd_cq) ++ bce_free_cq(bce, bce->cmd_cq); ++ if (bce->cmd_cmdq) ++ bce_free_cmdq(bce, bce->cmd_cmdq); ++ return status; ++} ++ ++static void bce_free_command_queues(struct apple_bce_device *bce) ++{ ++ bce_free_cq(bce, bce->cmd_cq); ++ bce_free_cmdq(bce, bce->cmd_cmdq); ++ bce->cmd_cq = NULL; ++ bce->queues[0] = NULL; ++} ++ ++static irqreturn_t bce_handle_mb_irq(int irq, void *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ bce_mailbox_handle_interrupt(&bce->mbox); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t bce_handle_dma_irq(int irq, void *dev) ++{ ++ int i; ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ spin_lock(&bce->queues_lock); ++ for (i = 0; i < BCE_MAX_QUEUE_COUNT; i++) ++ if (bce->queues[i] && bce->queues[i]->type == BCE_QUEUE_CQ) ++ bce_handle_cq_completions(bce, (struct bce_queue_cq *) bce->queues[i]); ++ spin_unlock(&bce->queues_lock); ++ return IRQ_HANDLED; ++} ++ ++static int bce_fw_version_handshake(struct apple_bce_device *bce) ++{ ++ u64 result; ++ int status; ++ ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_SET_FW_PROTOCOL_VERSION, BC_PROTOCOL_VERSION), ++ &result))) ++ return status; ++ if (BCE_MB_TYPE(result) != BCE_MB_SET_FW_PROTOCOL_VERSION || ++ BCE_MB_VALUE(result) != BC_PROTOCOL_VERSION) { ++ pr_err("apple-bce: FW version handshake failed %x:%llx\n", BCE_MB_TYPE(result), BCE_MB_VALUE(result)); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int bce_register_command_queue(struct apple_bce_device *bce, struct bce_queue_memcfg *cfg, int is_sq) ++{ ++ int status; ++ int cmd_type; ++ u64 result; ++ // OS X uses an bidirectional direction, but that's not really needed ++ dma_addr_t a = dma_map_single(&bce->pci->dev, cfg, sizeof(struct bce_queue_memcfg), DMA_TO_DEVICE); ++ if (dma_mapping_error(&bce->pci->dev, a)) ++ return -ENOMEM; ++ cmd_type = is_sq ? BCE_MB_REGISTER_COMMAND_SQ : BCE_MB_REGISTER_COMMAND_CQ; ++ status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(cmd_type, a), &result); ++ dma_unmap_single(&bce->pci->dev, a, sizeof(struct bce_queue_memcfg), DMA_TO_DEVICE); ++ if (status) ++ return status; ++ if (BCE_MB_TYPE(result) != BCE_MB_REGISTER_COMMAND_QUEUE_REPLY) ++ return -EINVAL; ++ return 0; ++} ++ ++static void apple_bce_remove(struct pci_dev *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ bce->is_being_removed = true; ++ ++ bce_vhci_destroy(&bce->vhci); ++ ++ bce_timestamp_stop(&bce->timestamp); ++#ifndef WITHOUT_NVME_PATCH ++ pci_disable_device(bce->pci0); ++#endif ++ pci_dev_put(bce->pci0); ++ pci_free_irq(dev, 0, dev); ++ pci_free_irq(dev, 4, dev); ++ bce_free_command_queues(bce); ++ pci_iounmap(dev, bce->reg_mem_mb); ++ pci_iounmap(dev, bce->reg_mem_dma); ++ device_destroy(bce_class, bce->devt); ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ kfree(bce); ++} ++ ++static int bce_save_state_and_sleep(struct apple_bce_device *bce) ++{ ++ int attempt, status = 0; ++ u64 resp; ++ dma_addr_t dma_addr; ++ void *dma_ptr = NULL; ++ size_t size = max(PAGE_SIZE, 4096UL); ++ ++ for (attempt = 0; attempt < 5; ++attempt) { ++ pr_debug("apple-bce: suspend: attempt %i, buffer size %li\n", attempt, size); ++ dma_ptr = dma_alloc_coherent(&bce->pci->dev, size, &dma_addr, GFP_KERNEL); ++ if (!dma_ptr) { ++ pr_err("apple-bce: suspend failed (data alloc failed)\n"); ++ break; ++ } ++ BUG_ON((dma_addr % 4096) != 0); ++ status = bce_mailbox_send(&bce->mbox, ++ BCE_MB_MSG(BCE_MB_SAVE_STATE_AND_SLEEP, (dma_addr & ~(4096LLU - 1)) | (size / 4096)), &resp); ++ if (status) { ++ pr_err("apple-bce: suspend failed (mailbox send)\n"); ++ break; ++ } ++ if (BCE_MB_TYPE(resp) == BCE_MB_SAVE_RESTORE_STATE_COMPLETE) { ++ bce->saved_data_dma_addr = dma_addr; ++ bce->saved_data_dma_ptr = dma_ptr; ++ bce->saved_data_dma_size = size; ++ return 0; ++ } else if (BCE_MB_TYPE(resp) == BCE_MB_SAVE_STATE_AND_SLEEP_FAILURE) { ++ dma_free_coherent(&bce->pci->dev, size, dma_ptr, dma_addr); ++ /* The 0x10ff magic value was extracted from Apple's driver */ ++ size = (BCE_MB_VALUE(resp) + 0x10ff) & ~(4096LLU - 1); ++ pr_debug("apple-bce: suspend: device requested a larger buffer (%li)\n", size); ++ continue; ++ } else { ++ pr_err("apple-bce: suspend failed (invalid device response)\n"); ++ status = -EINVAL; ++ break; ++ } ++ } ++ if (dma_ptr) ++ dma_free_coherent(&bce->pci->dev, size, dma_ptr, dma_addr); ++ if (!status) ++ return bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_SLEEP_NO_STATE, 0), &resp); ++ return status; ++} ++ ++static int bce_restore_state_and_wake(struct apple_bce_device *bce) ++{ ++ int status; ++ u64 resp; ++ if (!bce->saved_data_dma_ptr) { ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_RESTORE_NO_STATE, 0), &resp))) { ++ pr_err("apple-bce: resume with no state failed (mailbox send)\n"); ++ return status; ++ } ++ if (BCE_MB_TYPE(resp) != BCE_MB_RESTORE_NO_STATE) { ++ pr_err("apple-bce: resume with no state failed (invalid device response)\n"); ++ return -EINVAL; ++ } ++ return 0; ++ } ++ ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_RESTORE_STATE_AND_WAKE, ++ (bce->saved_data_dma_addr & ~(4096LLU - 1)) | (bce->saved_data_dma_size / 4096)), &resp))) { ++ pr_err("apple-bce: resume with state failed (mailbox send)\n"); ++ goto finish_with_state; ++ } ++ if (BCE_MB_TYPE(resp) != BCE_MB_SAVE_RESTORE_STATE_COMPLETE) { ++ pr_err("apple-bce: resume with state failed (invalid device response)\n"); ++ status = -EINVAL; ++ goto finish_with_state; ++ } ++ ++finish_with_state: ++ dma_free_coherent(&bce->pci->dev, bce->saved_data_dma_size, bce->saved_data_dma_ptr, bce->saved_data_dma_addr); ++ bce->saved_data_dma_ptr = NULL; ++ return status; ++} ++ ++static int apple_bce_suspend(struct device *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(to_pci_dev(dev)); ++ int status; ++ ++ bce_timestamp_stop(&bce->timestamp); ++ ++ if ((status = bce_save_state_and_sleep(bce))) ++ return status; ++ ++ return 0; ++} ++ ++static int apple_bce_resume(struct device *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(to_pci_dev(dev)); ++ int status; ++ ++ pci_set_master(bce->pci); ++ pci_set_master(bce->pci0); ++ ++ if ((status = bce_restore_state_and_wake(bce))) ++ return status; ++ ++ bce_timestamp_start(&bce->timestamp, false); ++ ++ return 0; ++} ++ ++static struct pci_device_id apple_bce_ids[ ] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x1801) }, ++ { 0, }, ++}; ++ ++MODULE_DEVICE_TABLE(pci, apple_bce_ids); ++ ++struct dev_pm_ops apple_bce_pci_driver_pm = { ++ .suspend = apple_bce_suspend, ++ .resume = apple_bce_resume ++}; ++struct pci_driver apple_bce_pci_driver = { ++ .name = "apple-bce", ++ .id_table = apple_bce_ids, ++ .probe = apple_bce_probe, ++ .remove = apple_bce_remove, ++ .driver = { ++ .pm = &apple_bce_pci_driver_pm ++ } ++}; ++ ++ ++static int __init apple_bce_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&bce_chrdev, 0, 1, "apple-bce"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ bce_class = class_create(THIS_MODULE, "apple-bce"); ++#else ++ bce_class = class_create("apple-bce"); ++#endif ++ if (IS_ERR(bce_class)) { ++ result = PTR_ERR(bce_class); ++ goto fail_class; ++ } ++ if ((result = bce_vhci_module_init())) { ++ pr_err("apple-bce: bce-vhci init failed"); ++ goto fail_class; ++ } ++ ++ result = pci_register_driver(&apple_bce_pci_driver); ++ if (result) ++ goto fail_drv; ++ ++ aaudio_module_init(); ++ ++ return 0; ++ ++fail_drv: ++ pci_unregister_driver(&apple_bce_pci_driver); ++fail_class: ++ class_destroy(bce_class); ++fail_chrdev: ++ unregister_chrdev_region(bce_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++static void __exit apple_bce_module_exit(void) ++{ ++ pci_unregister_driver(&apple_bce_pci_driver); ++ ++ aaudio_module_exit(); ++ bce_vhci_module_exit(); ++ class_destroy(bce_class); ++ unregister_chrdev_region(bce_chrdev, 1); ++} ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("MrARM"); ++MODULE_DESCRIPTION("Apple BCE Driver"); ++MODULE_VERSION("0.01"); ++module_init(apple_bce_module_init); ++module_exit(apple_bce_module_exit); +diff --git a/drivers/staging/apple-bce/apple_bce.h b/drivers/staging/apple-bce/apple_bce.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/apple_bce.h +@@ -0,0 +1,38 @@ ++#pragma once ++ ++#include ++#include ++#include "mailbox.h" ++#include "queue.h" ++#include "vhci/vhci.h" ++ ++#define BC_PROTOCOL_VERSION 0x20001 ++#define BCE_MAX_QUEUE_COUNT 0x100 ++ ++#define BCE_QUEUE_USER_MIN 2 ++#define BCE_QUEUE_USER_MAX (BCE_MAX_QUEUE_COUNT - 1) ++ ++struct apple_bce_device { ++ struct pci_dev *pci, *pci0; ++ dev_t devt; ++ struct device *dev; ++ void __iomem *reg_mem_mb; ++ void __iomem *reg_mem_dma; ++ struct bce_mailbox mbox; ++ struct bce_timestamp timestamp; ++ struct bce_queue *queues[BCE_MAX_QUEUE_COUNT]; ++ struct spinlock queues_lock; ++ struct ida queue_ida; ++ struct bce_queue_cq *cmd_cq; ++ struct bce_queue_cmdq *cmd_cmdq; ++ struct bce_queue_sq *int_sq_list[BCE_MAX_QUEUE_COUNT]; ++ bool is_being_removed; ++ ++ dma_addr_t saved_data_dma_addr; ++ void *saved_data_dma_ptr; ++ size_t saved_data_dma_size; ++ ++ struct bce_vhci vhci; ++}; ++ ++extern struct apple_bce_device *global_bce; +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/audio/audio.c b/drivers/staging/apple-bce/audio/audio.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/audio.c +@@ -0,0 +1,711 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "audio.h" ++#include "pcm.h" ++#include ++ ++static int aaudio_alsa_index = SNDRV_DEFAULT_IDX1; ++static char *aaudio_alsa_id = SNDRV_DEFAULT_STR1; ++ ++static dev_t aaudio_chrdev; ++static struct class *aaudio_class; ++ ++static int aaudio_init_cmd(struct aaudio_device *a); ++static int aaudio_init_bs(struct aaudio_device *a); ++static void aaudio_init_dev(struct aaudio_device *a, aaudio_device_id_t dev_id); ++static void aaudio_free_dev(struct aaudio_subdevice *sdev); ++ ++static int aaudio_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct aaudio_device *aaudio = NULL; ++ struct aaudio_subdevice *sdev = NULL; ++ int status = 0; ++ u32 cfg; ++ ++ pr_info("aaudio: capturing our device\n"); ++ ++ if (pci_enable_device(dev)) ++ return -ENODEV; ++ if (pci_request_regions(dev, "aaudio")) { ++ status = -ENODEV; ++ goto fail; ++ } ++ pci_set_master(dev); ++ ++ aaudio = kzalloc(sizeof(struct aaudio_device), GFP_KERNEL); ++ if (!aaudio) { ++ status = -ENOMEM; ++ goto fail; ++ } ++ ++ aaudio->bce = global_bce; ++ if (!aaudio->bce) { ++ dev_warn(&dev->dev, "aaudio: No BCE available\n"); ++ status = -EINVAL; ++ goto fail; ++ } ++ ++ aaudio->pci = dev; ++ pci_set_drvdata(dev, aaudio); ++ ++ aaudio->devt = aaudio_chrdev; ++ aaudio->dev = device_create(aaudio_class, &dev->dev, aaudio->devt, NULL, "aaudio"); ++ if (IS_ERR_OR_NULL(aaudio->dev)) { ++ status = PTR_ERR(aaudio_class); ++ goto fail; ++ } ++ device_link_add(aaudio->dev, aaudio->bce->dev, DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER); ++ ++ init_completion(&aaudio->remote_alive); ++ INIT_LIST_HEAD(&aaudio->subdevice_list); ++ ++ /* Init: set an unknown flag in the bitset */ ++ if (pci_read_config_dword(dev, 4, &cfg)) ++ dev_warn(&dev->dev, "aaudio: pci_read_config_dword fail\n"); ++ if (pci_write_config_dword(dev, 4, cfg | 6u)) ++ dev_warn(&dev->dev, "aaudio: pci_write_config_dword fail\n"); ++ ++ dev_info(aaudio->dev, "aaudio: bs len = %llx\n", pci_resource_len(dev, 0)); ++ aaudio->reg_mem_bs_dma = pci_resource_start(dev, 0); ++ aaudio->reg_mem_bs = pci_iomap(dev, 0, 0); ++ aaudio->reg_mem_cfg = pci_iomap(dev, 4, 0); ++ ++ aaudio->reg_mem_gpr = (u32 __iomem *) ((u8 __iomem *) aaudio->reg_mem_cfg + 0xC000); ++ ++ if (IS_ERR_OR_NULL(aaudio->reg_mem_bs) || IS_ERR_OR_NULL(aaudio->reg_mem_cfg)) { ++ dev_warn(&dev->dev, "aaudio: Failed to pci_iomap required regions\n"); ++ goto fail; ++ } ++ ++ if (aaudio_bce_init(aaudio)) { ++ dev_warn(&dev->dev, "aaudio: Failed to init BCE command transport\n"); ++ goto fail; ++ } ++ ++ if (snd_card_new(aaudio->dev, aaudio_alsa_index, aaudio_alsa_id, THIS_MODULE, 0, &aaudio->card)) { ++ dev_err(&dev->dev, "aaudio: Failed to create ALSA card\n"); ++ goto fail; ++ } ++ ++ strcpy(aaudio->card->shortname, "Apple T2 Audio"); ++ strcpy(aaudio->card->longname, "Apple T2 Audio"); ++ strcpy(aaudio->card->mixername, "Apple T2 Audio"); ++ /* Dynamic alsa ids start at 100 */ ++ aaudio->next_alsa_id = 100; ++ ++ if (aaudio_init_cmd(aaudio)) { ++ dev_err(&dev->dev, "aaudio: Failed to initialize over BCE\n"); ++ goto fail_snd; ++ } ++ ++ if (aaudio_init_bs(aaudio)) { ++ dev_err(&dev->dev, "aaudio: Failed to initialize BufferStruct\n"); ++ goto fail_snd; ++ } ++ ++ if ((status = aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_ON))) { ++ dev_err(&dev->dev, "Failed to set remote access\n"); ++ return status; ++ } ++ ++ if (snd_card_register(aaudio->card)) { ++ dev_err(&dev->dev, "aaudio: Failed to register ALSA sound device\n"); ++ goto fail_snd; ++ } ++ ++ list_for_each_entry(sdev, &aaudio->subdevice_list, list) { ++ struct aaudio_buffer_struct_device *dev = &aaudio->bs->devices[sdev->buf_id]; ++ ++ if (sdev->out_stream_cnt == 1 && !strcmp(dev->name, "Speaker")) { ++ struct snd_pcm_hardware *hw = sdev->out_streams[0].alsa_hw_desc; ++ ++ snprintf(aaudio->card->driver, sizeof(aaudio->card->driver) / sizeof(char), "AppleT2x%d", hw->channels_min); ++ } ++ } ++ ++ return 0; ++ ++fail_snd: ++ snd_card_free(aaudio->card); ++fail: ++ if (aaudio && aaudio->dev) ++ device_destroy(aaudio_class, aaudio->devt); ++ kfree(aaudio); ++ ++ if (!IS_ERR_OR_NULL(aaudio->reg_mem_bs)) ++ pci_iounmap(dev, aaudio->reg_mem_bs); ++ if (!IS_ERR_OR_NULL(aaudio->reg_mem_cfg)) ++ pci_iounmap(dev, aaudio->reg_mem_cfg); ++ ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++ ++ ++static void aaudio_remove(struct pci_dev *dev) ++{ ++ struct aaudio_subdevice *sdev; ++ struct aaudio_device *aaudio = pci_get_drvdata(dev); ++ ++ snd_card_free(aaudio->card); ++ while (!list_empty(&aaudio->subdevice_list)) { ++ sdev = list_first_entry(&aaudio->subdevice_list, struct aaudio_subdevice, list); ++ list_del(&sdev->list); ++ aaudio_free_dev(sdev); ++ } ++ pci_iounmap(dev, aaudio->reg_mem_bs); ++ pci_iounmap(dev, aaudio->reg_mem_cfg); ++ device_destroy(aaudio_class, aaudio->devt); ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ kfree(aaudio); ++} ++ ++static int aaudio_suspend(struct device *dev) ++{ ++ struct aaudio_device *aaudio = pci_get_drvdata(to_pci_dev(dev)); ++ ++ if (aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_OFF)) ++ dev_warn(aaudio->dev, "Failed to reset remote access\n"); ++ ++ pci_disable_device(aaudio->pci); ++ return 0; ++} ++ ++static int aaudio_resume(struct device *dev) ++{ ++ int status; ++ struct aaudio_device *aaudio = pci_get_drvdata(to_pci_dev(dev)); ++ ++ if ((status = pci_enable_device(aaudio->pci))) ++ return status; ++ pci_set_master(aaudio->pci); ++ ++ if ((status = aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_ON))) { ++ dev_err(aaudio->dev, "Failed to set remote access\n"); ++ return status; ++ } ++ ++ return 0; ++} ++ ++static int aaudio_init_cmd(struct aaudio_device *a) ++{ ++ int status; ++ struct aaudio_send_ctx sctx; ++ struct aaudio_msg buf; ++ u64 dev_cnt, dev_i; ++ aaudio_device_id_t *dev_l; ++ ++ if ((status = aaudio_send(a, &sctx, 500, ++ aaudio_msg_write_alive_notification, 1, 3))) { ++ dev_err(a->dev, "Sending alive notification failed\n"); ++ return status; ++ } ++ ++ if (wait_for_completion_timeout(&a->remote_alive, msecs_to_jiffies(500)) == 0) { ++ dev_err(a->dev, "Timed out waiting for remote\n"); ++ return -ETIMEDOUT; ++ } ++ dev_info(a->dev, "Continuing init\n"); ++ ++ buf = aaudio_reply_alloc(); ++ if ((status = aaudio_cmd_get_device_list(a, &buf, &dev_l, &dev_cnt))) { ++ dev_err(a->dev, "Failed to get device list\n"); ++ aaudio_reply_free(&buf); ++ return status; ++ } ++ for (dev_i = 0; dev_i < dev_cnt; ++dev_i) ++ aaudio_init_dev(a, dev_l[dev_i]); ++ aaudio_reply_free(&buf); ++ ++ return 0; ++} ++ ++static void aaudio_init_stream_info(struct aaudio_subdevice *sdev, struct aaudio_stream *strm); ++static void aaudio_handle_jack_connection_change(struct aaudio_subdevice *sdev); ++ ++static void aaudio_init_dev(struct aaudio_device *a, aaudio_device_id_t dev_id) ++{ ++ struct aaudio_subdevice *sdev; ++ struct aaudio_msg buf = aaudio_reply_alloc(); ++ u64 uid_len, stream_cnt, i; ++ aaudio_object_id_t *stream_list; ++ char *uid; ++ ++ sdev = kzalloc(sizeof(struct aaudio_subdevice), GFP_KERNEL); ++ ++ if (aaudio_cmd_get_property(a, &buf, dev_id, dev_id, AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_UID, 0), ++ NULL, 0, (void **) &uid, &uid_len) || uid_len > AAUDIO_DEVICE_MAX_UID_LEN) { ++ dev_err(a->dev, "Failed to get device uid for device %llx\n", dev_id); ++ goto fail; ++ } ++ dev_info(a->dev, "Remote device %llx %.*s\n", dev_id, (int) uid_len, uid); ++ ++ sdev->a = a; ++ INIT_LIST_HEAD(&sdev->list); ++ sdev->dev_id = dev_id; ++ sdev->buf_id = AAUDIO_BUFFER_ID_NONE; ++ strncpy(sdev->uid, uid, uid_len); ++ sdev->uid[uid_len + 1] = '\0'; ++ ++ if (aaudio_cmd_get_primitive_property(a, dev_id, dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_INPUT, AAUDIO_PROP_LATENCY, 0), NULL, 0, &sdev->in_latency, sizeof(u32))) ++ dev_warn(a->dev, "Failed to query device input latency\n"); ++ if (aaudio_cmd_get_primitive_property(a, dev_id, dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_LATENCY, 0), NULL, 0, &sdev->out_latency, sizeof(u32))) ++ dev_warn(a->dev, "Failed to query device output latency\n"); ++ ++ if (aaudio_cmd_get_input_stream_list(a, &buf, dev_id, &stream_list, &stream_cnt)) { ++ dev_err(a->dev, "Failed to get input stream list for device %llx\n", dev_id); ++ goto fail; ++ } ++ if (stream_cnt > AAUDIO_DEIVCE_MAX_INPUT_STREAMS) { ++ dev_warn(a->dev, "Device %s input stream count %llu is larger than the supported count of %u\n", ++ sdev->uid, stream_cnt, AAUDIO_DEIVCE_MAX_INPUT_STREAMS); ++ stream_cnt = AAUDIO_DEIVCE_MAX_INPUT_STREAMS; ++ } ++ sdev->in_stream_cnt = stream_cnt; ++ for (i = 0; i < stream_cnt; i++) { ++ sdev->in_streams[i].id = stream_list[i]; ++ sdev->in_streams[i].buffer_cnt = 0; ++ aaudio_init_stream_info(sdev, &sdev->in_streams[i]); ++ sdev->in_streams[i].latency += sdev->in_latency; ++ } ++ ++ if (aaudio_cmd_get_output_stream_list(a, &buf, dev_id, &stream_list, &stream_cnt)) { ++ dev_err(a->dev, "Failed to get output stream list for device %llx\n", dev_id); ++ goto fail; ++ } ++ if (stream_cnt > AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS) { ++ dev_warn(a->dev, "Device %s input stream count %llu is larger than the supported count of %u\n", ++ sdev->uid, stream_cnt, AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS); ++ stream_cnt = AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS; ++ } ++ sdev->out_stream_cnt = stream_cnt; ++ for (i = 0; i < stream_cnt; i++) { ++ sdev->out_streams[i].id = stream_list[i]; ++ sdev->out_streams[i].buffer_cnt = 0; ++ aaudio_init_stream_info(sdev, &sdev->out_streams[i]); ++ sdev->out_streams[i].latency += sdev->in_latency; ++ } ++ ++ if (sdev->is_pcm) ++ aaudio_create_pcm(sdev); ++ /* Headphone Jack status */ ++ if (!strcmp(sdev->uid, "Codec Output")) { ++ if (snd_jack_new(a->card, sdev->uid, SND_JACK_HEADPHONE, &sdev->jack, true, false)) ++ dev_warn(a->dev, "Failed to create an attached jack for %s\n", sdev->uid); ++ aaudio_cmd_property_listener(a, sdev->dev_id, sdev->dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_JACK_PLUGGED, 0)); ++ aaudio_handle_jack_connection_change(sdev); ++ } ++ ++ aaudio_reply_free(&buf); ++ ++ list_add_tail(&sdev->list, &a->subdevice_list); ++ return; ++ ++fail: ++ aaudio_reply_free(&buf); ++ kfree(sdev); ++} ++ ++static void aaudio_init_stream_info(struct aaudio_subdevice *sdev, struct aaudio_stream *strm) ++{ ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, strm->id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_PHYS_FORMAT, 0), NULL, 0, ++ &strm->desc, sizeof(strm->desc))) ++ dev_warn(sdev->a->dev, "Failed to query stream descriptor\n"); ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, strm->id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_LATENCY, 0), NULL, 0, &strm->latency, sizeof(u32))) ++ dev_warn(sdev->a->dev, "Failed to query stream latency\n"); ++ if (strm->desc.format_id == AAUDIO_FORMAT_LPCM) ++ sdev->is_pcm = true; ++} ++ ++static void aaudio_free_dev(struct aaudio_subdevice *sdev) ++{ ++ size_t i; ++ for (i = 0; i < sdev->in_stream_cnt; i++) { ++ if (sdev->in_streams[i].alsa_hw_desc) ++ kfree(sdev->in_streams[i].alsa_hw_desc); ++ if (sdev->in_streams[i].buffers) ++ kfree(sdev->in_streams[i].buffers); ++ } ++ for (i = 0; i < sdev->out_stream_cnt; i++) { ++ if (sdev->out_streams[i].alsa_hw_desc) ++ kfree(sdev->out_streams[i].alsa_hw_desc); ++ if (sdev->out_streams[i].buffers) ++ kfree(sdev->out_streams[i].buffers); ++ } ++ kfree(sdev); ++} ++ ++static struct aaudio_subdevice *aaudio_find_dev_by_dev_id(struct aaudio_device *a, aaudio_device_id_t dev_id) ++{ ++ struct aaudio_subdevice *sdev; ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (dev_id == sdev->dev_id) ++ return sdev; ++ } ++ return NULL; ++} ++ ++static struct aaudio_subdevice *aaudio_find_dev_by_uid(struct aaudio_device *a, const char *uid) ++{ ++ struct aaudio_subdevice *sdev; ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (!strcmp(uid, sdev->uid)) ++ return sdev; ++ } ++ return NULL; ++} ++ ++static void aaudio_init_bs_stream(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm); ++static void aaudio_init_bs_stream_host(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm); ++ ++static int aaudio_init_bs(struct aaudio_device *a) ++{ ++ int i, j; ++ struct aaudio_buffer_struct_device *dev; ++ struct aaudio_subdevice *sdev; ++ u32 ver, sig, bs_base; ++ ++ ver = ioread32(&a->reg_mem_gpr[0]); ++ if (ver < 3) { ++ dev_err(a->dev, "aaudio: Bad GPR version (%u)", ver); ++ return -EINVAL; ++ } ++ sig = ioread32(&a->reg_mem_gpr[1]); ++ if (sig != AAUDIO_SIG) { ++ dev_err(a->dev, "aaudio: Bad GPR sig (%x)", sig); ++ return -EINVAL; ++ } ++ bs_base = ioread32(&a->reg_mem_gpr[2]); ++ a->bs = (struct aaudio_buffer_struct *) ((u8 *) a->reg_mem_bs + bs_base); ++ if (a->bs->signature != AAUDIO_SIG) { ++ dev_err(a->dev, "aaudio: Bad BufferStruct sig (%x)", a->bs->signature); ++ return -EINVAL; ++ } ++ dev_info(a->dev, "aaudio: BufferStruct ver = %i\n", a->bs->version); ++ dev_info(a->dev, "aaudio: Num devices = %i\n", a->bs->num_devices); ++ for (i = 0; i < a->bs->num_devices; i++) { ++ dev = &a->bs->devices[i]; ++ dev_info(a->dev, "aaudio: Device %i %s\n", i, dev->name); ++ ++ sdev = aaudio_find_dev_by_uid(a, dev->name); ++ if (!sdev) { ++ dev_err(a->dev, "aaudio: Subdevice not found for BufferStruct device %s\n", dev->name); ++ continue; ++ } ++ sdev->buf_id = (u8) i; ++ dev->num_input_streams = 0; ++ for (j = 0; j < dev->num_output_streams; j++) { ++ dev_info(a->dev, "aaudio: Device %i Stream %i: Output; Buffer Count = %i\n", i, j, ++ dev->output_streams[j].num_buffers); ++ if (j < sdev->out_stream_cnt) ++ aaudio_init_bs_stream(a, &sdev->out_streams[j], &dev->output_streams[j]); ++ } ++ } ++ ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (sdev->buf_id != AAUDIO_BUFFER_ID_NONE) ++ continue; ++ sdev->buf_id = i; ++ dev_info(a->dev, "aaudio: Created device %i %s\n", i, sdev->uid); ++ strcpy(a->bs->devices[i].name, sdev->uid); ++ a->bs->devices[i].num_input_streams = 0; ++ a->bs->devices[i].num_output_streams = 0; ++ a->bs->num_devices = ++i; ++ } ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (sdev->in_stream_cnt == 1) { ++ dev_info(a->dev, "aaudio: Device %i Host Stream; Input\n", sdev->buf_id); ++ aaudio_init_bs_stream_host(a, &sdev->in_streams[0], &a->bs->devices[sdev->buf_id].input_streams[0]); ++ a->bs->devices[sdev->buf_id].num_input_streams = 1; ++ wmb(); ++ ++ if (aaudio_cmd_set_input_stream_address_ranges(a, sdev->dev_id)) { ++ dev_err(a->dev, "aaudio: Failed to set input stream address ranges\n"); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static void aaudio_init_bs_stream(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm) ++{ ++ size_t i; ++ strm->buffer_cnt = bs_strm->num_buffers; ++ if (bs_strm->num_buffers > AAUDIO_DEIVCE_MAX_BUFFER_COUNT) { ++ dev_warn(a->dev, "BufferStruct buffer count %u exceeds driver limit of %u\n", bs_strm->num_buffers, ++ AAUDIO_DEIVCE_MAX_BUFFER_COUNT); ++ strm->buffer_cnt = AAUDIO_DEIVCE_MAX_BUFFER_COUNT; ++ } ++ if (!strm->buffer_cnt) ++ return; ++ strm->buffers = kmalloc_array(strm->buffer_cnt, sizeof(struct aaudio_dma_buf), GFP_KERNEL); ++ if (!strm->buffers) { ++ dev_err(a->dev, "Buffer list allocation failed\n"); ++ return; ++ } ++ for (i = 0; i < strm->buffer_cnt; i++) { ++ strm->buffers[i].dma_addr = a->reg_mem_bs_dma + (dma_addr_t) bs_strm->buffers[i].address; ++ strm->buffers[i].ptr = a->reg_mem_bs + bs_strm->buffers[i].address; ++ strm->buffers[i].size = bs_strm->buffers[i].size; ++ } ++ ++ if (strm->buffer_cnt == 1) { ++ strm->alsa_hw_desc = kmalloc(sizeof(struct snd_pcm_hardware), GFP_KERNEL); ++ if (aaudio_create_hw_info(&strm->desc, strm->alsa_hw_desc, strm->buffers[0].size)) { ++ kfree(strm->alsa_hw_desc); ++ strm->alsa_hw_desc = NULL; ++ } ++ } ++} ++ ++static void aaudio_init_bs_stream_host(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm) ++{ ++ size_t size; ++ dma_addr_t dma_addr; ++ void *dma_ptr; ++ size = strm->desc.bytes_per_packet * 16640; ++ dma_ptr = dma_alloc_coherent(&a->pci->dev, size, &dma_addr, GFP_KERNEL); ++ if (!dma_ptr) { ++ dev_err(a->dev, "dma_alloc_coherent failed\n"); ++ return; ++ } ++ bs_strm->buffers[0].address = dma_addr; ++ bs_strm->buffers[0].size = size; ++ bs_strm->num_buffers = 1; ++ ++ memset(dma_ptr, 0, size); ++ ++ strm->buffer_cnt = 1; ++ strm->buffers = kmalloc_array(strm->buffer_cnt, sizeof(struct aaudio_dma_buf), GFP_KERNEL); ++ if (!strm->buffers) { ++ dev_err(a->dev, "Buffer list allocation failed\n"); ++ return; ++ } ++ strm->buffers[0].dma_addr = dma_addr; ++ strm->buffers[0].ptr = dma_ptr; ++ strm->buffers[0].size = size; ++ ++ strm->alsa_hw_desc = kmalloc(sizeof(struct snd_pcm_hardware), GFP_KERNEL); ++ if (aaudio_create_hw_info(&strm->desc, strm->alsa_hw_desc, strm->buffers[0].size)) { ++ kfree(strm->alsa_hw_desc); ++ strm->alsa_hw_desc = NULL; ++ } ++} ++ ++static void aaudio_handle_prop_change(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++void aaudio_handle_notification(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_send_ctx sctx; ++ struct aaudio_msg_base base; ++ if (aaudio_msg_read_base(msg, &base)) ++ return; ++ switch (base.msg) { ++ case AAUDIO_MSG_NOTIFICATION_BOOT: ++ dev_info(a->dev, "Received boot notification from remote\n"); ++ ++ /* Resend the alive notify */ ++ if (aaudio_send(a, &sctx, 500, ++ aaudio_msg_write_alive_notification, 1, 3)) { ++ pr_err("Sending alive notification failed\n"); ++ } ++ break; ++ case AAUDIO_MSG_NOTIFICATION_ALIVE: ++ dev_info(a->dev, "Received alive notification from remote\n"); ++ complete_all(&a->remote_alive); ++ break; ++ case AAUDIO_MSG_PROPERTY_CHANGED: ++ aaudio_handle_prop_change(a, msg); ++ break; ++ default: ++ dev_info(a->dev, "Unhandled notification %i", base.msg); ++ break; ++ } ++} ++ ++struct aaudio_prop_change_work_struct { ++ struct work_struct ws; ++ struct aaudio_device *a; ++ aaudio_device_id_t dev; ++ aaudio_object_id_t obj; ++ struct aaudio_prop_addr prop; ++}; ++ ++static void aaudio_handle_jack_connection_change(struct aaudio_subdevice *sdev) ++{ ++ u32 plugged; ++ if (!sdev->jack) ++ return; ++ /* NOTE: Apple made the plug status scoped to the input and output streams. This makes no sense for us, so I just ++ * always pick the OUTPUT status. */ ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, sdev->dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_JACK_PLUGGED, 0), NULL, 0, &plugged, sizeof(plugged))) { ++ dev_err(sdev->a->dev, "Failed to get jack enable status\n"); ++ return; ++ } ++ dev_dbg(sdev->a->dev, "Jack is now %s\n", plugged ? "plugged" : "unplugged"); ++ snd_jack_report(sdev->jack, plugged ? sdev->jack->type : 0); ++} ++ ++void aaudio_handle_prop_change_work(struct work_struct *ws) ++{ ++ struct aaudio_prop_change_work_struct *work = container_of(ws, struct aaudio_prop_change_work_struct, ws); ++ struct aaudio_subdevice *sdev; ++ ++ sdev = aaudio_find_dev_by_dev_id(work->a, work->dev); ++ if (!sdev) { ++ dev_err(work->a->dev, "Property notification change: device not found\n"); ++ goto done; ++ } ++ dev_dbg(work->a->dev, "Property changed for device: %s\n", sdev->uid); ++ ++ if (work->prop.scope == AAUDIO_PROP_SCOPE_OUTPUT && work->prop.selector == AAUDIO_PROP_JACK_PLUGGED) { ++ aaudio_handle_jack_connection_change(sdev); ++ } ++ ++done: ++ kfree(work); ++} ++ ++void aaudio_handle_prop_change(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ /* NOTE: This is a scheduled work because this callback will generally need to query device information and this ++ * is not possible when we are in the reply parsing code's context. */ ++ struct aaudio_prop_change_work_struct *work; ++ work = kmalloc(sizeof(struct aaudio_prop_change_work_struct), GFP_KERNEL); ++ work->a = a; ++ INIT_WORK(&work->ws, aaudio_handle_prop_change_work); ++ aaudio_msg_read_property_changed(msg, &work->dev, &work->obj, &work->prop); ++ schedule_work(&work->ws); ++} ++ ++#define aaudio_send_cmd_response(a, sctx, msg, fn, ...) \ ++ if (aaudio_send_with_tag(a, sctx, ((struct aaudio_msg_header *) msg->data)->tag, 500, fn, ##__VA_ARGS__)) \ ++ pr_err("aaudio: Failed to reply to a command\n"); ++ ++void aaudio_handle_cmd_timestamp(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ ktime_t time_os = ktime_get_boottime(); ++ struct aaudio_send_ctx sctx; ++ struct aaudio_subdevice *sdev; ++ u64 devid, timestamp, update_seed; ++ aaudio_msg_read_update_timestamp(msg, &devid, ×tamp, &update_seed); ++ dev_dbg(a->dev, "Received timestamp update for dev=%llx ts=%llx seed=%llx\n", devid, timestamp, update_seed); ++ ++ sdev = aaudio_find_dev_by_dev_id(a, devid); ++ aaudio_handle_timestamp(sdev, time_os, timestamp); ++ ++ aaudio_send_cmd_response(a, &sctx, msg, ++ aaudio_msg_write_update_timestamp_response); ++} ++ ++void aaudio_handle_command(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_msg_base base; ++ if (aaudio_msg_read_base(msg, &base)) ++ return; ++ switch (base.msg) { ++ case AAUDIO_MSG_UPDATE_TIMESTAMP: ++ aaudio_handle_cmd_timestamp(a, msg); ++ break; ++ default: ++ dev_info(a->dev, "Unhandled device command %i", base.msg); ++ break; ++ } ++} ++ ++static struct pci_device_id aaudio_ids[ ] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x1803) }, ++ { 0, }, ++}; ++ ++struct dev_pm_ops aaudio_pci_driver_pm = { ++ .suspend = aaudio_suspend, ++ .resume = aaudio_resume ++}; ++struct pci_driver aaudio_pci_driver = { ++ .name = "aaudio", ++ .id_table = aaudio_ids, ++ .probe = aaudio_probe, ++ .remove = aaudio_remove, ++ .driver = { ++ .pm = &aaudio_pci_driver_pm ++ } ++}; ++ ++ ++int aaudio_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&aaudio_chrdev, 0, 1, "aaudio"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ aaudio_class = class_create(THIS_MODULE, "aaudio"); ++#else ++ aaudio_class = class_create("aaudio"); ++#endif ++ if (IS_ERR(aaudio_class)) { ++ result = PTR_ERR(aaudio_class); ++ goto fail_class; ++ } ++ ++ result = pci_register_driver(&aaudio_pci_driver); ++ if (result) ++ goto fail_drv; ++ return 0; ++ ++fail_drv: ++ pci_unregister_driver(&aaudio_pci_driver); ++fail_class: ++ class_destroy(aaudio_class); ++fail_chrdev: ++ unregister_chrdev_region(aaudio_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++ ++void aaudio_module_exit(void) ++{ ++ pci_unregister_driver(&aaudio_pci_driver); ++ class_destroy(aaudio_class); ++ unregister_chrdev_region(aaudio_chrdev, 1); ++} ++ ++struct aaudio_alsa_pcm_id_mapping aaudio_alsa_id_mappings[] = { ++ {"Speaker", 0}, ++ {"Digital Mic", 1}, ++ {"Codec Output", 2}, ++ {"Codec Input", 3}, ++ {"Bridge Loopback", 4}, ++ {} ++}; ++ ++module_param_named(index, aaudio_alsa_index, int, 0444); ++MODULE_PARM_DESC(index, "Index value for Apple Internal Audio soundcard."); ++module_param_named(id, aaudio_alsa_id, charp, 0444); ++MODULE_PARM_DESC(id, "ID string for Apple Internal Audio soundcard."); +diff --git a/drivers/staging/apple-bce/audio/audio.h b/drivers/staging/apple-bce/audio/audio.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/audio.h +@@ -0,0 +1,125 @@ ++#ifndef AAUDIO_H ++#define AAUDIO_H ++ ++#include ++#include ++#include "../apple_bce.h" ++#include "protocol_bce.h" ++#include "description.h" ++ ++#define AAUDIO_SIG 0x19870423 ++ ++#define AAUDIO_DEVICE_MAX_UID_LEN 128 ++#define AAUDIO_DEIVCE_MAX_INPUT_STREAMS 1 ++#define AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS 1 ++#define AAUDIO_DEIVCE_MAX_BUFFER_COUNT 1 ++ ++#define AAUDIO_BUFFER_ID_NONE 0xffu ++ ++struct snd_card; ++struct snd_pcm; ++struct snd_pcm_hardware; ++struct snd_jack; ++ ++struct __attribute__((packed)) __attribute__((aligned(4))) aaudio_buffer_struct_buffer { ++ size_t address; ++ size_t size; ++ size_t pad[4]; ++}; ++struct aaudio_buffer_struct_stream { ++ u8 num_buffers; ++ struct aaudio_buffer_struct_buffer buffers[100]; ++ char filler[32]; ++}; ++struct aaudio_buffer_struct_device { ++ char name[128]; ++ u8 num_input_streams; ++ u8 num_output_streams; ++ struct aaudio_buffer_struct_stream input_streams[5]; ++ struct aaudio_buffer_struct_stream output_streams[5]; ++ char filler[128]; ++}; ++struct aaudio_buffer_struct { ++ u32 version; ++ u32 signature; ++ u32 flags; ++ u8 num_devices; ++ struct aaudio_buffer_struct_device devices[20]; ++}; ++ ++struct aaudio_device; ++struct aaudio_dma_buf { ++ dma_addr_t dma_addr; ++ void *ptr; ++ size_t size; ++}; ++struct aaudio_stream { ++ aaudio_object_id_t id; ++ size_t buffer_cnt; ++ struct aaudio_dma_buf *buffers; ++ ++ struct aaudio_apple_description desc; ++ struct snd_pcm_hardware *alsa_hw_desc; ++ u32 latency; ++ ++ bool waiting_for_first_ts; ++ ++ ktime_t remote_timestamp; ++ snd_pcm_sframes_t frame_min; ++ int started; ++}; ++struct aaudio_subdevice { ++ struct aaudio_device *a; ++ struct list_head list; ++ aaudio_device_id_t dev_id; ++ u32 in_latency, out_latency; ++ u8 buf_id; ++ int alsa_id; ++ char uid[AAUDIO_DEVICE_MAX_UID_LEN + 1]; ++ size_t in_stream_cnt; ++ struct aaudio_stream in_streams[AAUDIO_DEIVCE_MAX_INPUT_STREAMS]; ++ size_t out_stream_cnt; ++ struct aaudio_stream out_streams[AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS]; ++ bool is_pcm; ++ struct snd_pcm *pcm; ++ struct snd_jack *jack; ++}; ++struct aaudio_alsa_pcm_id_mapping { ++ const char *name; ++ int alsa_id; ++}; ++ ++struct aaudio_device { ++ struct pci_dev *pci; ++ dev_t devt; ++ struct device *dev; ++ void __iomem *reg_mem_bs; ++ dma_addr_t reg_mem_bs_dma; ++ void __iomem *reg_mem_cfg; ++ ++ u32 __iomem *reg_mem_gpr; ++ ++ struct aaudio_buffer_struct *bs; ++ ++ struct apple_bce_device *bce; ++ struct aaudio_bce bcem; ++ ++ struct snd_card *card; ++ ++ struct list_head subdevice_list; ++ int next_alsa_id; ++ ++ struct completion remote_alive; ++}; ++ ++void aaudio_handle_notification(struct aaudio_device *a, struct aaudio_msg *msg); ++void aaudio_handle_prop_change_work(struct work_struct *ws); ++void aaudio_handle_cmd_timestamp(struct aaudio_device *a, struct aaudio_msg *msg); ++void aaudio_handle_command(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++int aaudio_module_init(void); ++void aaudio_module_exit(void); ++ ++extern struct aaudio_alsa_pcm_id_mapping aaudio_alsa_id_mappings[]; ++ ++#endif //AAUDIO_H +diff --git a/drivers/staging/apple-bce/audio/description.h b/drivers/staging/apple-bce/audio/description.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/description.h +@@ -0,0 +1,42 @@ ++#ifndef AAUDIO_DESCRIPTION_H ++#define AAUDIO_DESCRIPTION_H ++ ++#include ++ ++struct aaudio_apple_description { ++ u64 sample_rate_double; ++ u32 format_id; ++ u32 format_flags; ++ u32 bytes_per_packet; ++ u32 frames_per_packet; ++ u32 bytes_per_frame; ++ u32 channels_per_frame; ++ u32 bits_per_channel; ++ u32 reserved; ++}; ++ ++enum { ++ AAUDIO_FORMAT_LPCM = 0x6c70636d // 'lpcm' ++}; ++ ++enum { ++ AAUDIO_FORMAT_FLAG_FLOAT = 1, ++ AAUDIO_FORMAT_FLAG_BIG_ENDIAN = 2, ++ AAUDIO_FORMAT_FLAG_SIGNED = 4, ++ AAUDIO_FORMAT_FLAG_PACKED = 8, ++ AAUDIO_FORMAT_FLAG_ALIGNED_HIGH = 16, ++ AAUDIO_FORMAT_FLAG_NON_INTERLEAVED = 32, ++ AAUDIO_FORMAT_FLAG_NON_MIXABLE = 64 ++}; ++ ++static inline u64 aaudio_double_to_u64(u64 d) ++{ ++ u8 sign = (u8) ((d >> 63) & 1); ++ s32 exp = (s32) ((d >> 52) & 0x7ff) - 1023; ++ u64 fr = d & ((1LL << 52) - 1); ++ if (sign || exp < 0) ++ return 0; ++ return (u64) ((1LL << exp) + (fr >> (52 - exp))); ++} ++ ++#endif //AAUDIO_DESCRIPTION_H +diff --git a/drivers/staging/apple-bce/audio/pcm.c b/drivers/staging/apple-bce/audio/pcm.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/pcm.c +@@ -0,0 +1,308 @@ ++#include "pcm.h" ++#include "audio.h" ++ ++static u64 aaudio_get_alsa_fmtbit(struct aaudio_apple_description *desc) ++{ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_FLOAT) { ++ if (desc->bits_per_channel == 32) { ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) ++ return SNDRV_PCM_FMTBIT_FLOAT_BE; ++ else ++ return SNDRV_PCM_FMTBIT_FLOAT_LE; ++ } else if (desc->bits_per_channel == 64) { ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) ++ return SNDRV_PCM_FMTBIT_FLOAT64_BE; ++ else ++ return SNDRV_PCM_FMTBIT_FLOAT64_LE; ++ } else { ++ pr_err("aaudio: unsupported bits per channel for float format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++#define DEFINE_BPC_OPTION(val, b) \ ++ case val: \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) { \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) \ ++ return SNDRV_PCM_FMTBIT_S ## b ## BE; \ ++ else \ ++ return SNDRV_PCM_FMTBIT_U ## b ## BE; \ ++ } else { \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) \ ++ return SNDRV_PCM_FMTBIT_S ## b ## LE; \ ++ else \ ++ return SNDRV_PCM_FMTBIT_U ## b ## LE; \ ++ } ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_PACKED) { ++ switch (desc->bits_per_channel) { ++ case 8: ++ case 16: ++ case 32: ++ break; ++ DEFINE_BPC_OPTION(24, 24_3) ++ default: ++ pr_err("aaudio: unsupported bits per channel for packed format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_ALIGNED_HIGH) { ++ switch (desc->bits_per_channel) { ++ DEFINE_BPC_OPTION(24, 32_) ++ default: ++ pr_err("aaudio: unsupported bits per channel for high-aligned format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++ switch (desc->bits_per_channel) { ++ case 8: ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) ++ return SNDRV_PCM_FMTBIT_S8; ++ else ++ return SNDRV_PCM_FMTBIT_U8; ++ DEFINE_BPC_OPTION(16, 16_) ++ DEFINE_BPC_OPTION(24, 24_) ++ DEFINE_BPC_OPTION(32, 32_) ++ default: ++ pr_err("aaudio: unsupported bits per channel: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++} ++int aaudio_create_hw_info(struct aaudio_apple_description *desc, struct snd_pcm_hardware *alsa_hw, ++ size_t buf_size) ++{ ++ uint rate; ++ alsa_hw->info = (SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_DOUBLE); ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_NON_MIXABLE) ++ pr_warn("aaudio: unsupported hw flag: NON_MIXABLE\n"); ++ if (!(desc->format_flags & AAUDIO_FORMAT_FLAG_NON_INTERLEAVED)) ++ alsa_hw->info |= SNDRV_PCM_INFO_INTERLEAVED; ++ alsa_hw->formats = aaudio_get_alsa_fmtbit(desc); ++ if (!alsa_hw->formats) ++ return -EINVAL; ++ rate = (uint) aaudio_double_to_u64(desc->sample_rate_double); ++ alsa_hw->rates = snd_pcm_rate_to_rate_bit(rate); ++ alsa_hw->rate_min = rate; ++ alsa_hw->rate_max = rate; ++ alsa_hw->channels_min = desc->channels_per_frame; ++ alsa_hw->channels_max = desc->channels_per_frame; ++ alsa_hw->buffer_bytes_max = buf_size; ++ alsa_hw->period_bytes_min = desc->bytes_per_packet; ++ alsa_hw->period_bytes_max = desc->bytes_per_packet; ++ alsa_hw->periods_min = (uint) (buf_size / desc->bytes_per_packet); ++ alsa_hw->periods_max = (uint) (buf_size / desc->bytes_per_packet); ++ pr_debug("aaudio_create_hw_info: format = %llu, rate = %u/%u. channels = %u, periods = %u, period size = %lu\n", ++ alsa_hw->formats, alsa_hw->rate_min, alsa_hw->rates, alsa_hw->channels_min, alsa_hw->periods_min, ++ alsa_hw->period_bytes_min); ++ return 0; ++} ++ ++static struct aaudio_stream *aaudio_pcm_stream(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ return &sdev->out_streams[substream->number]; ++ else ++ return &sdev->in_streams[substream->number]; ++} ++ ++static int aaudio_pcm_open(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_open\n"); ++ substream->runtime->hw = *aaudio_pcm_stream(substream)->alsa_hw_desc; ++ ++ return 0; ++} ++ ++static int aaudio_pcm_close(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_close\n"); ++ return 0; ++} ++ ++static int aaudio_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ return 0; ++} ++ ++static int aaudio_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) ++{ ++ struct aaudio_stream *astream = aaudio_pcm_stream(substream); ++ pr_debug("aaudio_pcm_hw_params\n"); ++ ++ if (!astream->buffer_cnt || !astream->buffers) ++ return -EINVAL; ++ ++ substream->runtime->dma_area = astream->buffers[0].ptr; ++ substream->runtime->dma_addr = astream->buffers[0].dma_addr; ++ substream->runtime->dma_bytes = astream->buffers[0].size; ++ return 0; ++} ++ ++static int aaudio_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_hw_free\n"); ++ return 0; ++} ++ ++static void aaudio_pcm_start(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ void *buf; ++ size_t s; ++ ktime_t time_start, time_end; ++ bool back_buffer; ++ time_start = ktime_get(); ++ ++ back_buffer = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); ++ ++ if (back_buffer) { ++ s = frames_to_bytes(substream->runtime, substream->runtime->control->appl_ptr); ++ buf = kmalloc(s, GFP_KERNEL); ++ memcpy_fromio(buf, substream->runtime->dma_area, s); ++ time_end = ktime_get(); ++ pr_debug("aaudio: Backed up the buffer in %lluns [%li]\n", ktime_to_ns(time_end - time_start), ++ substream->runtime->control->appl_ptr); ++ } ++ ++ stream->waiting_for_first_ts = true; ++ stream->frame_min = stream->latency; ++ ++ aaudio_cmd_start_io(sdev->a, sdev->dev_id); ++ if (back_buffer) ++ memcpy_toio(substream->runtime->dma_area, buf, s); ++ ++ time_end = ktime_get(); ++ pr_debug("aaudio: Started the audio device in %lluns\n", ktime_to_ns(time_end - time_start)); ++} ++ ++static int aaudio_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ pr_debug("aaudio_pcm_trigger %x\n", cmd); ++ ++ /* We only supports triggers on the #0 buffer */ ++ if (substream->number != 0) ++ return 0; ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ aaudio_pcm_start(substream); ++ stream->started = 1; ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ aaudio_cmd_stop_io(sdev->a, sdev->dev_id); ++ stream->started = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static snd_pcm_uframes_t aaudio_pcm_pointer(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ ktime_t time_from_start; ++ snd_pcm_sframes_t frames; ++ snd_pcm_sframes_t buffer_time_length; ++ ++ if (!stream->started || stream->waiting_for_first_ts) { ++ pr_warn("aaudio_pcm_pointer while not started\n"); ++ return 0; ++ } ++ ++ /* Approximate the pointer based on the last received timestamp */ ++ time_from_start = ktime_get_boottime() - stream->remote_timestamp; ++ buffer_time_length = NSEC_PER_SEC * substream->runtime->buffer_size / substream->runtime->rate; ++ frames = (ktime_to_ns(time_from_start) % buffer_time_length) * substream->runtime->buffer_size / buffer_time_length; ++ if (ktime_to_ns(time_from_start) < buffer_time_length) { ++ if (frames < stream->frame_min) ++ frames = stream->frame_min; ++ else ++ stream->frame_min = 0; ++ } else { ++ if (ktime_to_ns(time_from_start) < 2 * buffer_time_length) ++ stream->frame_min = frames; ++ else ++ stream->frame_min = 0; /* Heavy desync */ ++ } ++ frames -= stream->latency; ++ if (frames < 0) ++ frames += ((-frames - 1) / substream->runtime->buffer_size + 1) * substream->runtime->buffer_size; ++ return (snd_pcm_uframes_t) frames; ++} ++ ++static struct snd_pcm_ops aaudio_pcm_ops = { ++ .open = aaudio_pcm_open, ++ .close = aaudio_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = aaudio_pcm_hw_params, ++ .hw_free = aaudio_pcm_hw_free, ++ .prepare = aaudio_pcm_prepare, ++ .trigger = aaudio_pcm_trigger, ++ .pointer = aaudio_pcm_pointer, ++ .mmap = snd_pcm_lib_mmap_iomem ++}; ++ ++int aaudio_create_pcm(struct aaudio_subdevice *sdev) ++{ ++ struct snd_pcm *pcm; ++ struct aaudio_alsa_pcm_id_mapping *id_mapping; ++ int err; ++ ++ if (!sdev->is_pcm || (sdev->in_stream_cnt == 0 && sdev->out_stream_cnt == 0)) { ++ return -EINVAL; ++ } ++ ++ for (id_mapping = aaudio_alsa_id_mappings; id_mapping->name; id_mapping++) { ++ if (!strcmp(sdev->uid, id_mapping->name)) { ++ sdev->alsa_id = id_mapping->alsa_id; ++ break; ++ } ++ } ++ if (!id_mapping->name) ++ sdev->alsa_id = sdev->a->next_alsa_id++; ++ err = snd_pcm_new(sdev->a->card, sdev->uid, sdev->alsa_id, ++ (int) sdev->out_stream_cnt, (int) sdev->in_stream_cnt, &pcm); ++ if (err < 0) ++ return err; ++ pcm->private_data = sdev; ++ pcm->nonatomic = 1; ++ sdev->pcm = pcm; ++ strcpy(pcm->name, sdev->uid); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaudio_pcm_ops); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaudio_pcm_ops); ++ return 0; ++} ++ ++static void aaudio_handle_stream_timestamp(struct snd_pcm_substream *substream, ktime_t timestamp) ++{ ++ unsigned long flags; ++ struct aaudio_stream *stream; ++ ++ stream = aaudio_pcm_stream(substream); ++ snd_pcm_stream_lock_irqsave(substream, flags); ++ stream->remote_timestamp = timestamp; ++ if (stream->waiting_for_first_ts) { ++ stream->waiting_for_first_ts = false; ++ snd_pcm_stream_unlock_irqrestore(substream, flags); ++ return; ++ } ++ snd_pcm_stream_unlock_irqrestore(substream, flags); ++ snd_pcm_period_elapsed(substream); ++} ++ ++void aaudio_handle_timestamp(struct aaudio_subdevice *sdev, ktime_t os_timestamp, u64 dev_timestamp) ++{ ++ struct snd_pcm_substream *substream; ++ ++ substream = sdev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; ++ if (substream) ++ aaudio_handle_stream_timestamp(substream, dev_timestamp); ++ substream = sdev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; ++ if (substream) ++ aaudio_handle_stream_timestamp(substream, os_timestamp); ++} +diff --git a/drivers/staging/apple-bce/audio/pcm.h b/drivers/staging/apple-bce/audio/pcm.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/pcm.h +@@ -0,0 +1,16 @@ ++#ifndef AAUDIO_PCM_H ++#define AAUDIO_PCM_H ++ ++#include ++#include ++ ++struct aaudio_subdevice; ++struct aaudio_apple_description; ++struct snd_pcm_hardware; ++ ++int aaudio_create_hw_info(struct aaudio_apple_description *desc, struct snd_pcm_hardware *alsa_hw, size_t buf_size); ++int aaudio_create_pcm(struct aaudio_subdevice *sdev); ++ ++void aaudio_handle_timestamp(struct aaudio_subdevice *sdev, ktime_t os_timestamp, u64 dev_timestamp); ++ ++#endif //AAUDIO_PCM_H +diff --git a/drivers/staging/apple-bce/audio/protocol.c b/drivers/staging/apple-bce/audio/protocol.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol.c +@@ -0,0 +1,347 @@ ++#include "protocol.h" ++#include "protocol_bce.h" ++#include "audio.h" ++ ++int aaudio_msg_read_base(struct aaudio_msg *msg, struct aaudio_msg_base *base) ++{ ++ if (msg->size < sizeof(struct aaudio_msg_header) + sizeof(struct aaudio_msg_base) * 2) ++ return -EINVAL; ++ *base = *((struct aaudio_msg_base *) ((struct aaudio_msg_header *) msg->data + 1)); ++ return 0; ++} ++ ++#define READ_START(type) \ ++ size_t offset = sizeof(struct aaudio_msg_header) + sizeof(struct aaudio_msg_base); (void)offset; \ ++ if (((struct aaudio_msg_base *) ((struct aaudio_msg_header *) msg->data + 1))->msg != type) \ ++ return -EINVAL; ++#define READ_DEVID_VAR(devid) *devid = ((struct aaudio_msg_header *) msg->data)->device_id ++#define READ_VAL(type) ({ offset += sizeof(type); *((type *) ((u8 *) msg->data + offset - sizeof(type))); }) ++#define READ_VAR(type, var) *var = READ_VAL(type) ++ ++int aaudio_msg_read_start_io_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_START_IO_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_stop_io_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_STOP_IO_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_update_timestamp(struct aaudio_msg *msg, aaudio_device_id_t *devid, ++ u64 *timestamp, u64 *update_seed) ++{ ++ READ_START(AAUDIO_MSG_UPDATE_TIMESTAMP); ++ READ_DEVID_VAR(devid); ++ READ_VAR(u64, timestamp); ++ READ_VAR(u64, update_seed); ++ return 0; ++} ++ ++int aaudio_msg_read_get_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop, void **data, u64 *data_size) ++{ ++ READ_START(AAUDIO_MSG_GET_PROPERTY_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ READ_VAR(u64, data_size); ++ *data = ((u8 *) msg->data + offset); ++ /* offset += data_size; */ ++ return 0; ++} ++ ++int aaudio_msg_read_set_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj) ++{ ++ READ_START(AAUDIO_MSG_SET_PROPERTY_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ return 0; ++} ++ ++int aaudio_msg_read_property_listener_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop) ++{ ++ READ_START(AAUDIO_MSG_PROPERTY_LISTENER_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ return 0; ++} ++ ++int aaudio_msg_read_property_changed(struct aaudio_msg *msg, aaudio_device_id_t *devid, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop) ++{ ++ READ_START(AAUDIO_MSG_PROPERTY_CHANGED); ++ READ_DEVID_VAR(devid); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ return 0; ++} ++ ++int aaudio_msg_read_set_input_stream_address_ranges_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_get_input_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_INPUT_STREAM_LIST_RESPONSE); ++ READ_VAR(u64, str_cnt); ++ *str_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += str_cnt * sizeof(aaudio_object_id_t); */ ++ return 0; ++} ++ ++int aaudio_msg_read_get_output_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_OUTPUT_STREAM_LIST_RESPONSE); ++ READ_VAR(u64, str_cnt); ++ *str_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += str_cnt * sizeof(aaudio_object_id_t); */ ++ return 0; ++} ++ ++int aaudio_msg_read_set_remote_access_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_SET_REMOTE_ACCESS_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_get_device_list_response(struct aaudio_msg *msg, aaudio_device_id_t **dev_l, u64 *dev_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_DEVICE_LIST_RESPONSE); ++ READ_VAR(u64, dev_cnt); ++ *dev_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += dev_cnt * sizeof(aaudio_device_id_t); */ ++ return 0; ++} ++ ++#define WRITE_START_OF_TYPE(typev, devid) \ ++ size_t offset = sizeof(struct aaudio_msg_header); (void) offset; \ ++ ((struct aaudio_msg_header *) msg->data)->type = (typev); \ ++ ((struct aaudio_msg_header *) msg->data)->device_id = (devid); ++#define WRITE_START_COMMAND(devid) WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_COMMAND, devid) ++#define WRITE_START_RESPONSE() WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_RESPONSE, 0) ++#define WRITE_START_NOTIFICATION() WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_NOTIFICATION, 0) ++#define WRITE_VAL(type, value) { *((type *) ((u8 *) msg->data + offset)) = value; offset += sizeof(value); } ++#define WRITE_BIN(value, size) { memcpy((u8 *) msg->data + offset, value, size); offset += size; } ++#define WRITE_BASE(type) WRITE_VAL(u32, type) WRITE_VAL(u32, 0) ++#define WRITE_END() { msg->size = offset; } ++ ++void aaudio_msg_write_start_io(struct aaudio_msg *msg, aaudio_device_id_t dev) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_START_IO); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_stop_io(struct aaudio_msg *msg, aaudio_device_id_t dev) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_STOP_IO); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_GET_PROPERTY); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_VAL(u64, qualifier_size); ++ WRITE_BIN(qualifier, qualifier_size); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *data, u64 data_size, void *qualifier, u64 qualifier_size) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_SET_PROPERTY); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_VAL(u64, data_size); ++ WRITE_BIN(data, data_size); ++ WRITE_VAL(u64, qualifier_size); ++ WRITE_BIN(qualifier, qualifier_size); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_property_listener(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_PROPERTY_LISTENER); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_input_stream_address_ranges(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_input_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_GET_INPUT_STREAM_LIST); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_output_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_GET_OUTPUT_STREAM_LIST); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_remote_access(struct aaudio_msg *msg, u64 mode) ++{ ++ WRITE_START_COMMAND(0); ++ WRITE_BASE(AAUDIO_MSG_SET_REMOTE_ACCESS); ++ WRITE_VAL(u64, mode); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_alive_notification(struct aaudio_msg *msg, u32 proto_ver, u32 msg_ver) ++{ ++ WRITE_START_NOTIFICATION(); ++ WRITE_BASE(AAUDIO_MSG_NOTIFICATION_ALIVE); ++ WRITE_VAL(u32, proto_ver); ++ WRITE_VAL(u32, msg_ver); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_update_timestamp_response(struct aaudio_msg *msg) ++{ ++ WRITE_START_RESPONSE(); ++ WRITE_BASE(AAUDIO_MSG_UPDATE_TIMESTAMP_RESPONSE); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_device_list(struct aaudio_msg *msg) ++{ ++ WRITE_START_COMMAND(0); ++ WRITE_BASE(AAUDIO_MSG_GET_DEVICE_LIST); ++ WRITE_END(); ++} ++ ++#define CMD_SHARED_VARS_NO_REPLY \ ++ int status = 0; \ ++ struct aaudio_send_ctx sctx; ++#define CMD_SHARED_VARS \ ++ CMD_SHARED_VARS_NO_REPLY \ ++ struct aaudio_msg reply = aaudio_reply_alloc(); \ ++ struct aaudio_msg *buf = &reply; ++#define CMD_SEND_REQUEST(fn, ...) \ ++ if ((status = aaudio_send_cmd_sync(a, &sctx, buf, 500, fn, ##__VA_ARGS__))) \ ++ return status; ++#define CMD_DEF_SHARED_AND_SEND(fn, ...) \ ++ CMD_SHARED_VARS \ ++ CMD_SEND_REQUEST(fn, ##__VA_ARGS__); ++#define CMD_DEF_SHARED_NO_REPLY_AND_SEND(fn, ...) \ ++ CMD_SHARED_VARS_NO_REPLY \ ++ CMD_SEND_REQUEST(fn, ##__VA_ARGS__); ++#define CMD_HNDL_REPLY_NO_FREE(fn, ...) \ ++ status = fn(buf, ##__VA_ARGS__); \ ++ return status; ++#define CMD_HNDL_REPLY_AND_FREE(fn, ...) \ ++ status = fn(buf, ##__VA_ARGS__); \ ++ aaudio_reply_free(&reply); \ ++ return status; ++ ++int aaudio_cmd_start_io(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_start_io, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_start_io_response); ++} ++int aaudio_cmd_stop_io(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_stop_io, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_stop_io_response); ++} ++int aaudio_cmd_get_property(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void **data, u64 *data_size) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_property, devid, obj, prop, qualifier, qualifier_size); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_property_response, &obj, &prop, data, data_size); ++} ++int aaudio_cmd_get_primitive_property(struct aaudio_device *a, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size) ++{ ++ int status; ++ struct aaudio_msg reply = aaudio_reply_alloc(); ++ void *r_data; ++ u64 r_data_size; ++ if ((status = aaudio_cmd_get_property(a, &reply, devid, obj, prop, qualifier, qualifier_size, ++ &r_data, &r_data_size))) ++ goto finish; ++ if (r_data_size != data_size) { ++ status = -EINVAL; ++ goto finish; ++ } ++ memcpy(data, r_data, data_size); ++finish: ++ aaudio_reply_free(&reply); ++ return status; ++} ++int aaudio_cmd_set_property(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_property, devid, obj, prop, data, data_size, ++ qualifier, qualifier_size); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_property_response, &obj); ++} ++int aaudio_cmd_property_listener(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_property_listener, devid, obj, prop); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_property_listener_response, &obj, &prop); ++} ++int aaudio_cmd_set_input_stream_address_ranges(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_input_stream_address_ranges, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_input_stream_address_ranges_response); ++} ++int aaudio_cmd_get_input_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_input_stream_list, devid); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_input_stream_list_response, str_l, str_cnt); ++} ++int aaudio_cmd_get_output_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_output_stream_list, devid); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_output_stream_list_response, str_l, str_cnt); ++} ++int aaudio_cmd_set_remote_access(struct aaudio_device *a, u64 mode) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_remote_access, mode); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_remote_access_response); ++} ++int aaudio_cmd_get_device_list(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t **dev_l, u64 *dev_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_device_list); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_device_list_response, dev_l, dev_cnt); ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/audio/protocol.h b/drivers/staging/apple-bce/audio/protocol.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol.h +@@ -0,0 +1,147 @@ ++#ifndef AAUDIO_PROTOCOL_H ++#define AAUDIO_PROTOCOL_H ++ ++#include ++ ++struct aaudio_device; ++ ++typedef u64 aaudio_device_id_t; ++typedef u64 aaudio_object_id_t; ++ ++struct aaudio_msg { ++ void *data; ++ size_t size; ++}; ++ ++struct __attribute__((packed)) aaudio_msg_header { ++ char tag[4]; ++ u8 type; ++ aaudio_device_id_t device_id; // Idk, use zero for commands? ++}; ++struct __attribute__((packed)) aaudio_msg_base { ++ u32 msg; ++ u32 status; ++}; ++ ++struct aaudio_prop_addr { ++ u32 scope; ++ u32 selector; ++ u32 element; ++}; ++#define AAUDIO_PROP(scope, sel, el) (struct aaudio_prop_addr) { scope, sel, el } ++ ++enum { ++ AAUDIO_MSG_TYPE_COMMAND = 1, ++ AAUDIO_MSG_TYPE_RESPONSE = 2, ++ AAUDIO_MSG_TYPE_NOTIFICATION = 3 ++}; ++ ++enum { ++ AAUDIO_MSG_START_IO = 0, ++ AAUDIO_MSG_START_IO_RESPONSE = 1, ++ AAUDIO_MSG_STOP_IO = 2, ++ AAUDIO_MSG_STOP_IO_RESPONSE = 3, ++ AAUDIO_MSG_UPDATE_TIMESTAMP = 4, ++ AAUDIO_MSG_GET_PROPERTY = 7, ++ AAUDIO_MSG_GET_PROPERTY_RESPONSE = 8, ++ AAUDIO_MSG_SET_PROPERTY = 9, ++ AAUDIO_MSG_SET_PROPERTY_RESPONSE = 10, ++ AAUDIO_MSG_PROPERTY_LISTENER = 11, ++ AAUDIO_MSG_PROPERTY_LISTENER_RESPONSE = 12, ++ AAUDIO_MSG_PROPERTY_CHANGED = 13, ++ AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES = 18, ++ AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES_RESPONSE = 19, ++ AAUDIO_MSG_GET_INPUT_STREAM_LIST = 24, ++ AAUDIO_MSG_GET_INPUT_STREAM_LIST_RESPONSE = 25, ++ AAUDIO_MSG_GET_OUTPUT_STREAM_LIST = 26, ++ AAUDIO_MSG_GET_OUTPUT_STREAM_LIST_RESPONSE = 27, ++ AAUDIO_MSG_SET_REMOTE_ACCESS = 32, ++ AAUDIO_MSG_SET_REMOTE_ACCESS_RESPONSE = 33, ++ AAUDIO_MSG_UPDATE_TIMESTAMP_RESPONSE = 34, ++ ++ AAUDIO_MSG_NOTIFICATION_ALIVE = 100, ++ AAUDIO_MSG_GET_DEVICE_LIST = 101, ++ AAUDIO_MSG_GET_DEVICE_LIST_RESPONSE = 102, ++ AAUDIO_MSG_NOTIFICATION_BOOT = 104 ++}; ++ ++enum { ++ AAUDIO_REMOTE_ACCESS_OFF = 0, ++ AAUDIO_REMOTE_ACCESS_ON = 2 ++}; ++ ++enum { ++ AAUDIO_PROP_SCOPE_GLOBAL = 0x676c6f62, // 'glob' ++ AAUDIO_PROP_SCOPE_INPUT = 0x696e7074, // 'inpt' ++ AAUDIO_PROP_SCOPE_OUTPUT = 0x6f757470 // 'outp' ++}; ++ ++enum { ++ AAUDIO_PROP_UID = 0x75696420, // 'uid ' ++ AAUDIO_PROP_BOOL_VALUE = 0x6263766c, // 'bcvl' ++ AAUDIO_PROP_JACK_PLUGGED = 0x6a61636b, // 'jack' ++ AAUDIO_PROP_SEL_VOLUME = 0x64656176, // 'deav' ++ AAUDIO_PROP_LATENCY = 0x6c746e63, // 'ltnc' ++ AAUDIO_PROP_PHYS_FORMAT = 0x70667420 // 'pft ' ++}; ++ ++int aaudio_msg_read_base(struct aaudio_msg *msg, struct aaudio_msg_base *base); ++ ++int aaudio_msg_read_start_io_response(struct aaudio_msg *msg); ++int aaudio_msg_read_stop_io_response(struct aaudio_msg *msg); ++int aaudio_msg_read_update_timestamp(struct aaudio_msg *msg, aaudio_device_id_t *devid, ++ u64 *timestamp, u64 *update_seed); ++int aaudio_msg_read_get_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop, void **data, u64 *data_size); ++int aaudio_msg_read_set_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj); ++int aaudio_msg_read_property_listener_response(struct aaudio_msg *msg,aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop); ++int aaudio_msg_read_property_changed(struct aaudio_msg *msg, aaudio_device_id_t *devid, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop); ++int aaudio_msg_read_set_input_stream_address_ranges_response(struct aaudio_msg *msg); ++int aaudio_msg_read_get_input_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_msg_read_get_output_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_msg_read_set_remote_access_response(struct aaudio_msg *msg); ++int aaudio_msg_read_get_device_list_response(struct aaudio_msg *msg, aaudio_device_id_t **dev_l, u64 *dev_cnt); ++ ++void aaudio_msg_write_start_io(struct aaudio_msg *msg, aaudio_device_id_t dev); ++void aaudio_msg_write_stop_io(struct aaudio_msg *msg, aaudio_device_id_t dev); ++void aaudio_msg_write_get_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size); ++void aaudio_msg_write_set_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *data, u64 data_size, void *qualifier, u64 qualifier_size); ++void aaudio_msg_write_property_listener(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop); ++void aaudio_msg_write_set_input_stream_address_ranges(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_get_input_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_get_output_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_set_remote_access(struct aaudio_msg *msg, u64 mode); ++void aaudio_msg_write_alive_notification(struct aaudio_msg *msg, u32 proto_ver, u32 msg_ver); ++void aaudio_msg_write_update_timestamp_response(struct aaudio_msg *msg); ++void aaudio_msg_write_get_device_list(struct aaudio_msg *msg); ++ ++ ++int aaudio_cmd_start_io(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_stop_io(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_get_property(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void **data, u64 *data_size); ++int aaudio_cmd_get_primitive_property(struct aaudio_device *a, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size); ++int aaudio_cmd_set_property(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size); ++int aaudio_cmd_property_listener(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop); ++int aaudio_cmd_set_input_stream_address_ranges(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_get_input_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_cmd_get_output_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_cmd_set_remote_access(struct aaudio_device *a, u64 mode); ++int aaudio_cmd_get_device_list(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t **dev_l, u64 *dev_cnt); ++ ++ ++ ++#endif //AAUDIO_PROTOCOL_H +diff --git a/drivers/staging/apple-bce/audio/protocol_bce.c b/drivers/staging/apple-bce/audio/protocol_bce.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol_bce.c +@@ -0,0 +1,226 @@ ++#include "protocol_bce.h" ++ ++#include "audio.h" ++ ++static void aaudio_bce_out_queue_completion(struct bce_queue_sq *sq); ++static void aaudio_bce_in_queue_completion(struct bce_queue_sq *sq); ++static int aaudio_bce_queue_init(struct aaudio_device *dev, struct aaudio_bce_queue *q, const char *name, int direction, ++ bce_sq_completion cfn); ++void aaudio_bce_in_queue_submit_pending(struct aaudio_bce_queue *q, size_t count); ++ ++int aaudio_bce_init(struct aaudio_device *dev) ++{ ++ int status; ++ struct aaudio_bce *bce = &dev->bcem; ++ bce->cq = bce_create_cq(dev->bce, 0x80); ++ spin_lock_init(&bce->spinlock); ++ if (!bce->cq) ++ return -EINVAL; ++ if ((status = aaudio_bce_queue_init(dev, &bce->qout, "com.apple.BridgeAudio.IntelToARM", DMA_TO_DEVICE, ++ aaudio_bce_out_queue_completion))) { ++ return status; ++ } ++ if ((status = aaudio_bce_queue_init(dev, &bce->qin, "com.apple.BridgeAudio.ARMToIntel", DMA_FROM_DEVICE, ++ aaudio_bce_in_queue_completion))) { ++ return status; ++ } ++ aaudio_bce_in_queue_submit_pending(&bce->qin, bce->qin.el_count); ++ return 0; ++} ++ ++int aaudio_bce_queue_init(struct aaudio_device *dev, struct aaudio_bce_queue *q, const char *name, int direction, ++ bce_sq_completion cfn) ++{ ++ q->cq = dev->bcem.cq; ++ q->el_size = AAUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ q->el_count = AAUDIO_BCE_QUEUE_ELEMENT_COUNT; ++ /* NOTE: The Apple impl uses 0x80 as the queue size, however we use 21 (in fact 20) to simplify the impl */ ++ q->sq = bce_create_sq(dev->bce, q->cq, name, (u32) (q->el_count + 1), direction, cfn, dev); ++ if (!q->sq) ++ return -EINVAL; ++ ++ q->data = dma_alloc_coherent(&dev->bce->pci->dev, q->el_size * q->el_count, &q->dma_addr, GFP_KERNEL); ++ if (!q->data) { ++ bce_destroy_sq(dev->bce, q->sq); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static void aaudio_send_create_tag(struct aaudio_bce *b, int *tagn, char tag[4]) ++{ ++ char tag_zero[5]; ++ b->tag_num = (b->tag_num + 1) % AAUDIO_BCE_QUEUE_TAG_COUNT; ++ *tagn = b->tag_num; ++ snprintf(tag_zero, 5, "S%03d", b->tag_num); ++ *((u32 *) tag) = *((u32 *) tag_zero); ++} ++ ++int __aaudio_send_prepare(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, char *tag) ++{ ++ int status; ++ size_t index; ++ void *dptr; ++ struct aaudio_msg_header *header; ++ if ((status = bce_reserve_submission(b->qout.sq, &ctx->timeout))) ++ return status; ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ index = b->qout.data_tail; ++ dptr = (u8 *) b->qout.data + index * b->qout.el_size; ++ ctx->msg.data = dptr; ++ header = dptr; ++ if (tag) ++ *((u32 *) header->tag) = *((u32 *) tag); ++ else ++ aaudio_send_create_tag(b, &ctx->tag_n, header->tag); ++ return 0; ++} ++ ++void __aaudio_send(struct aaudio_bce *b, struct aaudio_send_ctx *ctx) ++{ ++ struct bce_qe_submission *s = bce_next_submission(b->qout.sq); ++#ifdef DEBUG ++ pr_debug("aaudio: Sending command data\n"); ++ print_hex_dump(KERN_DEBUG, "aaudio:OUT ", DUMP_PREFIX_NONE, 32, 1, ctx->msg.data, ctx->msg.size, true); ++#endif ++ bce_set_submission_single(s, b->qout.dma_addr + (dma_addr_t) (ctx->msg.data - b->qout.data), ctx->msg.size); ++ bce_submit_to_device(b->qout.sq); ++ b->qout.data_tail = (b->qout.data_tail + 1) % b->qout.el_count; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++} ++ ++int __aaudio_send_cmd_sync(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, struct aaudio_msg *reply) ++{ ++ struct aaudio_bce_queue_entry ent; ++ DECLARE_COMPLETION_ONSTACK(cmpl); ++ ent.msg = reply; ++ ent.cmpl = &cmpl; ++ b->pending_entries[ctx->tag_n] = &ent; ++ __aaudio_send(b, ctx); /* unlocks the spinlock */ ++ ctx->timeout = wait_for_completion_timeout(&cmpl, ctx->timeout); ++ if (ctx->timeout == 0) { ++ /* Remove the pending queue entry; this will be normally handled by the completion route but ++ * during a timeout it won't */ ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ if (b->pending_entries[ctx->tag_n] == &ent) ++ b->pending_entries[ctx->tag_n] = NULL; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static void aaudio_handle_reply(struct aaudio_bce *b, struct aaudio_msg *reply) ++{ ++ const char *tag; ++ int tagn; ++ unsigned long irq_flags; ++ char tag_zero[5]; ++ struct aaudio_bce_queue_entry *entry; ++ ++ tag = ((struct aaudio_msg_header *) reply->data)->tag; ++ if (tag[0] != 'S') { ++ pr_err("aaudio_handle_reply: Unexpected tag: %.4s\n", tag); ++ return; ++ } ++ *((u32 *) tag_zero) = *((u32 *) tag); ++ tag_zero[4] = 0; ++ if (kstrtoint(&tag_zero[1], 10, &tagn)) { ++ pr_err("aaudio_handle_reply: Tag parse failed: %.4s\n", tag); ++ return; ++ } ++ ++ spin_lock_irqsave(&b->spinlock, irq_flags); ++ entry = b->pending_entries[tagn]; ++ if (entry) { ++ if (reply->size < entry->msg->size) ++ entry->msg->size = reply->size; ++ memcpy(entry->msg->data, reply->data, entry->msg->size); ++ complete(entry->cmpl); ++ ++ b->pending_entries[tagn] = NULL; ++ } else { ++ pr_err("aaudio_handle_reply: No queued item found for tag: %.4s\n", tag); ++ } ++ spin_unlock_irqrestore(&b->spinlock, irq_flags); ++} ++ ++static void aaudio_bce_out_queue_completion(struct bce_queue_sq *sq) ++{ ++ while (bce_next_completion(sq)) { ++ //pr_info("aaudio: Send confirmed\n"); ++ bce_notify_submission_complete(sq); ++ } ++} ++ ++static void aaudio_bce_in_queue_handle_msg(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++static void aaudio_bce_in_queue_completion(struct bce_queue_sq *sq) ++{ ++ struct aaudio_msg msg; ++ struct aaudio_device *dev = sq->userdata; ++ struct aaudio_bce_queue *q = &dev->bcem.qin; ++ struct bce_sq_completion_data *c; ++ size_t cnt = 0; ++ ++ mb(); ++ while ((c = bce_next_completion(sq))) { ++ msg.data = (u8 *) q->data + q->data_head * q->el_size; ++ msg.size = c->data_size; ++#ifdef DEBUG ++ pr_debug("aaudio: Received command data %llx\n", c->data_size); ++ print_hex_dump(KERN_DEBUG, "aaudio:IN ", DUMP_PREFIX_NONE, 32, 1, msg.data, min(msg.size, 128UL), true); ++#endif ++ aaudio_bce_in_queue_handle_msg(dev, &msg); ++ ++ q->data_head = (q->data_head + 1) % q->el_count; ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ aaudio_bce_in_queue_submit_pending(q, cnt); ++} ++ ++static void aaudio_bce_in_queue_handle_msg(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_msg_header *header = (struct aaudio_msg_header *) msg->data; ++ if (msg->size < sizeof(struct aaudio_msg_header)) { ++ pr_err("aaudio: Msg size smaller than header (%lx)", msg->size); ++ return; ++ } ++ if (header->type == AAUDIO_MSG_TYPE_RESPONSE) { ++ aaudio_handle_reply(&a->bcem, msg); ++ } else if (header->type == AAUDIO_MSG_TYPE_COMMAND) { ++ aaudio_handle_command(a, msg); ++ } else if (header->type == AAUDIO_MSG_TYPE_NOTIFICATION) { ++ aaudio_handle_notification(a, msg); ++ } ++} ++ ++void aaudio_bce_in_queue_submit_pending(struct aaudio_bce_queue *q, size_t count) ++{ ++ struct bce_qe_submission *s; ++ while (count--) { ++ if (bce_reserve_submission(q->sq, NULL)) { ++ pr_err("aaudio: Failed to reserve an event queue submission\n"); ++ break; ++ } ++ s = bce_next_submission(q->sq); ++ bce_set_submission_single(s, q->dma_addr + (dma_addr_t) (q->data_tail * q->el_size), q->el_size); ++ q->data_tail = (q->data_tail + 1) % q->el_count; ++ } ++ bce_submit_to_device(q->sq); ++} ++ ++struct aaudio_msg aaudio_reply_alloc(void) ++{ ++ struct aaudio_msg ret; ++ ret.size = AAUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ ret.data = kmalloc(ret.size, GFP_KERNEL); ++ return ret; ++} ++ ++void aaudio_reply_free(struct aaudio_msg *reply) ++{ ++ kfree(reply->data); ++} +diff --git a/drivers/staging/apple-bce/audio/protocol_bce.h b/drivers/staging/apple-bce/audio/protocol_bce.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol_bce.h +@@ -0,0 +1,72 @@ ++#ifndef AAUDIO_PROTOCOL_BCE_H ++#define AAUDIO_PROTOCOL_BCE_H ++ ++#include "protocol.h" ++#include "../queue.h" ++ ++#define AAUDIO_BCE_QUEUE_ELEMENT_SIZE 0x1000 ++#define AAUDIO_BCE_QUEUE_ELEMENT_COUNT 20 ++ ++#define AAUDIO_BCE_QUEUE_TAG_COUNT 1000 ++ ++struct aaudio_device; ++ ++struct aaudio_bce_queue_entry { ++ struct aaudio_msg *msg; ++ struct completion *cmpl; ++}; ++struct aaudio_bce_queue { ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq; ++ void *data; ++ dma_addr_t dma_addr; ++ size_t data_head, data_tail; ++ size_t el_size, el_count; ++}; ++struct aaudio_bce { ++ struct bce_queue_cq *cq; ++ struct aaudio_bce_queue qin; ++ struct aaudio_bce_queue qout; ++ int tag_num; ++ struct aaudio_bce_queue_entry *pending_entries[AAUDIO_BCE_QUEUE_TAG_COUNT]; ++ struct spinlock spinlock; ++}; ++ ++struct aaudio_send_ctx { ++ int status; ++ int tag_n; ++ unsigned long irq_flags; ++ struct aaudio_msg msg; ++ unsigned long timeout; ++}; ++ ++int aaudio_bce_init(struct aaudio_device *dev); ++int __aaudio_send_prepare(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, char *tag); ++void __aaudio_send(struct aaudio_bce *b, struct aaudio_send_ctx *ctx); ++int __aaudio_send_cmd_sync(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, struct aaudio_msg *reply); ++ ++#define aaudio_send_with_tag(a, ctx, tag, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __aaudio_send_prepare(&(a)->bcem, (ctx), (tag)); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ __aaudio_send(&(a)->bcem, (ctx)); \ ++ } \ ++ (ctx)->status; \ ++}) ++#define aaudio_send(a, ctx, tout, fn, ...) aaudio_send_with_tag(a, ctx, NULL, tout, fn, ##__VA_ARGS__) ++ ++#define aaudio_send_cmd_sync(a, ctx, reply, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __aaudio_send_prepare(&(a)->bcem, (ctx), NULL); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ (ctx)->status = __aaudio_send_cmd_sync(&(a)->bcem, (ctx), (reply)); \ ++ } \ ++ (ctx)->status; \ ++}) ++ ++struct aaudio_msg aaudio_reply_alloc(void); ++void aaudio_reply_free(struct aaudio_msg *reply); ++ ++#endif //AAUDIO_PROTOCOL_BCE_H +diff --git a/drivers/staging/apple-bce/mailbox.c b/drivers/staging/apple-bce/mailbox.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/mailbox.c +@@ -0,0 +1,151 @@ ++#include "mailbox.h" ++#include ++#include "apple_bce.h" ++ ++#define REG_MBOX_OUT_BASE 0x820 ++#define REG_MBOX_REPLY_COUNTER 0x108 ++#define REG_MBOX_REPLY_BASE 0x810 ++#define REG_TIMESTAMP_BASE 0xC000 ++ ++#define BCE_MBOX_TIMEOUT_MS 200 ++ ++void bce_mailbox_init(struct bce_mailbox *mb, void __iomem *reg_mb) ++{ ++ mb->reg_mb = reg_mb; ++ init_completion(&mb->mb_completion); ++} ++ ++int bce_mailbox_send(struct bce_mailbox *mb, u64 msg, u64* recv) ++{ ++ u32 __iomem *regb; ++ ++ if (atomic_cmpxchg(&mb->mb_status, 0, 1) != 0) { ++ return -EEXIST; // We don't support two messages at once ++ } ++ reinit_completion(&mb->mb_completion); ++ ++ pr_debug("bce_mailbox_send: %llx\n", msg); ++ regb = (u32*) ((u8*) mb->reg_mb + REG_MBOX_OUT_BASE); ++ iowrite32((u32) msg, regb); ++ iowrite32((u32) (msg >> 32), regb + 1); ++ iowrite32(0, regb + 2); ++ iowrite32(0, regb + 3); ++ ++ wait_for_completion_timeout(&mb->mb_completion, msecs_to_jiffies(BCE_MBOX_TIMEOUT_MS)); ++ if (atomic_read(&mb->mb_status) != 2) { // Didn't get the reply ++ atomic_set(&mb->mb_status, 0); ++ return -ETIMEDOUT; ++ } ++ ++ *recv = mb->mb_result; ++ pr_debug("bce_mailbox_send: reply %llx\n", *recv); ++ ++ atomic_set(&mb->mb_status, 0); ++ return 0; ++} ++ ++static int bce_mailbox_retrive_response(struct bce_mailbox *mb) ++{ ++ u32 __iomem *regb; ++ u32 lo, hi; ++ int count, counter; ++ u32 res = ioread32((u8*) mb->reg_mb + REG_MBOX_REPLY_COUNTER); ++ count = (res >> 20) & 0xf; ++ counter = count; ++ pr_debug("bce_mailbox_retrive_response count=%i\n", count); ++ while (counter--) { ++ regb = (u32*) ((u8*) mb->reg_mb + REG_MBOX_REPLY_BASE); ++ lo = ioread32(regb); ++ hi = ioread32(regb + 1); ++ ioread32(regb + 2); ++ ioread32(regb + 3); ++ pr_debug("bce_mailbox_retrive_response %llx\n", ((u64) hi << 32) | lo); ++ mb->mb_result = ((u64) hi << 32) | lo; ++ } ++ return count > 0 ? 0 : -ENODATA; ++} ++ ++int bce_mailbox_handle_interrupt(struct bce_mailbox *mb) ++{ ++ int status = bce_mailbox_retrive_response(mb); ++ if (!status) { ++ atomic_set(&mb->mb_status, 2); ++ complete(&mb->mb_completion); ++ } ++ return status; ++} ++ ++static void bc_send_timestamp(struct timer_list *tl); ++ ++void bce_timestamp_init(struct bce_timestamp *ts, void __iomem *reg) ++{ ++ u32 __iomem *regb; ++ ++ spin_lock_init(&ts->stop_sl); ++ ts->stopped = false; ++ ++ ts->reg = reg; ++ ++ regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ ioread32(regb); ++ mb(); ++ ++ timer_setup(&ts->timer, bc_send_timestamp, 0); ++} ++ ++void bce_timestamp_start(struct bce_timestamp *ts, bool is_initial) ++{ ++ unsigned long flags; ++ u32 __iomem *regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ if (is_initial) { ++ iowrite32((u32) -4, regb + 2); ++ iowrite32((u32) -1, regb); ++ } else { ++ iowrite32((u32) -3, regb + 2); ++ iowrite32((u32) -1, regb); ++ } ++ ++ spin_lock_irqsave(&ts->stop_sl, flags); ++ ts->stopped = false; ++ spin_unlock_irqrestore(&ts->stop_sl, flags); ++ mod_timer(&ts->timer, jiffies + msecs_to_jiffies(150)); ++} ++ ++void bce_timestamp_stop(struct bce_timestamp *ts) ++{ ++ unsigned long flags; ++ u32 __iomem *regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ spin_lock_irqsave(&ts->stop_sl, flags); ++ ts->stopped = true; ++ spin_unlock_irqrestore(&ts->stop_sl, flags); ++ del_timer_sync(&ts->timer); ++ ++ iowrite32((u32) -2, regb + 2); ++ iowrite32((u32) -1, regb); ++} ++ ++static void bc_send_timestamp(struct timer_list *tl) ++{ ++ struct bce_timestamp *ts; ++ unsigned long flags; ++ u32 __iomem *regb; ++ ktime_t bt; ++ ++ ts = container_of(tl, struct bce_timestamp, timer); ++ regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ local_irq_save(flags); ++ ioread32(regb + 2); ++ mb(); ++ bt = ktime_get_boottime(); ++ iowrite32((u32) bt, regb + 2); ++ iowrite32((u32) (bt >> 32), regb); ++ ++ spin_lock(&ts->stop_sl); ++ if (!ts->stopped) ++ mod_timer(&ts->timer, jiffies + msecs_to_jiffies(150)); ++ spin_unlock(&ts->stop_sl); ++ local_irq_restore(flags); ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/mailbox.h b/drivers/staging/apple-bce/mailbox.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/mailbox.h +@@ -0,0 +1,53 @@ ++#ifndef BCE_MAILBOX_H ++#define BCE_MAILBOX_H ++ ++#include ++#include ++#include ++ ++struct bce_mailbox { ++ void __iomem *reg_mb; ++ ++ atomic_t mb_status; // possible statuses: 0 (no msg), 1 (has active msg), 2 (got reply) ++ struct completion mb_completion; ++ uint64_t mb_result; ++}; ++ ++enum bce_message_type { ++ BCE_MB_REGISTER_COMMAND_SQ = 0x7, // to-device ++ BCE_MB_REGISTER_COMMAND_CQ = 0x8, // to-device ++ BCE_MB_REGISTER_COMMAND_QUEUE_REPLY = 0xB, // to-host ++ BCE_MB_SET_FW_PROTOCOL_VERSION = 0xC, // both ++ BCE_MB_SLEEP_NO_STATE = 0x14, // to-device ++ BCE_MB_RESTORE_NO_STATE = 0x15, // to-device ++ BCE_MB_SAVE_STATE_AND_SLEEP = 0x17, // to-device ++ BCE_MB_RESTORE_STATE_AND_WAKE = 0x18, // to-device ++ BCE_MB_SAVE_STATE_AND_SLEEP_FAILURE = 0x19, // from-device ++ BCE_MB_SAVE_RESTORE_STATE_COMPLETE = 0x1A, // from-device ++}; ++ ++#define BCE_MB_MSG(type, value) (((u64) (type) << 58) | ((value) & 0x3FFFFFFFFFFFFFFLL)) ++#define BCE_MB_TYPE(v) ((u32) (v >> 58)) ++#define BCE_MB_VALUE(v) (v & 0x3FFFFFFFFFFFFFFLL) ++ ++void bce_mailbox_init(struct bce_mailbox *mb, void __iomem *reg_mb); ++ ++int bce_mailbox_send(struct bce_mailbox *mb, u64 msg, u64* recv); ++ ++int bce_mailbox_handle_interrupt(struct bce_mailbox *mb); ++ ++ ++struct bce_timestamp { ++ void __iomem *reg; ++ struct timer_list timer; ++ struct spinlock stop_sl; ++ bool stopped; ++}; ++ ++void bce_timestamp_init(struct bce_timestamp *ts, void __iomem *reg); ++ ++void bce_timestamp_start(struct bce_timestamp *ts, bool is_initial); ++ ++void bce_timestamp_stop(struct bce_timestamp *ts); ++ ++#endif //BCEDRIVER_MAILBOX_H +diff --git a/drivers/staging/apple-bce/queue.c b/drivers/staging/apple-bce/queue.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue.c +@@ -0,0 +1,390 @@ ++#include "queue.h" ++#include "apple_bce.h" ++ ++#define REG_DOORBELL_BASE 0x44000 ++ ++struct bce_queue_cq *bce_alloc_cq(struct apple_bce_device *dev, int qid, u32 el_count) ++{ ++ struct bce_queue_cq *q; ++ q = kzalloc(sizeof(struct bce_queue_cq), GFP_KERNEL); ++ q->qid = qid; ++ q->type = BCE_QUEUE_CQ; ++ q->el_count = el_count; ++ q->data = dma_alloc_coherent(&dev->pci->dev, el_count * sizeof(struct bce_qe_completion), ++ &q->dma_handle, GFP_KERNEL); ++ if (!q->data) { ++ pr_err("DMA queue memory alloc failed\n"); ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_get_cq_memcfg(struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg) ++{ ++ cfg->qid = (u16) cq->qid; ++ cfg->el_count = (u16) cq->el_count; ++ cfg->vector_or_cq = 0; ++ cfg->_pad = 0; ++ cfg->addr = cq->dma_handle; ++ cfg->length = cq->el_count * sizeof(struct bce_qe_completion); ++} ++ ++void bce_free_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ dma_free_coherent(&dev->pci->dev, cq->el_count * sizeof(struct bce_qe_completion), cq->data, cq->dma_handle); ++ kfree(cq); ++} ++ ++static void bce_handle_cq_completion(struct apple_bce_device *dev, struct bce_qe_completion *e, size_t *ce) ++{ ++ struct bce_queue *target; ++ struct bce_queue_sq *target_sq; ++ struct bce_sq_completion_data *cmpl; ++ if (e->qid >= BCE_MAX_QUEUE_COUNT) { ++ pr_err("Device sent a response for qid (%u) >= BCE_MAX_QUEUE_COUNT\n", e->qid); ++ return; ++ } ++ target = dev->queues[e->qid]; ++ if (!target || target->type != BCE_QUEUE_SQ) { ++ pr_err("Device sent a response for qid (%u), which does not exist\n", e->qid); ++ return; ++ } ++ target_sq = (struct bce_queue_sq *) target; ++ if (target_sq->completion_tail != e->completion_index) { ++ pr_err("Completion index mismatch; this is likely going to make this driver unusable\n"); ++ return; ++ } ++ if (!target_sq->has_pending_completions) { ++ target_sq->has_pending_completions = true; ++ dev->int_sq_list[(*ce)++] = target_sq; ++ } ++ cmpl = &target_sq->completion_data[e->completion_index]; ++ cmpl->status = e->status; ++ cmpl->data_size = e->data_size; ++ cmpl->result = e->result; ++ wmb(); ++ target_sq->completion_tail = (target_sq->completion_tail + 1) % target_sq->el_count; ++} ++ ++void bce_handle_cq_completions(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ size_t ce = 0; ++ struct bce_qe_completion *e; ++ struct bce_queue_sq *sq; ++ e = bce_cq_element(cq, cq->index); ++ if (!(e->flags & BCE_COMPLETION_FLAG_PENDING)) ++ return; ++ mb(); ++ while (true) { ++ e = bce_cq_element(cq, cq->index); ++ if (!(e->flags & BCE_COMPLETION_FLAG_PENDING)) ++ break; ++ // pr_info("apple-bce: compl: %i: %i %llx %llx", e->qid, e->status, e->data_size, e->result); ++ bce_handle_cq_completion(dev, e, &ce); ++ e->flags = 0; ++ cq->index = (cq->index + 1) % cq->el_count; ++ } ++ mb(); ++ iowrite32(cq->index, (u32 *) ((u8 *) dev->reg_mem_dma + REG_DOORBELL_BASE) + cq->qid); ++ while (ce) { ++ --ce; ++ sq = dev->int_sq_list[ce]; ++ sq->completion(sq); ++ sq->has_pending_completions = false; ++ } ++} ++ ++ ++struct bce_queue_sq *bce_alloc_sq(struct apple_bce_device *dev, int qid, u32 el_size, u32 el_count, ++ bce_sq_completion compl, void *userdata) ++{ ++ struct bce_queue_sq *q; ++ q = kzalloc(sizeof(struct bce_queue_sq), GFP_KERNEL); ++ q->qid = qid; ++ q->type = BCE_QUEUE_SQ; ++ q->el_size = el_size; ++ q->el_count = el_count; ++ q->data = dma_alloc_coherent(&dev->pci->dev, el_count * el_size, ++ &q->dma_handle, GFP_KERNEL); ++ q->completion = compl; ++ q->userdata = userdata; ++ q->completion_data = kzalloc(sizeof(struct bce_sq_completion_data) * el_count, GFP_KERNEL); ++ q->reg_mem_dma = dev->reg_mem_dma; ++ atomic_set(&q->available_commands, el_count - 1); ++ init_completion(&q->available_command_completion); ++ atomic_set(&q->available_command_completion_waiting_count, 0); ++ if (!q->data) { ++ pr_err("DMA queue memory alloc failed\n"); ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_get_sq_memcfg(struct bce_queue_sq *sq, struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg) ++{ ++ cfg->qid = (u16) sq->qid; ++ cfg->el_count = (u16) sq->el_count; ++ cfg->vector_or_cq = (u16) cq->qid; ++ cfg->_pad = 0; ++ cfg->addr = sq->dma_handle; ++ cfg->length = sq->el_count * sq->el_size; ++} ++ ++void bce_free_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq) ++{ ++ dma_free_coherent(&dev->pci->dev, sq->el_count * sq->el_size, sq->data, sq->dma_handle); ++ kfree(sq); ++} ++ ++int bce_reserve_submission(struct bce_queue_sq *sq, unsigned long *timeout) ++{ ++ while (atomic_dec_if_positive(&sq->available_commands) < 0) { ++ if (!timeout || !*timeout) ++ return -EAGAIN; ++ atomic_inc(&sq->available_command_completion_waiting_count); ++ *timeout = wait_for_completion_timeout(&sq->available_command_completion, *timeout); ++ if (!*timeout) { ++ if (atomic_dec_if_positive(&sq->available_command_completion_waiting_count) < 0) ++ try_wait_for_completion(&sq->available_command_completion); /* consume the pending completion */ ++ } ++ } ++ return 0; ++} ++ ++void bce_cancel_submission_reservation(struct bce_queue_sq *sq) ++{ ++ atomic_inc(&sq->available_commands); ++} ++ ++void *bce_next_submission(struct bce_queue_sq *sq) ++{ ++ void *ret = bce_sq_element(sq, sq->tail); ++ sq->tail = (sq->tail + 1) % sq->el_count; ++ return ret; ++} ++ ++void bce_submit_to_device(struct bce_queue_sq *sq) ++{ ++ mb(); ++ iowrite32(sq->tail, (u32 *) ((u8 *) sq->reg_mem_dma + REG_DOORBELL_BASE) + sq->qid); ++} ++ ++void bce_notify_submission_complete(struct bce_queue_sq *sq) ++{ ++ sq->head = (sq->head + 1) % sq->el_count; ++ atomic_inc(&sq->available_commands); ++ if (atomic_dec_if_positive(&sq->available_command_completion_waiting_count) >= 0) { ++ complete(&sq->available_command_completion); ++ } ++} ++ ++void bce_set_submission_single(struct bce_qe_submission *element, dma_addr_t addr, size_t size) ++{ ++ element->addr = addr; ++ element->length = size; ++ element->segl_addr = element->segl_length = 0; ++} ++ ++static void bce_cmdq_completion(struct bce_queue_sq *q); ++ ++struct bce_queue_cmdq *bce_alloc_cmdq(struct apple_bce_device *dev, int qid, u32 el_count) ++{ ++ struct bce_queue_cmdq *q; ++ q = kzalloc(sizeof(struct bce_queue_cmdq), GFP_KERNEL); ++ q->sq = bce_alloc_sq(dev, qid, BCE_CMD_SIZE, el_count, bce_cmdq_completion, q); ++ if (!q->sq) { ++ kfree(q); ++ return NULL; ++ } ++ spin_lock_init(&q->lck); ++ q->tres = kzalloc(sizeof(struct bce_queue_cmdq_result_el*) * el_count, GFP_KERNEL); ++ if (!q->tres) { ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_free_cmdq(struct apple_bce_device *dev, struct bce_queue_cmdq *cmdq) ++{ ++ bce_free_sq(dev, cmdq->sq); ++ kfree(cmdq->tres); ++ kfree(cmdq); ++} ++ ++void bce_cmdq_completion(struct bce_queue_sq *q) ++{ ++ struct bce_queue_cmdq_result_el *el; ++ struct bce_queue_cmdq *cmdq = q->userdata; ++ struct bce_sq_completion_data *result; ++ ++ spin_lock(&cmdq->lck); ++ while ((result = bce_next_completion(q))) { ++ el = cmdq->tres[cmdq->sq->head]; ++ if (el) { ++ el->result = result->result; ++ el->status = result->status; ++ mb(); ++ complete(&el->cmpl); ++ } else { ++ pr_err("apple-bce: Unexpected command queue completion\n"); ++ } ++ cmdq->tres[cmdq->sq->head] = NULL; ++ bce_notify_submission_complete(q); ++ } ++ spin_unlock(&cmdq->lck); ++} ++ ++static __always_inline void *bce_cmd_start(struct bce_queue_cmdq *cmdq, struct bce_queue_cmdq_result_el *res) ++{ ++ void *ret; ++ unsigned long timeout; ++ init_completion(&res->cmpl); ++ mb(); ++ ++ timeout = msecs_to_jiffies(1000L * 60 * 5); /* wait for up to ~5 minutes */ ++ if (bce_reserve_submission(cmdq->sq, &timeout)) ++ return NULL; ++ ++ spin_lock(&cmdq->lck); ++ cmdq->tres[cmdq->sq->tail] = res; ++ ret = bce_next_submission(cmdq->sq); ++ return ret; ++} ++ ++static __always_inline void bce_cmd_finish(struct bce_queue_cmdq *cmdq, struct bce_queue_cmdq_result_el *res) ++{ ++ bce_submit_to_device(cmdq->sq); ++ spin_unlock(&cmdq->lck); ++ ++ wait_for_completion(&res->cmpl); ++ mb(); ++} ++ ++u32 bce_cmd_register_queue(struct bce_queue_cmdq *cmdq, struct bce_queue_memcfg *cfg, const char *name, bool isdirout) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_register_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_REGISTER_MEMORY_QUEUE; ++ cmd->flags = (u16) ((name ? 2 : 0) | (isdirout ? 1 : 0)); ++ cmd->qid = cfg->qid; ++ cmd->el_count = cfg->el_count; ++ cmd->vector_or_cq = cfg->vector_or_cq; ++ memset(cmd->name, 0, sizeof(cmd->name)); ++ if (name) { ++ cmd->name_len = (u16) min(strlen(name), (size_t) sizeof(cmd->name)); ++ memcpy(cmd->name, name, cmd->name_len); ++ } else { ++ cmd->name_len = 0; ++ } ++ cmd->addr = cfg->addr; ++ cmd->length = cfg->length; ++ ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++u32 bce_cmd_unregister_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_simple_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_UNREGISTER_MEMORY_QUEUE; ++ cmd->flags = 0; ++ cmd->qid = qid; ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++u32 bce_cmd_flush_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_simple_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_FLUSH_MEMORY_QUEUE; ++ cmd->flags = 0; ++ cmd->qid = qid; ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++ ++struct bce_queue_cq *bce_create_cq(struct apple_bce_device *dev, u32 el_count) ++{ ++ struct bce_queue_cq *cq; ++ struct bce_queue_memcfg cfg; ++ int qid = ida_simple_get(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX, GFP_KERNEL); ++ if (qid < 0) ++ return NULL; ++ cq = bce_alloc_cq(dev, qid, el_count); ++ if (!cq) ++ return NULL; ++ bce_get_cq_memcfg(cq, &cfg); ++ if (bce_cmd_register_queue(dev->cmd_cmdq, &cfg, NULL, false) != 0) { ++ pr_err("apple-bce: CQ registration failed (%i)", qid); ++ bce_free_cq(dev, cq); ++ ida_simple_remove(&dev->queue_ida, (uint) qid); ++ return NULL; ++ } ++ dev->queues[qid] = (struct bce_queue *) cq; ++ return cq; ++} ++ ++struct bce_queue_sq *bce_create_sq(struct apple_bce_device *dev, struct bce_queue_cq *cq, const char *name, u32 el_count, ++ int direction, bce_sq_completion compl, void *userdata) ++{ ++ struct bce_queue_sq *sq; ++ struct bce_queue_memcfg cfg; ++ int qid; ++ if (cq == NULL) ++ return NULL; /* cq can not be null */ ++ if (name == NULL) ++ return NULL; /* name can not be null */ ++ if (direction != DMA_TO_DEVICE && direction != DMA_FROM_DEVICE) ++ return NULL; /* unsupported direction */ ++ qid = ida_simple_get(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX, GFP_KERNEL); ++ if (qid < 0) ++ return NULL; ++ sq = bce_alloc_sq(dev, qid, sizeof(struct bce_qe_submission), el_count, compl, userdata); ++ if (!sq) ++ return NULL; ++ bce_get_sq_memcfg(sq, cq, &cfg); ++ if (bce_cmd_register_queue(dev->cmd_cmdq, &cfg, name, direction != DMA_FROM_DEVICE) != 0) { ++ pr_err("apple-bce: SQ registration failed (%i)", qid); ++ bce_free_sq(dev, sq); ++ ida_simple_remove(&dev->queue_ida, (uint) qid); ++ return NULL; ++ } ++ spin_lock(&dev->queues_lock); ++ dev->queues[qid] = (struct bce_queue *) sq; ++ spin_unlock(&dev->queues_lock); ++ return sq; ++} ++ ++void bce_destroy_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ if (!dev->is_being_removed && bce_cmd_unregister_memory_queue(dev->cmd_cmdq, (u16) cq->qid)) ++ pr_err("apple-bce: CQ unregister failed"); ++ spin_lock(&dev->queues_lock); ++ dev->queues[cq->qid] = NULL; ++ spin_unlock(&dev->queues_lock); ++ ida_simple_remove(&dev->queue_ida, (uint) cq->qid); ++ bce_free_cq(dev, cq); ++} ++ ++void bce_destroy_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq) ++{ ++ if (!dev->is_being_removed && bce_cmd_unregister_memory_queue(dev->cmd_cmdq, (u16) sq->qid)) ++ pr_err("apple-bce: CQ unregister failed"); ++ spin_lock(&dev->queues_lock); ++ dev->queues[sq->qid] = NULL; ++ spin_unlock(&dev->queues_lock); ++ ida_simple_remove(&dev->queue_ida, (uint) sq->qid); ++ bce_free_sq(dev, sq); ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/queue.h b/drivers/staging/apple-bce/queue.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue.h +@@ -0,0 +1,177 @@ ++#ifndef BCE_QUEUE_H ++#define BCE_QUEUE_H ++ ++#include ++#include ++ ++#define BCE_CMD_SIZE 0x40 ++ ++struct apple_bce_device; ++ ++enum bce_queue_type { ++ BCE_QUEUE_CQ, BCE_QUEUE_SQ ++}; ++struct bce_queue { ++ int qid; ++ int type; ++}; ++struct bce_queue_cq { ++ int qid; ++ int type; ++ u32 el_count; ++ dma_addr_t dma_handle; ++ void *data; ++ ++ u32 index; ++}; ++struct bce_queue_sq; ++typedef void (*bce_sq_completion)(struct bce_queue_sq *q); ++struct bce_sq_completion_data { ++ u32 status; ++ u64 data_size; ++ u64 result; ++}; ++struct bce_queue_sq { ++ int qid; ++ int type; ++ u32 el_size; ++ u32 el_count; ++ dma_addr_t dma_handle; ++ void *data; ++ void *userdata; ++ void __iomem *reg_mem_dma; ++ ++ atomic_t available_commands; ++ struct completion available_command_completion; ++ atomic_t available_command_completion_waiting_count; ++ u32 head, tail; ++ ++ u32 completion_cidx, completion_tail; ++ struct bce_sq_completion_data *completion_data; ++ bool has_pending_completions; ++ bce_sq_completion completion; ++}; ++ ++struct bce_queue_cmdq_result_el { ++ struct completion cmpl; ++ u32 status; ++ u64 result; ++}; ++struct bce_queue_cmdq { ++ struct bce_queue_sq *sq; ++ struct spinlock lck; ++ struct bce_queue_cmdq_result_el **tres; ++}; ++ ++struct bce_queue_memcfg { ++ u16 qid; ++ u16 el_count; ++ u16 vector_or_cq; ++ u16 _pad; ++ u64 addr; ++ u64 length; ++}; ++ ++enum bce_qe_completion_status { ++ BCE_COMPLETION_SUCCESS = 0, ++ BCE_COMPLETION_ERROR = 1, ++ BCE_COMPLETION_ABORTED = 2, ++ BCE_COMPLETION_NO_SPACE = 3, ++ BCE_COMPLETION_OVERRUN = 4 ++}; ++enum bce_qe_completion_flags { ++ BCE_COMPLETION_FLAG_PENDING = 0x8000 ++}; ++struct bce_qe_completion { ++ u64 result; ++ u64 data_size; ++ u16 qid; ++ u16 completion_index; ++ u16 status; // bce_qe_completion_status ++ u16 flags; // bce_qe_completion_flags ++}; ++ ++struct bce_qe_submission { ++ u64 length; ++ u64 addr; ++ ++ u64 segl_addr; ++ u64 segl_length; ++}; ++ ++enum bce_cmdq_command { ++ BCE_CMD_REGISTER_MEMORY_QUEUE = 0x20, ++ BCE_CMD_UNREGISTER_MEMORY_QUEUE = 0x30, ++ BCE_CMD_FLUSH_MEMORY_QUEUE = 0x40, ++ BCE_CMD_SET_MEMORY_QUEUE_PROPERTY = 0x50 ++}; ++struct bce_cmdq_simple_memory_queue_cmd { ++ u16 cmd; // bce_cmdq_command ++ u16 flags; ++ u16 qid; ++}; ++struct bce_cmdq_register_memory_queue_cmd { ++ u16 cmd; // bce_cmdq_command ++ u16 flags; ++ u16 qid; ++ u16 _pad; ++ u16 el_count; ++ u16 vector_or_cq; ++ u16 _pad2; ++ u16 name_len; ++ char name[0x20]; ++ u64 addr; ++ u64 length; ++}; ++ ++static __always_inline void *bce_sq_element(struct bce_queue_sq *q, int i) { ++ return (void *) ((u8 *) q->data + q->el_size * i); ++} ++static __always_inline void *bce_cq_element(struct bce_queue_cq *q, int i) { ++ return (void *) ((struct bce_qe_completion *) q->data + i); ++} ++ ++static __always_inline struct bce_sq_completion_data *bce_next_completion(struct bce_queue_sq *sq) { ++ struct bce_sq_completion_data *res; ++ rmb(); ++ if (sq->completion_cidx == sq->completion_tail) ++ return NULL; ++ res = &sq->completion_data[sq->completion_cidx]; ++ sq->completion_cidx = (sq->completion_cidx + 1) % sq->el_count; ++ return res; ++} ++ ++struct bce_queue_cq *bce_alloc_cq(struct apple_bce_device *dev, int qid, u32 el_count); ++void bce_get_cq_memcfg(struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg); ++void bce_free_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++void bce_handle_cq_completions(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++ ++struct bce_queue_sq *bce_alloc_sq(struct apple_bce_device *dev, int qid, u32 el_size, u32 el_count, ++ bce_sq_completion compl, void *userdata); ++void bce_get_sq_memcfg(struct bce_queue_sq *sq, struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg); ++void bce_free_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq); ++int bce_reserve_submission(struct bce_queue_sq *sq, unsigned long *timeout); ++void bce_cancel_submission_reservation(struct bce_queue_sq *sq); ++void *bce_next_submission(struct bce_queue_sq *sq); ++void bce_submit_to_device(struct bce_queue_sq *sq); ++void bce_notify_submission_complete(struct bce_queue_sq *sq); ++ ++void bce_set_submission_single(struct bce_qe_submission *element, dma_addr_t addr, size_t size); ++ ++struct bce_queue_cmdq *bce_alloc_cmdq(struct apple_bce_device *dev, int qid, u32 el_count); ++void bce_free_cmdq(struct apple_bce_device *dev, struct bce_queue_cmdq *cmdq); ++ ++u32 bce_cmd_register_queue(struct bce_queue_cmdq *cmdq, struct bce_queue_memcfg *cfg, const char *name, bool isdirout); ++u32 bce_cmd_unregister_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid); ++u32 bce_cmd_flush_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid); ++ ++ ++/* User API - Creates and registers the queue */ ++ ++struct bce_queue_cq *bce_create_cq(struct apple_bce_device *dev, u32 el_count); ++struct bce_queue_sq *bce_create_sq(struct apple_bce_device *dev, struct bce_queue_cq *cq, const char *name, u32 el_count, ++ int direction, bce_sq_completion compl, void *userdata); ++void bce_destroy_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++void bce_destroy_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq); ++ ++#endif //BCEDRIVER_MAILBOX_H +diff --git a/drivers/staging/apple-bce/queue_dma.c b/drivers/staging/apple-bce/queue_dma.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue_dma.c +@@ -0,0 +1,220 @@ ++#include "queue_dma.h" ++#include ++#include ++#include "queue.h" ++ ++static int bce_alloc_scatterlist_from_vm(struct sg_table *tbl, void *data, size_t len); ++static struct bce_segment_list_element_hostinfo *bce_map_segment_list( ++ struct device *dev, struct scatterlist *pages, int pagen); ++static void bce_unmap_segement_list(struct device *dev, struct bce_segment_list_element_hostinfo *list); ++ ++int bce_map_dma_buffer(struct device *dev, struct bce_dma_buffer *buf, struct sg_table scatterlist, ++ enum dma_data_direction dir) ++{ ++ int cnt; ++ ++ buf->direction = dir; ++ buf->scatterlist = scatterlist; ++ buf->seglist_hostinfo = NULL; ++ ++ cnt = dma_map_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ if (cnt != buf->scatterlist.nents) { ++ pr_err("apple-bce: DMA scatter list mapping returned an unexpected count: %i\n", cnt); ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ return -EIO; ++ } ++ if (cnt == 1) ++ return 0; ++ ++ buf->seglist_hostinfo = bce_map_segment_list(dev, buf->scatterlist.sgl, buf->scatterlist.nents); ++ if (!buf->seglist_hostinfo) { ++ pr_err("apple-bce: Creating segment list failed\n"); ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ return -EIO; ++ } ++ return 0; ++} ++ ++int bce_map_dma_buffer_vm(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir) ++{ ++ int status; ++ struct sg_table scatterlist; ++ if ((status = bce_alloc_scatterlist_from_vm(&scatterlist, data, len))) ++ return status; ++ if ((status = bce_map_dma_buffer(dev, buf, scatterlist, dir))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ return 0; ++} ++ ++int bce_map_dma_buffer_km(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir) ++{ ++ /* Kernel memory is continuous which is great for us. */ ++ int status; ++ struct sg_table scatterlist; ++ if ((status = sg_alloc_table(&scatterlist, 1, GFP_KERNEL))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ sg_set_buf(scatterlist.sgl, data, (uint) len); ++ if ((status = bce_map_dma_buffer(dev, buf, scatterlist, dir))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ return 0; ++} ++ ++void bce_unmap_dma_buffer(struct device *dev, struct bce_dma_buffer *buf) ++{ ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, buf->direction); ++ bce_unmap_segement_list(dev, buf->seglist_hostinfo); ++} ++ ++ ++static int bce_alloc_scatterlist_from_vm(struct sg_table *tbl, void *data, size_t len) ++{ ++ int status, i; ++ struct page **pages; ++ size_t off, start_page, end_page, page_count; ++ off = (size_t) data % PAGE_SIZE; ++ start_page = (size_t) data / PAGE_SIZE; ++ end_page = ((size_t) data + len - 1) / PAGE_SIZE; ++ page_count = end_page - start_page + 1; ++ ++ if (page_count > PAGE_SIZE / sizeof(struct page *)) ++ pages = vmalloc(page_count * sizeof(struct page *)); ++ else ++ pages = kmalloc(page_count * sizeof(struct page *), GFP_KERNEL); ++ ++ for (i = 0; i < page_count; i++) ++ pages[i] = vmalloc_to_page((void *) ((start_page + i) * PAGE_SIZE)); ++ ++ if ((status = sg_alloc_table_from_pages(tbl, pages, page_count, (unsigned int) off, len, GFP_KERNEL))) { ++ sg_free_table(tbl); ++ } ++ ++ if (page_count > PAGE_SIZE / sizeof(struct page *)) ++ vfree(pages); ++ else ++ kfree(pages); ++ return status; ++} ++ ++#define BCE_ELEMENTS_PER_PAGE ((PAGE_SIZE - sizeof(struct bce_segment_list_header)) \ ++ / sizeof(struct bce_segment_list_element)) ++#define BCE_ELEMENTS_PER_ADDITIONAL_PAGE (PAGE_SIZE / sizeof(struct bce_segment_list_element)) ++ ++static struct bce_segment_list_element_hostinfo *bce_map_segment_list( ++ struct device *dev, struct scatterlist *pages, int pagen) ++{ ++ size_t ptr, pptr = 0; ++ struct bce_segment_list_header theader; /* a temp header, to store the initial seg */ ++ struct bce_segment_list_header *header; ++ struct bce_segment_list_element *el, *el_end; ++ struct bce_segment_list_element_hostinfo *out, *pout, *out_root; ++ struct scatterlist *sg; ++ int i; ++ header = &theader; ++ out = out_root = NULL; ++ el = el_end = NULL; ++ for_each_sg(pages, sg, pagen, i) { ++ if (el >= el_end) { ++ /* allocate a new page, this will be also done for the first element */ ++ ptr = __get_free_page(GFP_KERNEL); ++ if (pptr && ptr == pptr + PAGE_SIZE) { ++ out->page_count++; ++ header->element_count += BCE_ELEMENTS_PER_ADDITIONAL_PAGE; ++ el_end += BCE_ELEMENTS_PER_ADDITIONAL_PAGE; ++ } else { ++ header = (void *) ptr; ++ header->element_count = BCE_ELEMENTS_PER_PAGE; ++ header->data_size = 0; ++ header->next_segl_addr = 0; ++ header->next_segl_length = 0; ++ el = (void *) (header + 1); ++ el_end = el + BCE_ELEMENTS_PER_PAGE; ++ ++ if (out) { ++ out->next = kmalloc(sizeof(struct bce_segment_list_element_hostinfo), GFP_KERNEL); ++ out = out->next; ++ } else { ++ out_root = out = kmalloc(sizeof(struct bce_segment_list_element_hostinfo), GFP_KERNEL); ++ } ++ out->page_start = (void *) ptr; ++ out->page_count = 1; ++ out->dma_start = DMA_MAPPING_ERROR; ++ out->next = NULL; ++ } ++ pptr = ptr; ++ } ++ el->addr = sg->dma_address; ++ el->length = sg->length; ++ header->data_size += el->length; ++ } ++ ++ /* DMA map */ ++ out = out_root; ++ pout = NULL; ++ while (out) { ++ out->dma_start = dma_map_single(dev, out->page_start, out->page_count * PAGE_SIZE, DMA_TO_DEVICE); ++ if (dma_mapping_error(dev, out->dma_start)) ++ goto error; ++ if (pout) { ++ header = pout->page_start; ++ header->next_segl_addr = out->dma_start; ++ header->next_segl_length = out->page_count * PAGE_SIZE; ++ } ++ pout = out; ++ out = out->next; ++ } ++ return out_root; ++ ++ error: ++ bce_unmap_segement_list(dev, out_root); ++ return NULL; ++} ++ ++static void bce_unmap_segement_list(struct device *dev, struct bce_segment_list_element_hostinfo *list) ++{ ++ struct bce_segment_list_element_hostinfo *next; ++ while (list) { ++ if (list->dma_start != DMA_MAPPING_ERROR) ++ dma_unmap_single(dev, list->dma_start, list->page_count * PAGE_SIZE, DMA_TO_DEVICE); ++ next = list->next; ++ kfree(list); ++ list = next; ++ } ++} ++ ++int bce_set_submission_buf(struct bce_qe_submission *element, struct bce_dma_buffer *buf, size_t offset, size_t length) ++{ ++ struct bce_segment_list_element_hostinfo *seg; ++ struct bce_segment_list_header *seg_header; ++ ++ seg = buf->seglist_hostinfo; ++ if (!seg) { ++ element->addr = buf->scatterlist.sgl->dma_address + offset; ++ element->length = length; ++ element->segl_addr = 0; ++ element->segl_length = 0; ++ return 0; ++ } ++ ++ while (seg) { ++ seg_header = seg->page_start; ++ if (offset <= seg_header->data_size) ++ break; ++ offset -= seg_header->data_size; ++ seg = seg->next; ++ } ++ if (!seg) ++ return -EINVAL; ++ element->addr = offset; ++ element->length = buf->scatterlist.sgl->dma_length; ++ element->segl_addr = seg->dma_start; ++ element->segl_length = seg->page_count * PAGE_SIZE; ++ return 0; ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/queue_dma.h b/drivers/staging/apple-bce/queue_dma.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue_dma.h +@@ -0,0 +1,50 @@ ++#ifndef BCE_QUEUE_DMA_H ++#define BCE_QUEUE_DMA_H ++ ++#include ++ ++struct bce_qe_submission; ++ ++struct bce_segment_list_header { ++ u64 element_count; ++ u64 data_size; ++ ++ u64 next_segl_addr; ++ u64 next_segl_length; ++}; ++struct bce_segment_list_element { ++ u64 addr; ++ u64 length; ++}; ++ ++struct bce_segment_list_element_hostinfo { ++ struct bce_segment_list_element_hostinfo *next; ++ void *page_start; ++ size_t page_count; ++ dma_addr_t dma_start; ++}; ++ ++ ++struct bce_dma_buffer { ++ enum dma_data_direction direction; ++ struct sg_table scatterlist; ++ struct bce_segment_list_element_hostinfo *seglist_hostinfo; ++}; ++ ++/* NOTE: Takes ownership of the sg_table if it succeeds. Ownership is not transferred on failure. */ ++int bce_map_dma_buffer(struct device *dev, struct bce_dma_buffer *buf, struct sg_table scatterlist, ++ enum dma_data_direction dir); ++ ++/* Creates a buffer from virtual memory (vmalloc) */ ++int bce_map_dma_buffer_vm(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir); ++ ++/* Creates a buffer from kernel memory (kmalloc) */ ++int bce_map_dma_buffer_km(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir); ++ ++void bce_unmap_dma_buffer(struct device *dev, struct bce_dma_buffer *buf); ++ ++int bce_set_submission_buf(struct bce_qe_submission *element, struct bce_dma_buffer *buf, size_t offset, size_t length); ++ ++#endif //BCE_QUEUE_DMA_H +diff --git a/drivers/staging/apple-bce/vhci/command.h b/drivers/staging/apple-bce/vhci/command.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/command.h +@@ -0,0 +1,204 @@ ++#ifndef BCE_VHCI_COMMAND_H ++#define BCE_VHCI_COMMAND_H ++ ++#include "queue.h" ++#include ++#include ++ ++#define BCE_VHCI_CMD_TIMEOUT_SHORT msecs_to_jiffies(2000) ++#define BCE_VHCI_CMD_TIMEOUT_LONG msecs_to_jiffies(30000) ++ ++#define BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2 2 ++#define BCE_VHCI_BULK_MAX_ACTIVE_URBS (1 << BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2) ++ ++typedef u8 bce_vhci_port_t; ++typedef u8 bce_vhci_device_t; ++ ++enum bce_vhci_command { ++ BCE_VHCI_CMD_CONTROLLER_ENABLE = 1, ++ BCE_VHCI_CMD_CONTROLLER_DISABLE = 2, ++ BCE_VHCI_CMD_CONTROLLER_START = 3, ++ BCE_VHCI_CMD_CONTROLLER_PAUSE = 4, ++ ++ BCE_VHCI_CMD_PORT_POWER_ON = 0x10, ++ BCE_VHCI_CMD_PORT_POWER_OFF = 0x11, ++ BCE_VHCI_CMD_PORT_RESUME = 0x12, ++ BCE_VHCI_CMD_PORT_SUSPEND = 0x13, ++ BCE_VHCI_CMD_PORT_RESET = 0x14, ++ BCE_VHCI_CMD_PORT_DISABLE = 0x15, ++ BCE_VHCI_CMD_PORT_STATUS = 0x16, ++ ++ BCE_VHCI_CMD_DEVICE_CREATE = 0x30, ++ BCE_VHCI_CMD_DEVICE_DESTROY = 0x31, ++ ++ BCE_VHCI_CMD_ENDPOINT_CREATE = 0x40, ++ BCE_VHCI_CMD_ENDPOINT_DESTROY = 0x41, ++ BCE_VHCI_CMD_ENDPOINT_SET_STATE = 0x42, ++ BCE_VHCI_CMD_ENDPOINT_RESET = 0x44, ++ ++ /* Device to host only */ ++ BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE = 0x43, ++ BCE_VHCI_CMD_TRANSFER_REQUEST = 0x1000, ++ BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS = 0x1005 ++}; ++ ++enum bce_vhci_endpoint_state { ++ BCE_VHCI_ENDPOINT_ACTIVE = 0, ++ BCE_VHCI_ENDPOINT_PAUSED = 1, ++ BCE_VHCI_ENDPOINT_STALLED = 2 ++}; ++ ++static inline int bce_vhci_cmd_controller_enable(struct bce_vhci_command_queue *q, u8 busNum, u16 *portMask) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_ENABLE; ++ cmd.param1 = 0x7100u | busNum; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++ if (!status) ++ *portMask = (u16) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_controller_disable(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_DISABLE; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_controller_start(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_START; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_controller_pause(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_PAUSE; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++ ++static inline int bce_vhci_cmd_port_power_on(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_POWER_ON; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_power_off(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_POWER_OFF; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_resume(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_RESUME; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_port_suspend(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_SUSPEND; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_port_reset(struct bce_vhci_command_queue *q, bce_vhci_port_t port, u32 timeout) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_RESET; ++ cmd.param1 = port; ++ cmd.param2 = timeout; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_disable(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_DISABLE; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_status(struct bce_vhci_command_queue *q, bce_vhci_port_t port, ++ u32 clearFlags, u32 *resStatus) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_STATUS; ++ cmd.param1 = port; ++ cmd.param2 = clearFlags & 0x560000; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (status >= 0) ++ *resStatus = (u32) res.param2; ++ return status; ++} ++ ++static inline int bce_vhci_cmd_device_create(struct bce_vhci_command_queue *q, bce_vhci_port_t port, ++ bce_vhci_device_t *dev) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_DEVICE_CREATE; ++ cmd.param1 = port; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (!status) ++ *dev = (bce_vhci_device_t) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_device_destroy(struct bce_vhci_command_queue *q, bce_vhci_device_t dev) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_DEVICE_DESTROY; ++ cmd.param1 = dev; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++ ++static inline int bce_vhci_cmd_endpoint_create(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, ++ struct usb_endpoint_descriptor *desc) ++{ ++ struct bce_vhci_message cmd, res; ++ int endpoint_type = usb_endpoint_type(desc); ++ int maxp = usb_endpoint_maxp(desc); ++ int maxp_burst = usb_endpoint_maxp_mult(desc) * maxp; ++ u8 max_active_requests_pow2 = 0; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_CREATE; ++ cmd.param1 = dev | ((desc->bEndpointAddress & 0x8Fu) << 8); ++ if (endpoint_type == USB_ENDPOINT_XFER_BULK) ++ max_active_requests_pow2 = BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2; ++ cmd.param2 = endpoint_type | ((max_active_requests_pow2 & 0xf) << 4) | (maxp << 16) | ((u64) maxp_burst << 32); ++ if (endpoint_type == USB_ENDPOINT_XFER_INT) ++ cmd.param2 |= (desc->bInterval - 1) << 8; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_endpoint_destroy(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_DESTROY; ++ cmd.param1 = dev | (endpoint << 8); ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_endpoint_set_state(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint, ++ enum bce_vhci_endpoint_state newState, enum bce_vhci_endpoint_state *retState) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_SET_STATE; ++ cmd.param1 = dev | (endpoint << 8); ++ cmd.param2 = (u64) newState; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (status != BCE_VHCI_INTERNAL_ERROR && status != BCE_VHCI_NO_POWER) ++ *retState = (enum bce_vhci_endpoint_state) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_endpoint_reset(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_RESET; ++ cmd.param1 = dev | (endpoint << 8); ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++ ++ ++#endif //BCE_VHCI_COMMAND_H +diff --git a/drivers/staging/apple-bce/vhci/queue.c b/drivers/staging/apple-bce/vhci/queue.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/queue.c +@@ -0,0 +1,268 @@ ++#include "queue.h" ++#include "vhci.h" ++#include "../apple_bce.h" ++ ++ ++static void bce_vhci_message_queue_completion(struct bce_queue_sq *sq); ++ ++int bce_vhci_message_queue_create(struct bce_vhci *vhci, struct bce_vhci_message_queue *ret, const char *name) ++{ ++ int status; ++ ret->cq = bce_create_cq(vhci->dev, VHCI_EVENT_QUEUE_EL_COUNT); ++ if (!ret->cq) ++ return -EINVAL; ++ ret->sq = bce_create_sq(vhci->dev, ret->cq, name, VHCI_EVENT_QUEUE_EL_COUNT, DMA_TO_DEVICE, ++ bce_vhci_message_queue_completion, ret); ++ if (!ret->sq) { ++ status = -EINVAL; ++ goto fail_cq; ++ } ++ ret->data = dma_alloc_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ &ret->dma_addr, GFP_KERNEL); ++ if (!ret->data) { ++ status = -EINVAL; ++ goto fail_sq; ++ } ++ return 0; ++ ++fail_sq: ++ bce_destroy_sq(vhci->dev, ret->sq); ++ ret->sq = NULL; ++fail_cq: ++ bce_destroy_cq(vhci->dev, ret->cq); ++ ret->cq = NULL; ++ return status; ++} ++ ++void bce_vhci_message_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_message_queue *q) ++{ ++ if (!q->cq) ++ return; ++ dma_free_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ q->data, q->dma_addr); ++ bce_destroy_sq(vhci->dev, q->sq); ++ bce_destroy_cq(vhci->dev, q->cq); ++} ++ ++void bce_vhci_message_queue_write(struct bce_vhci_message_queue *q, struct bce_vhci_message *req) ++{ ++ int sidx; ++ struct bce_qe_submission *s; ++ sidx = q->sq->tail; ++ s = bce_next_submission(q->sq); ++ pr_debug("bce-vhci: Send message: %x s=%x p1=%x p2=%llx\n", req->cmd, req->status, req->param1, req->param2); ++ q->data[sidx] = *req; ++ bce_set_submission_single(s, q->dma_addr + sizeof(struct bce_vhci_message) * sidx, ++ sizeof(struct bce_vhci_message)); ++ bce_submit_to_device(q->sq); ++} ++ ++static void bce_vhci_message_queue_completion(struct bce_queue_sq *sq) ++{ ++ while (bce_next_completion(sq)) ++ bce_notify_submission_complete(sq); ++} ++ ++ ++ ++static void bce_vhci_event_queue_completion(struct bce_queue_sq *sq); ++ ++int __bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_sq_completion compl) ++{ ++ ret->vhci = vhci; ++ ++ ret->sq = bce_create_sq(vhci->dev, vhci->ev_cq, name, VHCI_EVENT_QUEUE_EL_COUNT, DMA_FROM_DEVICE, compl, ret); ++ if (!ret->sq) ++ return -EINVAL; ++ ret->data = dma_alloc_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ &ret->dma_addr, GFP_KERNEL); ++ if (!ret->data) { ++ bce_destroy_sq(vhci->dev, ret->sq); ++ ret->sq = NULL; ++ return -EINVAL; ++ } ++ ++ init_completion(&ret->queue_empty_completion); ++ bce_vhci_event_queue_submit_pending(ret, VHCI_EVENT_PENDING_COUNT); ++ return 0; ++} ++ ++int bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_vhci_event_queue_callback cb) ++{ ++ ret->cb = cb; ++ return __bce_vhci_event_queue_create(vhci, ret, name, bce_vhci_event_queue_completion); ++} ++ ++void bce_vhci_event_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_event_queue *q) ++{ ++ if (!q->sq) ++ return; ++ dma_free_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ q->data, q->dma_addr); ++ bce_destroy_sq(vhci->dev, q->sq); ++} ++ ++static void bce_vhci_event_queue_completion(struct bce_queue_sq *sq) ++{ ++ struct bce_sq_completion_data *cd; ++ struct bce_vhci_event_queue *ev = sq->userdata; ++ struct bce_vhci_message *msg; ++ size_t cnt = 0; ++ ++ while ((cd = bce_next_completion(sq))) { ++ if (cd->status == BCE_COMPLETION_ABORTED) { /* We flushed the queue */ ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ msg = &ev->data[sq->head]; ++ pr_debug("bce-vhci: Got event: %x s=%x p1=%x p2=%llx\n", msg->cmd, msg->status, msg->param1, msg->param2); ++ ev->cb(ev, msg); ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ bce_vhci_event_queue_submit_pending(ev, cnt); ++ if (atomic_read(&sq->available_commands) == sq->el_count - 1) ++ complete(&ev->queue_empty_completion); ++} ++ ++void bce_vhci_event_queue_submit_pending(struct bce_vhci_event_queue *q, size_t count) ++{ ++ int idx; ++ struct bce_qe_submission *s; ++ while (count--) { ++ if (bce_reserve_submission(q->sq, NULL)) { ++ pr_err("bce-vhci: Failed to reserve an event queue submission\n"); ++ break; ++ } ++ idx = q->sq->tail; ++ s = bce_next_submission(q->sq); ++ bce_set_submission_single(s, ++ q->dma_addr + idx * sizeof(struct bce_vhci_message), sizeof(struct bce_vhci_message)); ++ } ++ bce_submit_to_device(q->sq); ++} ++ ++void bce_vhci_event_queue_pause(struct bce_vhci_event_queue *q) ++{ ++ unsigned long timeout; ++ reinit_completion(&q->queue_empty_completion); ++ if (bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, q->sq->qid)) ++ pr_warn("bce-vhci: failed to flush event queue\n"); ++ timeout = msecs_to_jiffies(5000); ++ while (atomic_read(&q->sq->available_commands) != q->sq->el_count - 1) { ++ timeout = wait_for_completion_timeout(&q->queue_empty_completion, timeout); ++ if (timeout == 0) { ++ pr_err("bce-vhci: waiting for queue to be flushed timed out\n"); ++ break; ++ } ++ } ++} ++ ++void bce_vhci_event_queue_resume(struct bce_vhci_event_queue *q) ++{ ++ if (atomic_read(&q->sq->available_commands) != q->sq->el_count - 1) { ++ pr_err("bce-vhci: resume of a queue with pending submissions\n"); ++ return; ++ } ++ bce_vhci_event_queue_submit_pending(q, VHCI_EVENT_PENDING_COUNT); ++} ++ ++void bce_vhci_command_queue_create(struct bce_vhci_command_queue *ret, struct bce_vhci_message_queue *mq) ++{ ++ ret->mq = mq; ++ ret->completion.result = NULL; ++ init_completion(&ret->completion.completion); ++ spin_lock_init(&ret->completion_lock); ++ mutex_init(&ret->mutex); ++} ++ ++void bce_vhci_command_queue_destroy(struct bce_vhci_command_queue *cq) ++{ ++ spin_lock(&cq->completion_lock); ++ if (cq->completion.result) { ++ memset(cq->completion.result, 0, sizeof(struct bce_vhci_message)); ++ cq->completion.result->status = BCE_VHCI_ABORT; ++ complete(&cq->completion.completion); ++ cq->completion.result = NULL; ++ } ++ spin_unlock(&cq->completion_lock); ++ mutex_lock(&cq->mutex); ++ mutex_unlock(&cq->mutex); ++ mutex_destroy(&cq->mutex); ++} ++ ++void bce_vhci_command_queue_deliver_completion(struct bce_vhci_command_queue *cq, struct bce_vhci_message *msg) ++{ ++ struct bce_vhci_command_queue_completion *c = &cq->completion; ++ ++ spin_lock(&cq->completion_lock); ++ if (c->result) { ++ *c->result = *msg; ++ complete(&c->completion); ++ c->result = NULL; ++ } ++ spin_unlock(&cq->completion_lock); ++} ++ ++static int __bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout) ++{ ++ int status; ++ struct bce_vhci_command_queue_completion *c; ++ struct bce_vhci_message creq; ++ c = &cq->completion; ++ ++ if ((status = bce_reserve_submission(cq->mq->sq, &timeout))) ++ return status; ++ ++ spin_lock(&cq->completion_lock); ++ c->result = res; ++ reinit_completion(&c->completion); ++ spin_unlock(&cq->completion_lock); ++ ++ bce_vhci_message_queue_write(cq->mq, req); ++ ++ if (!wait_for_completion_timeout(&c->completion, timeout)) { ++ /* we ran out of time, send cancellation */ ++ pr_debug("bce-vhci: command timed out req=%x\n", req->cmd); ++ if ((status = bce_reserve_submission(cq->mq->sq, &timeout))) ++ return status; ++ ++ creq = *req; ++ creq.cmd |= 0x4000; ++ bce_vhci_message_queue_write(cq->mq, &creq); ++ ++ if (!wait_for_completion_timeout(&c->completion, 1000)) { ++ pr_err("bce-vhci: Possible desync, cmd cancel timed out\n"); ++ ++ spin_lock(&cq->completion_lock); ++ c->result = NULL; ++ spin_unlock(&cq->completion_lock); ++ return -ETIMEDOUT; ++ } ++ if ((res->cmd & ~0x8000) == creq.cmd) ++ return -ETIMEDOUT; ++ /* reply for the previous command most likely arrived */ ++ } ++ ++ if ((res->cmd & ~0x8000) != req->cmd) { ++ pr_err("bce-vhci: Possible desync, cmd reply mismatch req=%x, res=%x\n", req->cmd, res->cmd); ++ return -EIO; ++ } ++ if (res->status == BCE_VHCI_SUCCESS) ++ return 0; ++ return res->status; ++} ++ ++int bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout) ++{ ++ int status; ++ mutex_lock(&cq->mutex); ++ status = __bce_vhci_command_queue_execute(cq, req, res, timeout); ++ mutex_unlock(&cq->mutex); ++ return status; ++} +diff --git a/drivers/staging/apple-bce/vhci/queue.h b/drivers/staging/apple-bce/vhci/queue.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/queue.h +@@ -0,0 +1,76 @@ ++#ifndef BCE_VHCI_QUEUE_H ++#define BCE_VHCI_QUEUE_H ++ ++#include ++#include "../queue.h" ++ ++#define VHCI_EVENT_QUEUE_EL_COUNT 256 ++#define VHCI_EVENT_PENDING_COUNT 32 ++ ++struct bce_vhci; ++struct bce_vhci_event_queue; ++ ++enum bce_vhci_message_status { ++ BCE_VHCI_SUCCESS = 1, ++ BCE_VHCI_ERROR = 2, ++ BCE_VHCI_USB_PIPE_STALL = 3, ++ BCE_VHCI_ABORT = 4, ++ BCE_VHCI_BAD_ARGUMENT = 5, ++ BCE_VHCI_OVERRUN = 6, ++ BCE_VHCI_INTERNAL_ERROR = 7, ++ BCE_VHCI_NO_POWER = 8, ++ BCE_VHCI_UNSUPPORTED = 9 ++}; ++struct bce_vhci_message { ++ u16 cmd; ++ u16 status; // bce_vhci_message_status ++ u32 param1; ++ u64 param2; ++}; ++ ++struct bce_vhci_message_queue { ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq; ++ struct bce_vhci_message *data; ++ dma_addr_t dma_addr; ++}; ++typedef void (*bce_vhci_event_queue_callback)(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++struct bce_vhci_event_queue { ++ struct bce_vhci *vhci; ++ struct bce_queue_sq *sq; ++ struct bce_vhci_message *data; ++ dma_addr_t dma_addr; ++ bce_vhci_event_queue_callback cb; ++ struct completion queue_empty_completion; ++}; ++struct bce_vhci_command_queue_completion { ++ struct bce_vhci_message *result; ++ struct completion completion; ++}; ++struct bce_vhci_command_queue { ++ struct bce_vhci_message_queue *mq; ++ struct bce_vhci_command_queue_completion completion; ++ struct spinlock completion_lock; ++ struct mutex mutex; ++}; ++ ++int bce_vhci_message_queue_create(struct bce_vhci *vhci, struct bce_vhci_message_queue *ret, const char *name); ++void bce_vhci_message_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_message_queue *q); ++void bce_vhci_message_queue_write(struct bce_vhci_message_queue *q, struct bce_vhci_message *req); ++ ++int __bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_sq_completion compl); ++int bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_vhci_event_queue_callback cb); ++void bce_vhci_event_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_event_queue *q); ++void bce_vhci_event_queue_submit_pending(struct bce_vhci_event_queue *q, size_t count); ++void bce_vhci_event_queue_pause(struct bce_vhci_event_queue *q); ++void bce_vhci_event_queue_resume(struct bce_vhci_event_queue *q); ++ ++void bce_vhci_command_queue_create(struct bce_vhci_command_queue *ret, struct bce_vhci_message_queue *mq); ++void bce_vhci_command_queue_destroy(struct bce_vhci_command_queue *cq); ++int bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout); ++void bce_vhci_command_queue_deliver_completion(struct bce_vhci_command_queue *cq, struct bce_vhci_message *msg); ++ ++#endif //BCE_VHCI_QUEUE_H +diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/transfer.c +@@ -0,0 +1,661 @@ ++#include "transfer.h" ++#include "../queue.h" ++#include "vhci.h" ++#include "../apple_bce.h" ++#include ++ ++static void bce_vhci_transfer_queue_completion(struct bce_queue_sq *sq); ++static void bce_vhci_transfer_queue_giveback(struct bce_vhci_transfer_queue *q); ++static void bce_vhci_transfer_queue_remove_pending(struct bce_vhci_transfer_queue *q); ++ ++static int bce_vhci_urb_init(struct bce_vhci_urb *vurb); ++static int bce_vhci_urb_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg); ++static int bce_vhci_urb_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c); ++ ++static void bce_vhci_transfer_queue_reset_w(struct work_struct *work); ++ ++void bce_vhci_create_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q, ++ struct usb_host_endpoint *endp, bce_vhci_device_t dev_addr, enum dma_data_direction dir) ++{ ++ char name[0x21]; ++ INIT_LIST_HEAD(&q->evq); ++ INIT_LIST_HEAD(&q->giveback_urb_list); ++ spin_lock_init(&q->urb_lock); ++ mutex_init(&q->pause_lock); ++ q->vhci = vhci; ++ q->endp = endp; ++ q->dev_addr = dev_addr; ++ q->endp_addr = (u8) (endp->desc.bEndpointAddress & 0x8F); ++ q->state = BCE_VHCI_ENDPOINT_ACTIVE; ++ q->active = true; ++ q->stalled = false; ++ q->max_active_requests = 1; ++ if (usb_endpoint_type(&endp->desc) == USB_ENDPOINT_XFER_BULK) ++ q->max_active_requests = BCE_VHCI_BULK_MAX_ACTIVE_URBS; ++ q->remaining_active_requests = q->max_active_requests; ++ q->cq = bce_create_cq(vhci->dev, 0x100); ++ INIT_WORK(&q->w_reset, bce_vhci_transfer_queue_reset_w); ++ q->sq_in = NULL; ++ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { ++ snprintf(name, sizeof(name), "VHC1-%i-%02x", dev_addr, 0x80 | usb_endpoint_num(&endp->desc)); ++ q->sq_in = bce_create_sq(vhci->dev, q->cq, name, 0x100, DMA_FROM_DEVICE, ++ bce_vhci_transfer_queue_completion, q); ++ } ++ q->sq_out = NULL; ++ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) { ++ snprintf(name, sizeof(name), "VHC1-%i-%02x", dev_addr, usb_endpoint_num(&endp->desc)); ++ q->sq_out = bce_create_sq(vhci->dev, q->cq, name, 0x100, DMA_TO_DEVICE, ++ bce_vhci_transfer_queue_completion, q); ++ } ++} ++ ++void bce_vhci_destroy_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q) ++{ ++ bce_vhci_transfer_queue_giveback(q); ++ bce_vhci_transfer_queue_remove_pending(q); ++ if (q->sq_in) ++ bce_destroy_sq(vhci->dev, q->sq_in); ++ if (q->sq_out) ++ bce_destroy_sq(vhci->dev, q->sq_out); ++ bce_destroy_cq(vhci->dev, q->cq); ++} ++ ++static inline bool bce_vhci_transfer_queue_can_init_urb(struct bce_vhci_transfer_queue *q) ++{ ++ return q->remaining_active_requests > 0; ++} ++ ++static void bce_vhci_transfer_queue_defer_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg) ++{ ++ struct bce_vhci_list_message *lm; ++ lm = kmalloc(sizeof(struct bce_vhci_list_message), GFP_KERNEL); ++ INIT_LIST_HEAD(&lm->list); ++ lm->msg = *msg; ++ list_add_tail(&lm->list, &q->evq); ++} ++ ++static void bce_vhci_transfer_queue_giveback(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ struct urb *urb; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while (!list_empty(&q->giveback_urb_list)) { ++ urb = list_first_entry(&q->giveback_urb_list, struct urb, urb_list); ++ list_del(&urb->urb_list); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ usb_hcd_giveback_urb(q->vhci->hcd, urb, urb->status); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++} ++ ++static void bce_vhci_transfer_queue_init_pending_urbs(struct bce_vhci_transfer_queue *q); ++ ++static void bce_vhci_transfer_queue_deliver_pending(struct bce_vhci_transfer_queue *q) ++{ ++ struct urb *urb; ++ struct bce_vhci_list_message *lm; ++ ++ while (!list_empty(&q->endp->urb_list) && !list_empty(&q->evq)) { ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ ++ lm = list_first_entry(&q->evq, struct bce_vhci_list_message, list); ++ if (bce_vhci_urb_update(urb->hcpriv, &lm->msg) == -EAGAIN) ++ break; ++ list_del(&lm->list); ++ kfree(lm); ++ } ++ ++ /* some of the URBs could have been completed, so initialize more URBs if possible */ ++ bce_vhci_transfer_queue_init_pending_urbs(q); ++} ++ ++static void bce_vhci_transfer_queue_remove_pending(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ struct bce_vhci_list_message *lm; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while (!list_empty(&q->evq)) { ++ lm = list_first_entry(&q->evq, struct bce_vhci_list_message, list); ++ list_del(&lm->list); ++ kfree(lm); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++} ++ ++void bce_vhci_transfer_queue_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg) ++{ ++ unsigned long flags; ++ struct bce_vhci_urb *turb; ++ struct urb *urb; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_deliver_pending(q); ++ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && ++ (!list_empty(&q->evq) || list_empty(&q->endp->urb_list))) { ++ bce_vhci_transfer_queue_defer_event(q, msg); ++ goto complete; ++ } ++ if (list_empty(&q->endp->urb_list)) { ++ pr_err("bce-vhci: [%02x] Unexpected transfer queue event\n", q->endp_addr); ++ goto complete; ++ } ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ turb = urb->hcpriv; ++ if (bce_vhci_urb_update(turb, msg) == -EAGAIN) { ++ bce_vhci_transfer_queue_defer_event(q, msg); ++ } else { ++ bce_vhci_transfer_queue_init_pending_urbs(q); ++ } ++ ++complete: ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_giveback(q); ++} ++ ++static void bce_vhci_transfer_queue_completion(struct bce_queue_sq *sq) ++{ ++ unsigned long flags; ++ struct bce_sq_completion_data *c; ++ struct urb *urb; ++ struct bce_vhci_transfer_queue *q = sq->userdata; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while ((c = bce_next_completion(sq))) { ++ if (c->status == BCE_COMPLETION_ABORTED) { /* We flushed the queue */ ++ pr_debug("bce-vhci: [%02x] Got an abort completion\n", q->endp_addr); ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ if (list_empty(&q->endp->urb_list)) { ++ pr_err("bce-vhci: [%02x] Got a completion while no requests are pending\n", q->endp_addr); ++ continue; ++ } ++ pr_debug("bce-vhci: [%02x] Got a transfer queue completion\n", q->endp_addr); ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ bce_vhci_urb_transfer_completion(urb->hcpriv, c); ++ bce_notify_submission_complete(sq); ++ } ++ bce_vhci_transfer_queue_deliver_pending(q); ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_giveback(q); ++} ++ ++int bce_vhci_transfer_queue_do_pause(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ int status; ++ u8 endp_addr = (u8) (q->endp->desc.bEndpointAddress & 0x8F); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->active = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ if (q->sq_out) { ++ pr_err("bce-vhci: Not implemented: wait for pending output requests\n"); ++ } ++ bce_vhci_transfer_queue_remove_pending(q); ++ if ((status = bce_vhci_cmd_endpoint_set_state( ++ &q->vhci->cq, q->dev_addr, endp_addr, BCE_VHCI_ENDPOINT_PAUSED, &q->state))) ++ return status; ++ if (q->state != BCE_VHCI_ENDPOINT_PAUSED) ++ return -EINVAL; ++ if (q->sq_in) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_in->qid); ++ if (q->sq_out) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_out->qid); ++ return 0; ++} ++ ++static void bce_vhci_urb_resume(struct bce_vhci_urb *urb); ++ ++int bce_vhci_transfer_queue_do_resume(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ int status; ++ struct urb *urb, *urbt; ++ struct bce_vhci_urb *vurb; ++ u8 endp_addr = (u8) (q->endp->desc.bEndpointAddress & 0x8F); ++ if ((status = bce_vhci_cmd_endpoint_set_state( ++ &q->vhci->cq, q->dev_addr, endp_addr, BCE_VHCI_ENDPOINT_ACTIVE, &q->state))) ++ return status; ++ if (q->state != BCE_VHCI_ENDPOINT_ACTIVE) ++ return -EINVAL; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->active = true; ++ list_for_each_entry_safe(urb, urbt, &q->endp->urb_list, urb_list) { ++ vurb = urb->hcpriv; ++ if (vurb->state == BCE_VHCI_URB_INIT_PENDING) { ++ if (!bce_vhci_transfer_queue_can_init_urb(q)) ++ break; ++ bce_vhci_urb_init(vurb); ++ } else { ++ bce_vhci_urb_resume(vurb); ++ } ++ } ++ bce_vhci_transfer_queue_deliver_pending(q); ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ return 0; ++} ++ ++int bce_vhci_transfer_queue_pause(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src) ++{ ++ int ret = 0; ++ mutex_lock(&q->pause_lock); ++ if ((q->paused_by & src) != src) { ++ if (!q->paused_by) ++ ret = bce_vhci_transfer_queue_do_pause(q); ++ if (!ret) ++ q->paused_by |= src; ++ } ++ mutex_unlock(&q->pause_lock); ++ return ret; ++} ++ ++int bce_vhci_transfer_queue_resume(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src) ++{ ++ int ret = 0; ++ mutex_lock(&q->pause_lock); ++ if (q->paused_by & src) { ++ if (!(q->paused_by & ~src)) ++ ret = bce_vhci_transfer_queue_do_resume(q); ++ if (!ret) ++ q->paused_by &= ~src; ++ } ++ mutex_unlock(&q->pause_lock); ++ return ret; ++} ++ ++static void bce_vhci_transfer_queue_reset_w(struct work_struct *work) ++{ ++ unsigned long flags; ++ struct bce_vhci_transfer_queue *q = container_of(work, struct bce_vhci_transfer_queue, w_reset); ++ ++ mutex_lock(&q->pause_lock); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ if (!q->stalled) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ mutex_unlock(&q->pause_lock); ++ return; ++ } ++ q->active = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ q->paused_by |= BCE_VHCI_PAUSE_INTERNAL_WQ; ++ bce_vhci_transfer_queue_remove_pending(q); ++ if (q->sq_in) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_in->qid); ++ if (q->sq_out) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_out->qid); ++ bce_vhci_cmd_endpoint_reset(&q->vhci->cq, q->dev_addr, (u8) (q->endp->desc.bEndpointAddress & 0x8F)); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->stalled = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ mutex_unlock(&q->pause_lock); ++ bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++} ++ ++void bce_vhci_transfer_queue_request_reset(struct bce_vhci_transfer_queue *q) ++{ ++ queue_work(q->vhci->tq_state_wq, &q->w_reset); ++} ++ ++static void bce_vhci_transfer_queue_init_pending_urbs(struct bce_vhci_transfer_queue *q) ++{ ++ struct urb *urb, *urbt; ++ struct bce_vhci_urb *vurb; ++ list_for_each_entry_safe(urb, urbt, &q->endp->urb_list, urb_list) { ++ vurb = urb->hcpriv; ++ if (!bce_vhci_transfer_queue_can_init_urb(q)) ++ break; ++ if (vurb->state == BCE_VHCI_URB_INIT_PENDING) ++ bce_vhci_urb_init(vurb); ++ } ++} ++ ++ ++ ++static int bce_vhci_urb_data_start(struct bce_vhci_urb *urb, unsigned long *timeout); ++ ++int bce_vhci_urb_create(struct bce_vhci_transfer_queue *q, struct urb *urb) ++{ ++ unsigned long flags; ++ int status = 0; ++ struct bce_vhci_urb *vurb; ++ vurb = kzalloc(sizeof(struct bce_vhci_urb), GFP_KERNEL); ++ urb->hcpriv = vurb; ++ ++ vurb->q = q; ++ vurb->urb = urb; ++ vurb->dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; ++ vurb->is_control = (usb_endpoint_num(&urb->ep->desc) == 0); ++ ++ spin_lock_irqsave(&q->urb_lock, flags); ++ status = usb_hcd_link_urb_to_ep(q->vhci->hcd, urb); ++ if (status) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ urb->hcpriv = NULL; ++ kfree(vurb); ++ return status; ++ } ++ ++ if (q->active) { ++ if (bce_vhci_transfer_queue_can_init_urb(vurb->q)) ++ status = bce_vhci_urb_init(vurb); ++ else ++ vurb->state = BCE_VHCI_URB_INIT_PENDING; ++ } else { ++ if (q->stalled) ++ bce_vhci_transfer_queue_request_reset(q); ++ vurb->state = BCE_VHCI_URB_INIT_PENDING; ++ } ++ if (status) { ++ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb); ++ urb->hcpriv = NULL; ++ kfree(vurb); ++ } else { ++ bce_vhci_transfer_queue_deliver_pending(q); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ pr_debug("bce-vhci: [%02x] URB enqueued (dir = %s, size = %i)\n", q->endp_addr, ++ usb_urb_dir_in(urb) ? "IN" : "OUT", urb->transfer_buffer_length); ++ return status; ++} ++ ++static int bce_vhci_urb_init(struct bce_vhci_urb *vurb) ++{ ++ int status = 0; ++ ++ if (vurb->q->remaining_active_requests == 0) { ++ pr_err("bce-vhci: cannot init request (remaining_active_requests = 0)\n"); ++ return -EINVAL; ++ } ++ ++ if (vurb->is_control) { ++ vurb->state = BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST; ++ } else { ++ status = bce_vhci_urb_data_start(vurb, NULL); ++ } ++ ++ if (!status) { ++ --vurb->q->remaining_active_requests; ++ } ++ return status; ++} ++ ++static void bce_vhci_urb_complete(struct bce_vhci_urb *urb, int status) ++{ ++ struct bce_vhci_transfer_queue *q = urb->q; ++ struct bce_vhci *vhci = q->vhci; ++ struct urb *real_urb = urb->urb; ++ pr_debug("bce-vhci: [%02x] URB complete %i\n", q->endp_addr, status); ++ usb_hcd_unlink_urb_from_ep(vhci->hcd, real_urb); ++ real_urb->hcpriv = NULL; ++ real_urb->status = status; ++ if (urb->state != BCE_VHCI_URB_INIT_PENDING) ++ ++urb->q->remaining_active_requests; ++ kfree(urb); ++ list_add_tail(&real_urb->urb_list, &q->giveback_urb_list); ++} ++ ++int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *urb, int status) ++{ ++ struct bce_vhci_urb *vurb; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&q->urb_lock, flags); ++ if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ return ret; ++ } ++ ++ vurb = urb->hcpriv; ++ /* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */ ++ if (vurb->state != BCE_VHCI_URB_INIT_PENDING) { ++ pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_pause(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ ++ ++q->remaining_active_requests; ++ } ++ ++ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ ++ usb_hcd_giveback_urb(q->vhci->hcd, urb, status); ++ ++ if (vurb->state != BCE_VHCI_URB_INIT_PENDING) ++ bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++ ++ kfree(vurb); ++ ++ return 0; ++} ++ ++static int bce_vhci_urb_data_transfer_in(struct bce_vhci_urb *urb, unsigned long *timeout) ++{ ++ struct bce_vhci_message msg; ++ struct bce_qe_submission *s; ++ u32 tr_len; ++ int reservation1, reservation2 = -EFAULT; ++ ++ pr_debug("bce-vhci: [%02x] DMA from device %llx %x\n", urb->q->endp_addr, ++ (u64) urb->urb->transfer_dma, urb->urb->transfer_buffer_length); ++ ++ /* Reserve both a message and a submission, so we don't run into issues later. */ ++ reservation1 = bce_reserve_submission(urb->q->vhci->msg_asynchronous.sq, timeout); ++ if (!reservation1) ++ reservation2 = bce_reserve_submission(urb->q->sq_in, timeout); ++ if (reservation1 || reservation2) { ++ pr_err("bce-vhci: Failed to reserve a submission for URB data transfer\n"); ++ if (!reservation1) ++ bce_cancel_submission_reservation(urb->q->vhci->msg_asynchronous.sq); ++ return -ENOMEM; ++ } ++ ++ urb->send_offset = urb->receive_offset; ++ ++ tr_len = urb->urb->transfer_buffer_length - urb->send_offset; ++ ++ spin_lock(&urb->q->vhci->msg_asynchronous_lock); ++ msg.cmd = BCE_VHCI_CMD_TRANSFER_REQUEST; ++ msg.status = 0; ++ msg.param1 = ((urb->urb->ep->desc.bEndpointAddress & 0x8Fu) << 8) | urb->q->dev_addr; ++ msg.param2 = tr_len; ++ bce_vhci_message_queue_write(&urb->q->vhci->msg_asynchronous, &msg); ++ spin_unlock(&urb->q->vhci->msg_asynchronous_lock); ++ ++ s = bce_next_submission(urb->q->sq_in); ++ bce_set_submission_single(s, urb->urb->transfer_dma + urb->send_offset, tr_len); ++ bce_submit_to_device(urb->q->sq_in); ++ ++ urb->state = BCE_VHCI_URB_WAITING_FOR_COMPLETION; ++ return 0; ++} ++ ++static int bce_vhci_urb_data_start(struct bce_vhci_urb *urb, unsigned long *timeout) ++{ ++ if (urb->dir == DMA_TO_DEVICE) { ++ if (urb->urb->transfer_buffer_length > 0) ++ urb->state = BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST; ++ else ++ urb->state = BCE_VHCI_URB_DATA_TRANSFER_COMPLETE; ++ return 0; ++ } else { ++ return bce_vhci_urb_data_transfer_in(urb, timeout); ++ } ++} ++ ++static int bce_vhci_urb_send_out_data(struct bce_vhci_urb *urb, dma_addr_t addr, size_t size) ++{ ++ struct bce_qe_submission *s; ++ unsigned long timeout = 0; ++ if (bce_reserve_submission(urb->q->sq_out, &timeout)) { ++ pr_err("bce-vhci: Failed to reserve a submission for URB data transfer\n"); ++ return -EPIPE; ++ } ++ ++ pr_debug("bce-vhci: [%02x] DMA to device %llx %lx\n", urb->q->endp_addr, (u64) addr, size); ++ ++ s = bce_next_submission(urb->q->sq_out); ++ bce_set_submission_single(s, addr, size); ++ bce_submit_to_device(urb->q->sq_out); ++ return 0; ++} ++ ++static int bce_vhci_urb_data_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ u32 tr_len; ++ int status; ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST) { ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST) { ++ tr_len = min(urb->urb->transfer_buffer_length - urb->send_offset, (u32) msg->param2); ++ if ((status = bce_vhci_urb_send_out_data(urb, urb->urb->transfer_dma + urb->send_offset, tr_len))) ++ return status; ++ urb->send_offset += tr_len; ++ urb->state = BCE_VHCI_URB_WAITING_FOR_COMPLETION; ++ return 0; ++ } ++ } ++ ++ /* 0x1000 in out queues aren't really unexpected */ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && urb->q->sq_out != NULL) ++ return -EAGAIN; ++ pr_err("bce-vhci: [%02x] %s URB unexpected message (state = %x, msg: %x %x %x %llx)\n", ++ urb->q->endp_addr, (urb->is_control ? "Control (data update)" : "Data"), urb->state, ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ return -EAGAIN; ++} ++ ++static int bce_vhci_urb_data_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ urb->receive_offset += c->data_size; ++ if (urb->dir == DMA_FROM_DEVICE || urb->receive_offset >= urb->urb->transfer_buffer_length) { ++ urb->urb->actual_length = (u32) urb->receive_offset; ++ urb->state = BCE_VHCI_URB_DATA_TRANSFER_COMPLETE; ++ if (!urb->is_control) { ++ bce_vhci_urb_complete(urb, 0); ++ return -ENOENT; ++ } ++ } ++ } else { ++ pr_err("bce-vhci: [%02x] Data URB unexpected completion\n", urb->q->endp_addr); ++ } ++ return 0; ++} ++ ++ ++static int bce_vhci_urb_control_check_status(struct bce_vhci_urb *urb) ++{ ++ struct bce_vhci_transfer_queue *q = urb->q; ++ if (urb->received_status == 0) ++ return 0; ++ if (urb->state == BCE_VHCI_URB_DATA_TRANSFER_COMPLETE || ++ (urb->received_status != BCE_VHCI_SUCCESS && urb->state != BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST && ++ urb->state != BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION)) { ++ urb->state = BCE_VHCI_URB_CONTROL_COMPLETE; ++ if (urb->received_status != BCE_VHCI_SUCCESS) { ++ pr_err("bce-vhci: [%02x] URB failed: %x\n", urb->q->endp_addr, urb->received_status); ++ urb->q->active = false; ++ urb->q->stalled = true; ++ bce_vhci_urb_complete(urb, -EPIPE); ++ if (!list_empty(&q->endp->urb_list)) ++ bce_vhci_transfer_queue_request_reset(q); ++ return -ENOENT; ++ } ++ bce_vhci_urb_complete(urb, 0); ++ return -ENOENT; ++ } ++ return 0; ++} ++ ++static int bce_vhci_urb_control_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ int status; ++ if (msg->cmd == BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS) { ++ urb->received_status = msg->status; ++ return bce_vhci_urb_control_check_status(urb); ++ } ++ ++ if (urb->state == BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST) { ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST) { ++ if (bce_vhci_urb_send_out_data(urb, urb->urb->setup_dma, sizeof(struct usb_ctrlrequest))) { ++ pr_err("bce-vhci: [%02x] Failed to start URB setup transfer\n", urb->q->endp_addr); ++ return 0; /* TODO: fail the URB? */ ++ } ++ urb->state = BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION; ++ pr_debug("bce-vhci: [%02x] Sent setup %llx\n", urb->q->endp_addr, urb->urb->setup_dma); ++ return 0; ++ } ++ } else if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST || ++ urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ if ((status = bce_vhci_urb_data_update(urb, msg))) ++ return status; ++ return bce_vhci_urb_control_check_status(urb); ++ } ++ ++ /* 0x1000 in out queues aren't really unexpected */ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && urb->q->sq_out != NULL) ++ return -EAGAIN; ++ pr_err("bce-vhci: [%02x] Control URB unexpected message (state = %x, msg: %x %x %x %llx)\n", urb->q->endp_addr, ++ urb->state, msg->cmd, msg->status, msg->param1, msg->param2); ++ return -EAGAIN; ++} ++ ++static int bce_vhci_urb_control_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ int status; ++ unsigned long timeout; ++ ++ if (urb->state == BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION) { ++ if (c->data_size != sizeof(struct usb_ctrlrequest)) ++ pr_err("bce-vhci: [%02x] transfer complete data size mistmatch for usb_ctrlrequest (%llx instead of %lx)\n", ++ urb->q->endp_addr, c->data_size, sizeof(struct usb_ctrlrequest)); ++ ++ timeout = 1000; ++ status = bce_vhci_urb_data_start(urb, &timeout); ++ if (status) { ++ bce_vhci_urb_complete(urb, status); ++ return -ENOENT; ++ } ++ return 0; ++ } else if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST || ++ urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ if ((status = bce_vhci_urb_data_transfer_completion(urb, c))) ++ return status; ++ return bce_vhci_urb_control_check_status(urb); ++ } else { ++ pr_err("bce-vhci: [%02x] Control URB unexpected completion (state = %x)\n", urb->q->endp_addr, urb->state); ++ } ++ return 0; ++} ++ ++static int bce_vhci_urb_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ if (urb->state == BCE_VHCI_URB_INIT_PENDING) ++ return -EAGAIN; ++ if (urb->is_control) ++ return bce_vhci_urb_control_update(urb, msg); ++ else ++ return bce_vhci_urb_data_update(urb, msg); ++} ++ ++static int bce_vhci_urb_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ if (urb->is_control) ++ return bce_vhci_urb_control_transfer_completion(urb, c); ++ else ++ return bce_vhci_urb_data_transfer_completion(urb, c); ++} ++ ++static void bce_vhci_urb_resume(struct bce_vhci_urb *urb) ++{ ++ int status = 0; ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ status = bce_vhci_urb_data_transfer_in(urb, NULL); ++ } ++ if (status) ++ bce_vhci_urb_complete(urb, status); ++} +diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/transfer.h +@@ -0,0 +1,73 @@ ++#ifndef BCEDRIVER_TRANSFER_H ++#define BCEDRIVER_TRANSFER_H ++ ++#include ++#include "queue.h" ++#include "command.h" ++#include "../queue.h" ++ ++struct bce_vhci_list_message { ++ struct list_head list; ++ struct bce_vhci_message msg; ++}; ++enum bce_vhci_pause_source { ++ BCE_VHCI_PAUSE_INTERNAL_WQ = 1, ++ BCE_VHCI_PAUSE_FIRMWARE = 2, ++ BCE_VHCI_PAUSE_SUSPEND = 4, ++ BCE_VHCI_PAUSE_SHUTDOWN = 8 ++}; ++struct bce_vhci_transfer_queue { ++ struct bce_vhci *vhci; ++ struct usb_host_endpoint *endp; ++ enum bce_vhci_endpoint_state state; ++ u32 max_active_requests, remaining_active_requests; ++ bool active, stalled; ++ u32 paused_by; ++ bce_vhci_device_t dev_addr; ++ u8 endp_addr; ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq_in; ++ struct bce_queue_sq *sq_out; ++ struct list_head evq; ++ struct spinlock urb_lock; ++ struct mutex pause_lock; ++ struct list_head giveback_urb_list; ++ ++ struct work_struct w_reset; ++}; ++enum bce_vhci_urb_state { ++ BCE_VHCI_URB_INIT_PENDING, ++ ++ BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST, ++ BCE_VHCI_URB_WAITING_FOR_COMPLETION, ++ BCE_VHCI_URB_DATA_TRANSFER_COMPLETE, ++ ++ BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST, ++ BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION, ++ BCE_VHCI_URB_CONTROL_COMPLETE ++}; ++struct bce_vhci_urb { ++ struct urb *urb; ++ struct bce_vhci_transfer_queue *q; ++ enum dma_data_direction dir; ++ bool is_control; ++ enum bce_vhci_urb_state state; ++ int received_status; ++ u32 send_offset; ++ u32 receive_offset; ++}; ++ ++void bce_vhci_create_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q, ++ struct usb_host_endpoint *endp, bce_vhci_device_t dev_addr, enum dma_data_direction dir); ++void bce_vhci_destroy_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q); ++void bce_vhci_transfer_queue_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg); ++int bce_vhci_transfer_queue_do_pause(struct bce_vhci_transfer_queue *q); ++int bce_vhci_transfer_queue_do_resume(struct bce_vhci_transfer_queue *q); ++int bce_vhci_transfer_queue_pause(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src); ++int bce_vhci_transfer_queue_resume(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src); ++void bce_vhci_transfer_queue_request_reset(struct bce_vhci_transfer_queue *q); ++ ++int bce_vhci_urb_create(struct bce_vhci_transfer_queue *q, struct urb *urb); ++int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *urb, int status); ++ ++#endif //BCEDRIVER_TRANSFER_H +diff --git a/drivers/staging/apple-bce/vhci/vhci.c b/drivers/staging/apple-bce/vhci/vhci.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/vhci.c +@@ -0,0 +1,759 @@ ++#include "vhci.h" ++#include "../apple_bce.h" ++#include "command.h" ++#include ++#include ++#include ++#include ++ ++static dev_t bce_vhci_chrdev; ++static struct class *bce_vhci_class; ++static const struct hc_driver bce_vhci_driver; ++static u16 bce_vhci_port_mask = U16_MAX; ++ ++static int bce_vhci_create_event_queues(struct bce_vhci *vhci); ++static void bce_vhci_destroy_event_queues(struct bce_vhci *vhci); ++static int bce_vhci_create_message_queues(struct bce_vhci *vhci); ++static void bce_vhci_destroy_message_queues(struct bce_vhci *vhci); ++static void bce_vhci_handle_firmware_events_w(struct work_struct *ws); ++static void bce_vhci_firmware_event_completion(struct bce_queue_sq *sq); ++ ++int bce_vhci_create(struct apple_bce_device *dev, struct bce_vhci *vhci) ++{ ++ int status; ++ ++ spin_lock_init(&vhci->hcd_spinlock); ++ ++ vhci->dev = dev; ++ ++ vhci->vdevt = bce_vhci_chrdev; ++ vhci->vdev = device_create(bce_vhci_class, dev->dev, vhci->vdevt, NULL, "bce-vhci"); ++ if (IS_ERR_OR_NULL(vhci->vdev)) { ++ status = PTR_ERR(vhci->vdev); ++ goto fail_dev; ++ } ++ ++ if ((status = bce_vhci_create_message_queues(vhci))) ++ goto fail_mq; ++ if ((status = bce_vhci_create_event_queues(vhci))) ++ goto fail_eq; ++ ++ vhci->tq_state_wq = alloc_ordered_workqueue("bce-vhci-tq-state", 0); ++ INIT_WORK(&vhci->w_fw_events, bce_vhci_handle_firmware_events_w); ++ ++ vhci->hcd = usb_create_hcd(&bce_vhci_driver, vhci->vdev, "bce-vhci"); ++ if (!vhci->hcd) { ++ status = -ENOMEM; ++ goto fail_hcd; ++ } ++ vhci->hcd->self.sysdev = &dev->pci->dev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ++ vhci->hcd->self.uses_dma = 1; ++#endif ++ *((struct bce_vhci **) vhci->hcd->hcd_priv) = vhci; ++ vhci->hcd->speed = HCD_USB2; ++ ++ if ((status = usb_add_hcd(vhci->hcd, 0, 0))) ++ goto fail_hcd; ++ ++ return 0; ++ ++fail_hcd: ++ bce_vhci_destroy_event_queues(vhci); ++fail_eq: ++ bce_vhci_destroy_message_queues(vhci); ++fail_mq: ++ device_destroy(bce_vhci_class, vhci->vdevt); ++fail_dev: ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++void bce_vhci_destroy(struct bce_vhci *vhci) ++{ ++ usb_remove_hcd(vhci->hcd); ++ bce_vhci_destroy_event_queues(vhci); ++ bce_vhci_destroy_message_queues(vhci); ++ device_destroy(bce_vhci_class, vhci->vdevt); ++} ++ ++struct bce_vhci *bce_vhci_from_hcd(struct usb_hcd *hcd) ++{ ++ return *((struct bce_vhci **) hcd->hcd_priv); ++} ++ ++int bce_vhci_start(struct usb_hcd *hcd) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int status; ++ u16 port_mask = 0; ++ bce_vhci_port_t port_no = 0; ++ if ((status = bce_vhci_cmd_controller_enable(&vhci->cq, 1, &port_mask))) ++ return status; ++ vhci->port_mask = port_mask; ++ vhci->port_power_mask = 0; ++ if ((status = bce_vhci_cmd_controller_start(&vhci->cq))) ++ return status; ++ port_mask = vhci->port_mask; ++ while (port_mask) { ++ port_no += 1; ++ port_mask >>= 1; ++ } ++ vhci->port_count = port_no; ++ return 0; ++} ++ ++void bce_vhci_stop(struct usb_hcd *hcd) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_cmd_controller_disable(&vhci->cq); ++} ++ ++static int bce_vhci_hub_status_data(struct usb_hcd *hcd, char *buf) ++{ ++ return 0; ++} ++ ++static int bce_vhci_reset_device(struct bce_vhci *vhci, int index, u16 timeout); ++ ++static int bce_vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int status; ++ struct usb_hub_descriptor *hd; ++ struct usb_hub_status *hs; ++ struct usb_port_status *ps; ++ u32 port_status; ++ // pr_info("bce-vhci: bce_vhci_hub_control %x %i %i [bufl=%i]\n", typeReq, wValue, wIndex, wLength); ++ if (typeReq == GetHubDescriptor && wLength >= sizeof(struct usb_hub_descriptor)) { ++ hd = (struct usb_hub_descriptor *) buf; ++ memset(hd, 0, sizeof(*hd)); ++ hd->bDescLength = sizeof(struct usb_hub_descriptor); ++ hd->bDescriptorType = USB_DT_HUB; ++ hd->bNbrPorts = (u8) vhci->port_count; ++ hd->wHubCharacteristics = HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_INDV_PORT_OCPM; ++ hd->bPwrOn2PwrGood = 0; ++ hd->bHubContrCurrent = 0; ++ return 0; ++ } else if (typeReq == GetHubStatus && wLength >= sizeof(struct usb_hub_status)) { ++ hs = (struct usb_hub_status *) buf; ++ memset(hs, 0, sizeof(*hs)); ++ hs->wHubStatus = 0; ++ hs->wHubChange = 0; ++ return 0; ++ } else if (typeReq == GetPortStatus && wLength >= 4 /* usb 2.0 */) { ++ ps = (struct usb_port_status *) buf; ++ ps->wPortStatus = 0; ++ ps->wPortChange = 0; ++ ++ if (vhci->port_power_mask & BIT(wIndex)) ++ ps->wPortStatus |= USB_PORT_STAT_POWER; ++ ++ if (!(bce_vhci_port_mask & BIT(wIndex))) ++ return 0; ++ ++ if ((status = bce_vhci_cmd_port_status(&vhci->cq, (u8) wIndex, 0, &port_status))) ++ return status; ++ ++ if (port_status & 16) ++ ps->wPortStatus |= USB_PORT_STAT_ENABLE | USB_PORT_STAT_HIGH_SPEED; ++ if (port_status & 4) ++ ps->wPortStatus |= USB_PORT_STAT_CONNECTION; ++ if (port_status & 2) ++ ps->wPortStatus |= USB_PORT_STAT_OVERCURRENT; ++ if (port_status & 8) ++ ps->wPortStatus |= USB_PORT_STAT_RESET; ++ if (port_status & 0x60) ++ ps->wPortStatus |= USB_PORT_STAT_SUSPEND; ++ ++ if (port_status & 0x40000) ++ ps->wPortChange |= USB_PORT_STAT_C_CONNECTION; ++ ++ pr_debug("bce-vhci: Translated status %x to %x:%x\n", port_status, ps->wPortStatus, ps->wPortChange); ++ return 0; ++ } else if (typeReq == SetPortFeature) { ++ if (wValue == USB_PORT_FEAT_POWER) { ++ status = bce_vhci_cmd_port_power_on(&vhci->cq, (u8) wIndex); ++ /* As far as I am aware, power status is not part of the port status so store it separately */ ++ if (!status) ++ vhci->port_power_mask |= BIT(wIndex); ++ return status; ++ } ++ if (wValue == USB_PORT_FEAT_RESET) { ++ return bce_vhci_reset_device(vhci, wIndex, wValue); ++ } ++ if (wValue == USB_PORT_FEAT_SUSPEND) { ++ /* TODO: Am I supposed to also suspend the endpoints? */ ++ pr_debug("bce-vhci: Suspending port %i\n", wIndex); ++ return bce_vhci_cmd_port_suspend(&vhci->cq, (u8) wIndex); ++ } ++ } else if (typeReq == ClearPortFeature) { ++ if (wValue == USB_PORT_FEAT_ENABLE) ++ return bce_vhci_cmd_port_disable(&vhci->cq, (u8) wIndex); ++ if (wValue == USB_PORT_FEAT_POWER) { ++ status = bce_vhci_cmd_port_power_off(&vhci->cq, (u8) wIndex); ++ if (!status) ++ vhci->port_power_mask &= ~BIT(wIndex); ++ return status; ++ } ++ if (wValue == USB_PORT_FEAT_C_CONNECTION) ++ return bce_vhci_cmd_port_status(&vhci->cq, (u8) wIndex, 0x40000, &port_status); ++ if (wValue == USB_PORT_FEAT_C_RESET) { /* I don't think I can transfer it in any way */ ++ return 0; ++ } ++ if (wValue == USB_PORT_FEAT_SUSPEND) { ++ pr_debug("bce-vhci: Resuming port %i\n", wIndex); ++ return bce_vhci_cmd_port_resume(&vhci->cq, (u8) wIndex); ++ } ++ } ++ pr_err("bce-vhci: bce_vhci_hub_control unhandled request: %x %i %i [bufl=%i]\n", typeReq, wValue, wIndex, wLength); ++ dump_stack(); ++ return -EIO; ++} ++ ++static int bce_vhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ struct bce_vhci_device *vdev; ++ bce_vhci_device_t devid; ++ pr_info("bce_vhci_enable_device\n"); ++ ++ if (vhci->port_to_device[udev->portnum]) ++ return 0; ++ ++ /* We need to early address the device */ ++ if (bce_vhci_cmd_device_create(&vhci->cq, udev->portnum, &devid)) ++ return -EIO; ++ ++ pr_info("bce_vhci_cmd_device_create %i -> %i\n", udev->portnum, devid); ++ ++ vdev = kzalloc(sizeof(struct bce_vhci_device), GFP_KERNEL); ++ vhci->port_to_device[udev->portnum] = devid; ++ vhci->devices[devid] = vdev; ++ ++ bce_vhci_create_transfer_queue(vhci, &vdev->tq[0], &udev->ep0, devid, DMA_BIDIRECTIONAL); ++ udev->ep0.hcpriv = &vdev->tq[0]; ++ vdev->tq_mask |= BIT(0); ++ ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &udev->ep0.desc); ++ return 0; ++} ++ ++static int bce_vhci_address_device(struct usb_hcd *hcd, struct usb_device *udev, unsigned int timeout_ms) //TODO: follow timeout ++{ ++ /* This is the same as enable_device, but instead in the old scheme */ ++ return bce_vhci_enable_device(hcd, udev); ++} ++ ++static void bce_vhci_free_device(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int i; ++ bce_vhci_device_t devid; ++ struct bce_vhci_device *dev; ++ pr_info("bce_vhci_free_device %i\n", udev->portnum); ++ if (!vhci->port_to_device[udev->portnum]) ++ return; ++ devid = vhci->port_to_device[udev->portnum]; ++ dev = vhci->devices[devid]; ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ bce_vhci_transfer_queue_pause(&dev->tq[i], BCE_VHCI_PAUSE_SHUTDOWN); ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) i); ++ bce_vhci_destroy_transfer_queue(vhci, &dev->tq[i]); ++ } ++ } ++ vhci->devices[devid] = NULL; ++ vhci->port_to_device[udev->portnum] = 0; ++ bce_vhci_cmd_device_destroy(&vhci->cq, devid); ++ kfree(dev); ++} ++ ++static int bce_vhci_reset_device(struct bce_vhci *vhci, int index, u16 timeout) ++{ ++ struct bce_vhci_device *dev = NULL; ++ bce_vhci_device_t devid; ++ int i; ++ int status; ++ enum dma_data_direction dir; ++ pr_info("bce_vhci_reset_device %i\n", index); ++ ++ devid = vhci->port_to_device[index]; ++ if (devid) { ++ dev = vhci->devices[devid]; ++ ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ bce_vhci_transfer_queue_pause(&dev->tq[i], BCE_VHCI_PAUSE_SHUTDOWN); ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) i); ++ bce_vhci_destroy_transfer_queue(vhci, &dev->tq[i]); ++ } ++ } ++ vhci->devices[devid] = NULL; ++ vhci->port_to_device[index] = 0; ++ bce_vhci_cmd_device_destroy(&vhci->cq, devid); ++ } ++ status = bce_vhci_cmd_port_reset(&vhci->cq, (u8) index, timeout); ++ ++ if (dev) { ++ if ((status = bce_vhci_cmd_device_create(&vhci->cq, index, &devid))) ++ return status; ++ vhci->devices[devid] = dev; ++ vhci->port_to_device[index] = devid; ++ ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ dir = usb_endpoint_dir_in(&dev->tq[i].endp->desc) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; ++ if (i == 0) ++ dir = DMA_BIDIRECTIONAL; ++ bce_vhci_create_transfer_queue(vhci, &dev->tq[i], dev->tq[i].endp, devid, dir); ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &dev->tq[i].endp->desc); ++ } ++ } ++ } ++ ++ return status; ++} ++ ++static int bce_vhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ return 0; ++} ++ ++static int bce_vhci_get_frame_number(struct usb_hcd *hcd) ++{ ++ return 0; ++} ++ ++static int bce_vhci_bus_suspend(struct usb_hcd *hcd) ++{ ++ int i, j; ++ int status; ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ pr_info("bce_vhci: suspend started\n"); ++ ++ pr_info("bce_vhci: suspend endpoints\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ for (j = 0; j < 32; j++) { ++ if (!(vhci->devices[vhci->port_to_device[i]]->tq_mask & BIT(j))) ++ continue; ++ bce_vhci_transfer_queue_pause(&vhci->devices[vhci->port_to_device[i]]->tq[j], ++ BCE_VHCI_PAUSE_SUSPEND); ++ } ++ } ++ ++ pr_info("bce_vhci: suspend ports\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ bce_vhci_cmd_port_suspend(&vhci->cq, i); ++ } ++ pr_info("bce_vhci: suspend controller\n"); ++ if ((status = bce_vhci_cmd_controller_pause(&vhci->cq))) ++ return status; ++ ++ bce_vhci_event_queue_pause(&vhci->ev_commands); ++ bce_vhci_event_queue_pause(&vhci->ev_system); ++ bce_vhci_event_queue_pause(&vhci->ev_isochronous); ++ bce_vhci_event_queue_pause(&vhci->ev_interrupt); ++ bce_vhci_event_queue_pause(&vhci->ev_asynchronous); ++ pr_info("bce_vhci: suspend done\n"); ++ return 0; ++} ++ ++static int bce_vhci_bus_resume(struct usb_hcd *hcd) ++{ ++ int i, j; ++ int status; ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ pr_info("bce_vhci: resume started\n"); ++ ++ bce_vhci_event_queue_resume(&vhci->ev_system); ++ bce_vhci_event_queue_resume(&vhci->ev_isochronous); ++ bce_vhci_event_queue_resume(&vhci->ev_interrupt); ++ bce_vhci_event_queue_resume(&vhci->ev_asynchronous); ++ bce_vhci_event_queue_resume(&vhci->ev_commands); ++ ++ pr_info("bce_vhci: resume controller\n"); ++ if ((status = bce_vhci_cmd_controller_start(&vhci->cq))) ++ return status; ++ ++ pr_info("bce_vhci: resume ports\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ bce_vhci_cmd_port_resume(&vhci->cq, i); ++ } ++ pr_info("bce_vhci: resume endpoints\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ for (j = 0; j < 32; j++) { ++ if (!(vhci->devices[vhci->port_to_device[i]]->tq_mask & BIT(j))) ++ continue; ++ bce_vhci_transfer_queue_resume(&vhci->devices[vhci->port_to_device[i]]->tq[j], ++ BCE_VHCI_PAUSE_SUSPEND); ++ } ++ } ++ ++ pr_info("bce_vhci: resume done\n"); ++ return 0; ++} ++ ++static int bce_vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ++{ ++ struct bce_vhci_transfer_queue *q = urb->ep->hcpriv; ++ pr_debug("bce_vhci_urb_enqueue %i:%x\n", q->dev_addr, urb->ep->desc.bEndpointAddress); ++ if (!q) ++ return -ENOENT; ++ return bce_vhci_urb_create(q, urb); ++} ++ ++static int bce_vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ++{ ++ struct bce_vhci_transfer_queue *q = urb->ep->hcpriv; ++ pr_debug("bce_vhci_urb_dequeue %x\n", urb->ep->desc.bEndpointAddress); ++ return bce_vhci_urb_request_cancel(q, urb, status); ++} ++ ++static void bce_vhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) ++{ ++ struct bce_vhci_transfer_queue *q = ep->hcpriv; ++ pr_debug("bce_vhci_endpoint_reset\n"); ++ if (q) ++ bce_vhci_transfer_queue_request_reset(q); ++} ++ ++static u8 bce_vhci_endpoint_index(u8 addr) ++{ ++ if (addr & 0x80) ++ return (u8) (0x10 + (addr & 0xf)); ++ return (u8) (addr & 0xf); ++} ++ ++static int bce_vhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *endp) ++{ ++ u8 endp_index = bce_vhci_endpoint_index(endp->desc.bEndpointAddress); ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_device_t devid = vhci->port_to_device[udev->portnum]; ++ struct bce_vhci_device *vdev = vhci->devices[devid]; ++ pr_debug("bce_vhci_add_endpoint %x/%x:%x\n", udev->portnum, devid, endp_index); ++ ++ if (udev->bus->root_hub == udev) /* The USB hub */ ++ return 0; ++ if (vdev == NULL) ++ return -ENODEV; ++ if (vdev->tq_mask & BIT(endp_index)) { ++ endp->hcpriv = &vdev->tq[endp_index]; ++ return 0; ++ } ++ ++ bce_vhci_create_transfer_queue(vhci, &vdev->tq[endp_index], endp, devid, ++ usb_endpoint_dir_in(&endp->desc) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); ++ endp->hcpriv = &vdev->tq[endp_index]; ++ vdev->tq_mask |= BIT(endp_index); ++ ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &endp->desc); ++ return 0; ++} ++ ++static int bce_vhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *endp) ++{ ++ u8 endp_index = bce_vhci_endpoint_index(endp->desc.bEndpointAddress); ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_device_t devid = vhci->port_to_device[udev->portnum]; ++ struct bce_vhci_transfer_queue *q = endp->hcpriv; ++ struct bce_vhci_device *vdev = vhci->devices[devid]; ++ pr_info("bce_vhci_drop_endpoint %x:%x\n", udev->portnum, endp_index); ++ if (!q) { ++ if (vdev && vdev->tq_mask & BIT(endp_index)) { ++ pr_err("something deleted the hcpriv?\n"); ++ q = &vdev->tq[endp_index]; ++ } else { ++ return 0; ++ } ++ } ++ ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) (endp->desc.bEndpointAddress & 0x8Fu)); ++ vhci->devices[devid]->tq_mask &= ~BIT(endp_index); ++ bce_vhci_destroy_transfer_queue(vhci, q); ++ return 0; ++} ++ ++static int bce_vhci_create_message_queues(struct bce_vhci *vhci) ++{ ++ if (bce_vhci_message_queue_create(vhci, &vhci->msg_commands, "VHC1HostCommands") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_system, "VHC1HostSystemEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_isochronous, "VHC1HostIsochronousEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_interrupt, "VHC1HostInterruptEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_asynchronous, "VHC1HostAsynchronousEvents")) { ++ bce_vhci_destroy_message_queues(vhci); ++ return -EINVAL; ++ } ++ spin_lock_init(&vhci->msg_asynchronous_lock); ++ bce_vhci_command_queue_create(&vhci->cq, &vhci->msg_commands); ++ return 0; ++} ++ ++static void bce_vhci_destroy_message_queues(struct bce_vhci *vhci) ++{ ++ bce_vhci_command_queue_destroy(&vhci->cq); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_commands); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_system); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_isochronous); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_interrupt); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_asynchronous); ++} ++ ++static void bce_vhci_handle_system_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++static void bce_vhci_handle_usb_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++ ++static int bce_vhci_create_event_queues(struct bce_vhci *vhci) ++{ ++ vhci->ev_cq = bce_create_cq(vhci->dev, 0x100); ++ if (!vhci->ev_cq) ++ return -EINVAL; ++#define CREATE_EVENT_QUEUE(field, name, cb) bce_vhci_event_queue_create(vhci, &vhci->field, name, cb) ++ if (__bce_vhci_event_queue_create(vhci, &vhci->ev_commands, "VHC1FirmwareCommands", ++ bce_vhci_firmware_event_completion) || ++ CREATE_EVENT_QUEUE(ev_system, "VHC1FirmwareSystemEvents", bce_vhci_handle_system_event) || ++ CREATE_EVENT_QUEUE(ev_isochronous, "VHC1FirmwareIsochronousEvents", bce_vhci_handle_usb_event) || ++ CREATE_EVENT_QUEUE(ev_interrupt, "VHC1FirmwareInterruptEvents", bce_vhci_handle_usb_event) || ++ CREATE_EVENT_QUEUE(ev_asynchronous, "VHC1FirmwareAsynchronousEvents", bce_vhci_handle_usb_event)) { ++ bce_vhci_destroy_event_queues(vhci); ++ return -EINVAL; ++ } ++#undef CREATE_EVENT_QUEUE ++ return 0; ++} ++ ++static void bce_vhci_destroy_event_queues(struct bce_vhci *vhci) ++{ ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_commands); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_system); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_isochronous); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_interrupt); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_asynchronous); ++ if (vhci->ev_cq) ++ bce_destroy_cq(vhci->dev, vhci->ev_cq); ++} ++ ++static void bce_vhci_send_fw_event_response(struct bce_vhci *vhci, struct bce_vhci_message *req, u16 status) ++{ ++ unsigned long timeout = 1000; ++ struct bce_vhci_message r = *req; ++ r.cmd = (u16) (req->cmd | 0x8000u); ++ r.status = status; ++ r.param1 = req->param1; ++ r.param2 = 0; ++ ++ if (bce_reserve_submission(vhci->msg_system.sq, &timeout)) { ++ pr_err("bce-vhci: Cannot reserve submision for FW event reply\n"); ++ return; ++ } ++ bce_vhci_message_queue_write(&vhci->msg_system, &r); ++} ++ ++static int bce_vhci_handle_firmware_event(struct bce_vhci *vhci, struct bce_vhci_message *msg) ++{ ++ unsigned long flags; ++ bce_vhci_device_t devid; ++ u8 endp; ++ struct bce_vhci_device *dev; ++ struct bce_vhci_transfer_queue *tq; ++ if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE || msg->cmd == BCE_VHCI_CMD_ENDPOINT_SET_STATE) { ++ devid = (bce_vhci_device_t) (msg->param1 & 0xff); ++ endp = bce_vhci_endpoint_index((u8) ((msg->param1 >> 8) & 0xff)); ++ dev = vhci->devices[devid]; ++ if (!dev || !(dev->tq_mask & BIT(endp))) ++ return BCE_VHCI_BAD_ARGUMENT; ++ tq = &dev->tq[endp]; ++ } ++ ++ if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE) { ++ if (msg->param2 == BCE_VHCI_ENDPOINT_ACTIVE) { ++ bce_vhci_transfer_queue_resume(tq, BCE_VHCI_PAUSE_FIRMWARE); ++ return BCE_VHCI_SUCCESS; ++ } else if (msg->param2 == BCE_VHCI_ENDPOINT_PAUSED) { ++ bce_vhci_transfer_queue_pause(tq, BCE_VHCI_PAUSE_FIRMWARE); ++ return BCE_VHCI_SUCCESS; ++ } ++ return BCE_VHCI_BAD_ARGUMENT; ++ } else if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_SET_STATE) { ++ if (msg->param2 == BCE_VHCI_ENDPOINT_STALLED) { ++ tq->state = msg->param2; ++ spin_lock_irqsave(&tq->urb_lock, flags); ++ tq->stalled = true; ++ spin_unlock_irqrestore(&tq->urb_lock, flags); ++ return BCE_VHCI_SUCCESS; ++ } ++ return BCE_VHCI_BAD_ARGUMENT; ++ } ++ pr_warn("bce-vhci: Unhandled firmware event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ return BCE_VHCI_BAD_ARGUMENT; ++} ++ ++static void bce_vhci_handle_firmware_events_w(struct work_struct *ws) ++{ ++ size_t cnt = 0; ++ int result; ++ struct bce_vhci *vhci = container_of(ws, struct bce_vhci, w_fw_events); ++ struct bce_queue_sq *sq = vhci->ev_commands.sq; ++ struct bce_sq_completion_data *cq; ++ struct bce_vhci_message *msg, *msg2 = NULL; ++ ++ while (true) { ++ if (msg2) { ++ msg = msg2; ++ msg2 = NULL; ++ } else if ((cq = bce_next_completion(sq))) { ++ if (cq->status == BCE_COMPLETION_ABORTED) { ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ msg = &vhci->ev_commands.data[sq->head]; ++ } else { ++ break; ++ } ++ ++ pr_debug("bce-vhci: Got fw event: %x s=%x p1=%x p2=%llx\n", msg->cmd, msg->status, msg->param1, msg->param2); ++ if ((cq = bce_next_completion(sq))) { ++ msg2 = &vhci->ev_commands.data[(sq->head + 1) % sq->el_count]; ++ pr_debug("bce-vhci: Got second fw event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ if (cq->status != BCE_COMPLETION_ABORTED && ++ msg2->cmd == (msg->cmd | 0x4000) && msg2->param1 == msg->param1) { ++ /* Take two elements */ ++ pr_debug("bce-vhci: Cancelled\n"); ++ bce_vhci_send_fw_event_response(vhci, msg, BCE_VHCI_ABORT); ++ ++ bce_notify_submission_complete(sq); ++ bce_notify_submission_complete(sq); ++ msg2 = NULL; ++ cnt += 2; ++ continue; ++ } ++ ++ pr_warn("bce-vhci: Handle fw event - unexpected cancellation\n"); ++ } ++ ++ result = bce_vhci_handle_firmware_event(vhci, msg); ++ bce_vhci_send_fw_event_response(vhci, msg, (u16) result); ++ ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ bce_vhci_event_queue_submit_pending(&vhci->ev_commands, cnt); ++ if (atomic_read(&sq->available_commands) == sq->el_count - 1) { ++ pr_debug("bce-vhci: complete\n"); ++ complete(&vhci->ev_commands.queue_empty_completion); ++ } ++} ++ ++static void bce_vhci_firmware_event_completion(struct bce_queue_sq *sq) ++{ ++ struct bce_vhci_event_queue *q = sq->userdata; ++ queue_work(q->vhci->tq_state_wq, &q->vhci->w_fw_events); ++} ++ ++static void bce_vhci_handle_system_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg) ++{ ++ if (msg->cmd & 0x8000) { ++ bce_vhci_command_queue_deliver_completion(&q->vhci->cq, msg); ++ } else { ++ pr_warn("bce-vhci: Unhandled system event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ } ++} ++ ++static void bce_vhci_handle_usb_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg) ++{ ++ bce_vhci_device_t devid; ++ u8 endp; ++ struct bce_vhci_device *dev; ++ if (msg->cmd & 0x8000) { ++ bce_vhci_command_queue_deliver_completion(&q->vhci->cq, msg); ++ } else if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST || msg->cmd == BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS) { ++ devid = (bce_vhci_device_t) (msg->param1 & 0xff); ++ endp = bce_vhci_endpoint_index((u8) ((msg->param1 >> 8) & 0xff)); ++ dev = q->vhci->devices[devid]; ++ if (!dev || (dev->tq_mask & BIT(endp)) == 0) { ++ pr_err("bce-vhci: Didn't find destination for transfer queue event\n"); ++ return; ++ } ++ bce_vhci_transfer_queue_event(&dev->tq[endp], msg); ++ } else { ++ pr_warn("bce-vhci: Unhandled USB event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ } ++} ++ ++ ++ ++static const struct hc_driver bce_vhci_driver = { ++ .description = "bce-vhci", ++ .product_desc = "BCE VHCI Host Controller", ++ .hcd_priv_size = sizeof(struct bce_vhci *), ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ++ .flags = HCD_USB2, ++#else ++ .flags = HCD_USB2 | HCD_DMA, ++#endif ++ ++ .start = bce_vhci_start, ++ .stop = bce_vhci_stop, ++ .hub_status_data = bce_vhci_hub_status_data, ++ .hub_control = bce_vhci_hub_control, ++ .urb_enqueue = bce_vhci_urb_enqueue, ++ .urb_dequeue = bce_vhci_urb_dequeue, ++ .enable_device = bce_vhci_enable_device, ++ .free_dev = bce_vhci_free_device, ++ .address_device = bce_vhci_address_device, ++ .add_endpoint = bce_vhci_add_endpoint, ++ .drop_endpoint = bce_vhci_drop_endpoint, ++ .endpoint_reset = bce_vhci_endpoint_reset, ++ .check_bandwidth = bce_vhci_check_bandwidth, ++ .get_frame_number = bce_vhci_get_frame_number, ++ .bus_suspend = bce_vhci_bus_suspend, ++ .bus_resume = bce_vhci_bus_resume ++}; ++ ++ ++int __init bce_vhci_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&bce_vhci_chrdev, 0, 1, "bce-vhci"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ bce_vhci_class = class_create(THIS_MODULE, "bce-vhci"); ++#else ++ bce_vhci_class = class_create("bce-vhci"); ++#endif ++ if (IS_ERR(bce_vhci_class)) { ++ result = PTR_ERR(bce_vhci_class); ++ goto fail_class; ++ } ++ return 0; ++ ++fail_class: ++ class_destroy(bce_vhci_class); ++fail_chrdev: ++ unregister_chrdev_region(bce_vhci_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++void __exit bce_vhci_module_exit(void) ++{ ++ class_destroy(bce_vhci_class); ++ unregister_chrdev_region(bce_vhci_chrdev, 1); ++} ++ ++module_param_named(vhci_port_mask, bce_vhci_port_mask, ushort, 0444); ++MODULE_PARM_DESC(vhci_port_mask, "Specifies which VHCI ports are enabled"); +diff --git a/drivers/staging/apple-bce/vhci/vhci.h b/drivers/staging/apple-bce/vhci/vhci.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/vhci.h +@@ -0,0 +1,52 @@ ++#ifndef BCE_VHCI_H ++#define BCE_VHCI_H ++ ++#include "queue.h" ++#include "transfer.h" ++ ++struct usb_hcd; ++struct bce_queue_cq; ++ ++struct bce_vhci_device { ++ struct bce_vhci_transfer_queue tq[32]; ++ u32 tq_mask; ++}; ++struct bce_vhci { ++ struct apple_bce_device *dev; ++ dev_t vdevt; ++ struct device *vdev; ++ struct usb_hcd *hcd; ++ struct spinlock hcd_spinlock; ++ struct bce_vhci_message_queue msg_commands; ++ struct bce_vhci_message_queue msg_system; ++ struct bce_vhci_message_queue msg_isochronous; ++ struct bce_vhci_message_queue msg_interrupt; ++ struct bce_vhci_message_queue msg_asynchronous; ++ struct spinlock msg_asynchronous_lock; ++ struct bce_vhci_command_queue cq; ++ struct bce_queue_cq *ev_cq; ++ struct bce_vhci_event_queue ev_commands; ++ struct bce_vhci_event_queue ev_system; ++ struct bce_vhci_event_queue ev_isochronous; ++ struct bce_vhci_event_queue ev_interrupt; ++ struct bce_vhci_event_queue ev_asynchronous; ++ u16 port_mask; ++ u8 port_count; ++ u16 port_power_mask; ++ bce_vhci_device_t port_to_device[16]; ++ struct bce_vhci_device *devices[16]; ++ struct workqueue_struct *tq_state_wq; ++ struct work_struct w_fw_events; ++}; ++ ++int __init bce_vhci_module_init(void); ++void __exit bce_vhci_module_exit(void); ++ ++int bce_vhci_create(struct apple_bce_device *dev, struct bce_vhci *vhci); ++void bce_vhci_destroy(struct bce_vhci *vhci); ++int bce_vhci_start(struct usb_hcd *hcd); ++void bce_vhci_stop(struct usb_hcd *hcd); ++ ++struct bce_vhci *bce_vhci_from_hcd(struct usb_hcd *hcd); ++ ++#endif //BCE_VHCI_H +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1002-Put-apple-bce-in-drivers-staging.patch b/patch/kernel/archive/uefi-x86-6.12/1002-Put-apple-bce-in-drivers-staging.patch new file mode 100644 index 000000000..1aebed2ce --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1002-Put-apple-bce-in-drivers-staging.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Redecorating <69827514+Redecorating@users.noreply.github.com> +Date: Mon, 7 Nov 2022 14:56:34 +0530 +Subject: Put apple-bce in drivers/staging + +- rpardini: 6.12: in drivers/staging/Makefile do it at the top to avoid + conflicts with Armbian's (wifi?) patching. + +Signed-off-by: Ricardo Pardini +--- + drivers/staging/Kconfig | 2 ++ + drivers/staging/Makefile | 1 + + drivers/staging/apple-bce/Kconfig | 18 ++++++++++ + drivers/staging/apple-bce/Makefile | 2 +- + 4 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -66,4 +66,6 @@ source "drivers/staging/vme_user/Kconfig" + + source "drivers/staging/rtl8723cs/Kconfig" + ++source "drivers/staging/apple-bce/Kconfig" ++ + endif # STAGING +diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -2,6 +2,7 @@ + # Makefile for staging directory + + obj-y += media/ ++obj-$(CONFIG_APPLE_BCE) += apple-bce/ + obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ + obj-$(CONFIG_RTL8192E) += rtl8192e/ + obj-$(CONFIG_RTL8723BS) += rtl8723bs/ +diff --git a/drivers/staging/apple-bce/Kconfig b/drivers/staging/apple-bce/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/Kconfig +@@ -0,0 +1,18 @@ ++config APPLE_BCE ++ tristate "Apple BCE driver (VHCI and Audio support)" ++ default m ++ depends on X86 ++ select SOUND ++ select SND ++ select SND_PCM ++ select SND_JACK ++ help ++ VHCI and audio support on Apple MacBooks with the T2 Chip. ++ This driver is divided in three components: ++ - BCE (Buffer Copy Engine): which establishes a basic communication ++ channel with the T2 chip. This component is required by the other two: ++ - VHCI (Virtual Host Controller Interface): Access to keyboard, mouse ++ and other system devices depend on this virtual USB host controller ++ - Audio: a driver for the T2 audio interface. ++ ++ If "M" is selected, the module will be called apple-bce.' +diff --git a/drivers/staging/apple-bce/Makefile b/drivers/staging/apple-bce/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/Makefile ++++ b/drivers/staging/apple-bce/Makefile +@@ -1,5 +1,5 @@ + modname := apple-bce +-obj-m += $(modname).o ++obj-$(CONFIG_APPLE_BCE) += $(modname).o + + apple-bce-objs := apple_bce.o mailbox.o queue.o queue_dma.o vhci/vhci.o vhci/queue.o vhci/transfer.o audio/audio.o audio/protocol.o audio/protocol_bce.o audio/pcm.o + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1003-Fix-sparse-errors.patch b/patch/kernel/archive/uefi-x86-6.12/1003-Fix-sparse-errors.patch new file mode 100644 index 000000000..c2ca16bf8 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1003-Fix-sparse-errors.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Sun, 13 Apr 2025 11:43:53 +0530 +Subject: Fix sparse errors + +apple_bce.h was using #pragma once, which is not acceptable by sparse +--- + drivers/staging/apple-bce/apple_bce.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/apple-bce/apple_bce.h b/drivers/staging/apple-bce/apple_bce.h +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/apple_bce.h ++++ b/drivers/staging/apple-bce/apple_bce.h +@@ -1,4 +1,5 @@ +-#pragma once ++#ifndef APPLE_BCE_H ++#define APPLE_BCE_H + + #include + #include +@@ -35,4 +36,6 @@ struct apple_bce_device { + struct bce_vhci vhci; + }; + +-extern struct apple_bce_device *global_bce; +\ No newline at end of file ++extern struct apple_bce_device *global_bce; ++ ++#endif //APPLE_BCE_H +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1004-Fix-freezing-on-turning-off-camera.patch b/patch/kernel/archive/uefi-x86-6.12/1004-Fix-freezing-on-turning-off-camera.patch new file mode 100644 index 000000000..f4f746a4d --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1004-Fix-freezing-on-turning-off-camera.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: mnural +Date: Mon, 14 Apr 2025 14:44:20 +0530 +Subject: Fix freezing on turning off camera + +Detailed logs and reason behind can be seen here: +https://github.com/t2linux/T2-Debian-and-Ubuntu-Kernel/issues/130#issuecomment-2799130835 +--- + drivers/staging/apple-bce/vhci/transfer.c | 16 ++++++++-- + drivers/staging/apple-bce/vhci/transfer.h | 4 ++- + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/vhci/transfer.c ++++ b/drivers/staging/apple-bce/vhci/transfer.c +@@ -400,6 +400,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + struct bce_vhci_urb *vurb; + unsigned long flags; + int ret; ++ enum bce_vhci_urb_state old_state; + + spin_lock_irqsave(&q->urb_lock, flags); + if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) { +@@ -408,8 +409,19 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + } + + vurb = urb->hcpriv; ++ ++ old_state = vurb->state; /* save old state to use later because we'll set state as cancelled */ ++ ++ if (old_state == BCE_VHCI_URB_CANCELLED) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ pr_debug("bce-vhci: URB %p is already cancelled, skipping\n", urb); ++ return 0; ++ } ++ ++ vurb->state = BCE_VHCI_URB_CANCELLED; ++ + /* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */ +- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) { ++ if (old_state != BCE_VHCI_URB_INIT_PENDING) { + pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr); + + spin_unlock_irqrestore(&q->urb_lock, flags); +@@ -425,7 +437,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + + usb_hcd_giveback_urb(q->vhci->hcd, urb, status); + +- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) ++ if (old_state != BCE_VHCI_URB_INIT_PENDING) + bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); + + kfree(vurb); +diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/vhci/transfer.h ++++ b/drivers/staging/apple-bce/vhci/transfer.h +@@ -44,7 +44,9 @@ enum bce_vhci_urb_state { + + BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST, + BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION, +- BCE_VHCI_URB_CONTROL_COMPLETE ++ BCE_VHCI_URB_CONTROL_COMPLETE, ++ ++ BCE_VHCI_URB_CANCELLED + }; + struct bce_vhci_urb { + struct urb *urb; +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1005-HID-hid-appletb-bl-add-driver-for-the-backlight-of-A.patch b/patch/kernel/archive/uefi-x86-6.12/1005-HID-hid-appletb-bl-add-driver-for-the-backlight-of-A.patch new file mode 100644 index 000000000..fb5a9cd01 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1005-HID-hid-appletb-bl-add-driver-for-the-backlight-of-A.patch @@ -0,0 +1,289 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Sun, 5 Mar 2023 18:52:43 +0300 +Subject: HID: hid-appletb-bl: add driver for the backlight of Apple Touch Bars + +This commit adds a driver for the backlight of Apple Touch Bars on x86 +Macs. Note that currently only T2 Macs are supported. + +This driver is based on previous work done by Ronald Tschalar +. + +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/Kconfig | 10 + + drivers/hid/Makefile | 1 + + drivers/hid/hid-appletb-bl.c | 204 ++++++++++ + drivers/hid/hid-quirks.c | 4 +- + 4 files changed, 218 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -148,6 +148,16 @@ config HID_APPLEIR + + Say Y here if you want support for Apple infrared remote control. + ++config HID_APPLETB_BL ++ tristate "Apple Touch Bar Backlight" ++ depends on BACKLIGHT_CLASS_DEVICE ++ help ++ Say Y here if you want support for the backlight of Touch Bars on x86 ++ MacBook Pros. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called hid-appletb-bl. ++ + config HID_ASUS + tristate "Asus" + depends on USB_HID +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -29,6 +29,7 @@ obj-$(CONFIG_HID_ALPS) += hid-alps.o + obj-$(CONFIG_HID_ACRUX) += hid-axff.o + obj-$(CONFIG_HID_APPLE) += hid-apple.o + obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o ++obj-$(CONFIG_HID_APPLETB_BL) += hid-appletb-bl.o + obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o + obj-$(CONFIG_HID_ASUS) += hid-asus.o + obj-$(CONFIG_HID_AUREAL) += hid-aureal.o +diff --git a/drivers/hid/hid-appletb-bl.c b/drivers/hid/hid-appletb-bl.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/hid-appletb-bl.c +@@ -0,0 +1,204 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Apple Touch Bar Backlight Driver ++ * ++ * Copyright (c) 2017-2018 Ronald Tschalär ++ * Copyright (c) 2022-2023 Kerem Karabay ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define APPLETB_BL_ON 1 ++#define APPLETB_BL_DIM 3 ++#define APPLETB_BL_OFF 4 ++ ++#define HID_UP_APPLEVENDOR_TB_BL 0xff120000 ++ ++#define HID_VD_APPLE_TB_BRIGHTNESS 0xff120001 ++#define HID_USAGE_AUX1 0xff120020 ++#define HID_USAGE_BRIGHTNESS 0xff120021 ++ ++static int appletb_bl_def_brightness = 2; ++module_param_named(brightness, appletb_bl_def_brightness, int, 0444); ++MODULE_PARM_DESC(brightness, "Default brightness:\n" ++ " 0 - Touchbar is off\n" ++ " 1 - Dim brightness\n" ++ " [2] - Full brightness"); ++ ++struct appletb_bl { ++ struct hid_field *aux1_field, *brightness_field; ++ struct backlight_device *bdev; ++ ++ bool full_on; ++}; ++ ++static const u8 appletb_bl_brightness_map[] = { ++ APPLETB_BL_OFF, ++ APPLETB_BL_DIM, ++ APPLETB_BL_ON, ++}; ++ ++static int appletb_bl_set_brightness(struct appletb_bl *bl, u8 brightness) ++{ ++ struct hid_report *report = bl->brightness_field->report; ++ struct hid_device *hdev = report->device; ++ int ret; ++ ++ ret = hid_set_field(bl->aux1_field, 0, 1); ++ if (ret) { ++ hid_err(hdev, "Failed to set auxiliary field (%pe)\n", ERR_PTR(ret)); ++ return ret; ++ } ++ ++ ret = hid_set_field(bl->brightness_field, 0, brightness); ++ if (ret) { ++ hid_err(hdev, "Failed to set brightness field (%pe)\n", ERR_PTR(ret)); ++ return ret; ++ } ++ ++ if (!bl->full_on) { ++ ret = hid_hw_power(hdev, PM_HINT_FULLON); ++ if (ret < 0) { ++ hid_err(hdev, "Device didn't power on (%pe)\n", ERR_PTR(ret)); ++ return ret; ++ } ++ ++ bl->full_on = true; ++ } ++ ++ hid_hw_request(hdev, report, HID_REQ_SET_REPORT); ++ ++ if (brightness == APPLETB_BL_OFF) { ++ hid_hw_power(hdev, PM_HINT_NORMAL); ++ bl->full_on = false; ++ } ++ ++ return 0; ++} ++ ++static int appletb_bl_update_status(struct backlight_device *bdev) ++{ ++ struct appletb_bl *bl = bl_get_data(bdev); ++ u8 brightness; ++ ++ if (backlight_is_blank(bdev)) ++ brightness = APPLETB_BL_OFF; ++ else ++ brightness = appletb_bl_brightness_map[backlight_get_brightness(bdev)]; ++ ++ return appletb_bl_set_brightness(bl, brightness); ++} ++ ++static const struct backlight_ops appletb_bl_backlight_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .update_status = appletb_bl_update_status, ++}; ++ ++static int appletb_bl_probe(struct hid_device *hdev, const struct hid_device_id *id) ++{ ++ struct hid_field *aux1_field, *brightness_field; ++ struct backlight_properties bl_props = { 0 }; ++ struct device *dev = &hdev->dev; ++ struct appletb_bl *bl; ++ int ret; ++ ++ ret = hid_parse(hdev); ++ if (ret) ++ return dev_err_probe(dev, ret, "HID parse failed\n"); ++ ++ aux1_field = hid_find_field(hdev, HID_FEATURE_REPORT, ++ HID_VD_APPLE_TB_BRIGHTNESS, HID_USAGE_AUX1); ++ ++ brightness_field = hid_find_field(hdev, HID_FEATURE_REPORT, ++ HID_VD_APPLE_TB_BRIGHTNESS, HID_USAGE_BRIGHTNESS); ++ ++ if (!aux1_field || !brightness_field) ++ return -ENODEV; ++ ++ if (aux1_field->report != brightness_field->report) ++ return dev_err_probe(dev, -ENODEV, "Encountered unexpected report structure\n"); ++ ++ bl = devm_kzalloc(dev, sizeof(*bl), GFP_KERNEL); ++ if (!bl) ++ return -ENOMEM; ++ ++ ret = hid_hw_start(hdev, HID_CONNECT_DRIVER); ++ if (ret) ++ return dev_err_probe(dev, ret, "HID hardware start failed\n"); ++ ++ ret = hid_hw_open(hdev); ++ if (ret) { ++ dev_err_probe(dev, ret, "HID hardware open failed\n"); ++ goto stop_hw; ++ } ++ ++ bl->aux1_field = aux1_field; ++ bl->brightness_field = brightness_field; ++ ++ ret = appletb_bl_set_brightness(bl, ++ appletb_bl_brightness_map[(appletb_bl_def_brightness > 2) ? 2 : appletb_bl_def_brightness]); ++ ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to set default touch bar brightness to %d\n", ++ appletb_bl_def_brightness); ++ goto close_hw; ++ } ++ ++ bl_props.type = BACKLIGHT_RAW; ++ bl_props.max_brightness = ARRAY_SIZE(appletb_bl_brightness_map) - 1; ++ ++ bl->bdev = devm_backlight_device_register(dev, "appletb_backlight", dev, bl, ++ &appletb_bl_backlight_ops, &bl_props); ++ if (IS_ERR(bl->bdev)) { ++ ret = PTR_ERR(bl->bdev); ++ dev_err_probe(dev, ret, "Failed to register backlight device\n"); ++ goto close_hw; ++ } ++ ++ hid_set_drvdata(hdev, bl); ++ ++ return 0; ++ ++close_hw: ++ hid_hw_close(hdev); ++stop_hw: ++ hid_hw_stop(hdev); ++ ++ return ret; ++} ++ ++static void appletb_bl_remove(struct hid_device *hdev) ++{ ++ struct appletb_bl *bl = hid_get_drvdata(hdev); ++ ++ appletb_bl_set_brightness(bl, APPLETB_BL_OFF); ++ ++ hid_hw_close(hdev); ++ hid_hw_stop(hdev); ++} ++ ++static const struct hid_device_id appletb_bl_hid_ids[] = { ++ /* MacBook Pro's 2018, 2019, with T2 chip: iBridge DFR Brightness */ ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, appletb_bl_hid_ids); ++ ++static struct hid_driver appletb_bl_hid_driver = { ++ .name = "hid-appletb-bl", ++ .id_table = appletb_bl_hid_ids, ++ .probe = appletb_bl_probe, ++ .remove = appletb_bl_remove, ++}; ++module_hid_driver(appletb_bl_hid_driver); ++ ++MODULE_AUTHOR("Ronald Tschalär"); ++MODULE_AUTHOR("Kerem Karabay "); ++MODULE_DESCRIPTION("MacBook Pro Touch Bar Backlight driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -332,7 +332,6 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, + #endif + #if IS_ENABLED(CONFIG_HID_APPLEIR) +@@ -342,6 +341,9 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, + #endif ++#if IS_ENABLED(CONFIG_HID_APPLETB_BL) ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) }, ++#endif + #if IS_ENABLED(CONFIG_HID_ASUS) + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) }, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1006-HID-hid-appletb-kbd-add-driver-for-the-keyboard-mode.patch b/patch/kernel/archive/uefi-x86-6.12/1006-HID-hid-appletb-kbd-add-driver-for-the-keyboard-mode.patch new file mode 100644 index 000000000..60cb8eb0f --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1006-HID-hid-appletb-kbd-add-driver-for-the-keyboard-mode.patch @@ -0,0 +1,623 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Sun, 5 Mar 2023 18:17:23 +0300 +Subject: HID: hid-appletb-kbd: add driver for the keyboard mode of Apple Touch + Bars + +The Touch Bars found on x86 Macs support two USB configurations: one +where the device presents itself as a HID keyboard and can display +predefined sets of keys, and one where the operating system has full +control over what is displayed. This commit adds a driver for the +display functionality of the first configuration. + +Note that currently only T2 Macs are supported. + +This driver is based on previous work done by Ronald Tschalar +. + +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + Documentation/ABI/testing/sysfs-driver-hid-appletb-kbd | 13 + + drivers/hid/Kconfig | 15 + + drivers/hid/Makefile | 1 + + drivers/hid/hid-appletb-kbd.c | 507 ++++++++++ + drivers/hid/hid-quirks.c | 4 +- + 5 files changed, 539 insertions(+), 1 deletion(-) + +diff --git a/Documentation/ABI/testing/sysfs-driver-hid-appletb-kbd b/Documentation/ABI/testing/sysfs-driver-hid-appletb-kbd +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-driver-hid-appletb-kbd +@@ -0,0 +1,13 @@ ++What: /sys/bus/hid/drivers/hid-appletb-kbd//mode ++Date: September, 2023 ++KernelVersion: 6.5 ++Contact: linux-input@vger.kernel.org ++Description: ++ The set of keys displayed on the Touch Bar. ++ Valid values are: ++ == ================= ++ 0 Escape key only ++ 1 Function keys ++ 2 Media/brightness keys ++ 3 None ++ == ================= +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -158,6 +158,21 @@ config HID_APPLETB_BL + To compile this driver as a module, choose M here: the + module will be called hid-appletb-bl. + ++config HID_APPLETB_KBD ++ tristate "Apple Touch Bar Keyboard Mode" ++ depends on USB_HID ++ depends on BACKLIGHT_CLASS_DEVICE ++ depends on INPUT ++ select INPUT_SPARSEKMAP ++ select HID_APPLETB_BL ++ help ++ Say Y here if you want support for the keyboard mode (escape, ++ function, media and brightness keys) of Touch Bars on x86 MacBook ++ Pros. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called hid-appletb-kbd. ++ + config HID_ASUS + tristate "Asus" + depends on USB_HID +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -30,6 +30,7 @@ obj-$(CONFIG_HID_ACRUX) += hid-axff.o + obj-$(CONFIG_HID_APPLE) += hid-apple.o + obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o + obj-$(CONFIG_HID_APPLETB_BL) += hid-appletb-bl.o ++obj-$(CONFIG_HID_APPLETB_KBD) += hid-appletb-kbd.o + obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o + obj-$(CONFIG_HID_ASUS) += hid-asus.o + obj-$(CONFIG_HID_AUREAL) += hid-aureal.o +diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/hid-appletb-kbd.c +@@ -0,0 +1,507 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Apple Touch Bar Keyboard Mode Driver ++ * ++ * Copyright (c) 2017-2018 Ronald Tschalär ++ * Copyright (c) 2022-2023 Kerem Karabay ++ * Copyright (c) 2024-2025 Aditya Garg ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define APPLETB_KBD_MODE_ESC 0 ++#define APPLETB_KBD_MODE_FN 1 ++#define APPLETB_KBD_MODE_SPCL 2 ++#define APPLETB_KBD_MODE_OFF 3 ++#define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF ++ ++#define APPLETB_DEVID_KEYBOARD 1 ++#define APPLETB_DEVID_TRACKPAD 2 ++ ++#define HID_USAGE_MODE 0x00ff0004 ++ ++static int appletb_tb_def_mode = APPLETB_KBD_MODE_SPCL; ++module_param_named(mode, appletb_tb_def_mode, int, 0444); ++MODULE_PARM_DESC(mode, "Default touchbar mode:\n" ++ " 0 - escape key only\n" ++ " 1 - function-keys\n" ++ " [2] - special keys"); ++ ++static bool appletb_tb_fn_toggle = true; ++module_param_named(fntoggle, appletb_tb_fn_toggle, bool, 0644); ++MODULE_PARM_DESC(fntoggle, "Switch between Fn and media controls on pressing Fn key"); ++ ++static bool appletb_tb_autodim = true; ++module_param_named(autodim, appletb_tb_autodim, bool, 0644); ++MODULE_PARM_DESC(autodim, "Automatically dim and turn off the Touch Bar after some time"); ++ ++static int appletb_tb_dim_timeout = 60; ++module_param_named(dim_timeout, appletb_tb_dim_timeout, int, 0644); ++MODULE_PARM_DESC(dim_timeout, "Dim timeout in sec"); ++ ++static int appletb_tb_idle_timeout = 15; ++module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644); ++MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec"); ++ ++struct appletb_kbd { ++ struct hid_field *mode_field; ++ struct input_handler inp_handler; ++ struct input_handle kbd_handle; ++ struct input_handle tpd_handle; ++ struct backlight_device *backlight_dev; ++ struct timer_list inactivity_timer; ++ bool has_dimmed; ++ bool has_turned_off; ++ u8 saved_mode; ++ u8 current_mode; ++}; ++ ++static const struct key_entry appletb_kbd_keymap[] = { ++ { KE_KEY, KEY_ESC, { KEY_ESC } }, ++ { KE_KEY, KEY_F1, { KEY_BRIGHTNESSDOWN } }, ++ { KE_KEY, KEY_F2, { KEY_BRIGHTNESSUP } }, ++ { KE_KEY, KEY_F3, { KEY_RESERVED } }, ++ { KE_KEY, KEY_F4, { KEY_RESERVED } }, ++ { KE_KEY, KEY_F5, { KEY_KBDILLUMDOWN } }, ++ { KE_KEY, KEY_F6, { KEY_KBDILLUMUP } }, ++ { KE_KEY, KEY_F7, { KEY_PREVIOUSSONG } }, ++ { KE_KEY, KEY_F8, { KEY_PLAYPAUSE } }, ++ { KE_KEY, KEY_F9, { KEY_NEXTSONG } }, ++ { KE_KEY, KEY_F10, { KEY_MUTE } }, ++ { KE_KEY, KEY_F11, { KEY_VOLUMEDOWN } }, ++ { KE_KEY, KEY_F12, { KEY_VOLUMEUP } }, ++ { KE_END, 0 } ++}; ++ ++static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode) ++{ ++ struct hid_report *report = kbd->mode_field->report; ++ struct hid_device *hdev = report->device; ++ int ret; ++ ++ ret = hid_hw_power(hdev, PM_HINT_FULLON); ++ if (ret) { ++ hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret)); ++ return ret; ++ } ++ ++ ret = hid_set_field(kbd->mode_field, 0, mode); ++ if (ret) { ++ hid_err(hdev, "Failed to set mode field to %u (%pe)\n", mode, ERR_PTR(ret)); ++ goto power_normal; ++ } ++ ++ hid_hw_request(hdev, report, HID_REQ_SET_REPORT); ++ ++ kbd->current_mode = mode; ++ ++power_normal: ++ hid_hw_power(hdev, PM_HINT_NORMAL); ++ ++ return ret; ++} ++ ++static ssize_t mode_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct appletb_kbd *kbd = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%d\n", kbd->current_mode); ++} ++ ++static ssize_t mode_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct appletb_kbd *kbd = dev_get_drvdata(dev); ++ u8 mode; ++ int ret; ++ ++ ret = kstrtou8(buf, 0, &mode); ++ if (ret) ++ return ret; ++ ++ if (mode > APPLETB_KBD_MODE_MAX) ++ return -EINVAL; ++ ++ ret = appletb_kbd_set_mode(kbd, mode); ++ ++ return ret < 0 ? ret : size; ++} ++static DEVICE_ATTR_RW(mode); ++ ++static struct attribute *appletb_kbd_attrs[] = { ++ &dev_attr_mode.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(appletb_kbd); ++ ++static int appletb_tb_key_to_slot(unsigned int code) ++{ ++ switch (code) { ++ case KEY_ESC: ++ return 0; ++ case KEY_F1 ... KEY_F10: ++ return code - KEY_F1 + 1; ++ case KEY_F11 ... KEY_F12: ++ return code - KEY_F11 + 11; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ ++static void appletb_inactivity_timer(struct timer_list *t) ++{ ++ struct appletb_kbd *kbd = from_timer(kbd, t, inactivity_timer); ++ ++ if (kbd->backlight_dev && appletb_tb_autodim) { ++ if (!kbd->has_dimmed) { ++ backlight_device_set_brightness(kbd->backlight_dev, 1); ++ kbd->has_dimmed = true; ++ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000)); ++ } else if (!kbd->has_turned_off) { ++ backlight_device_set_brightness(kbd->backlight_dev, 0); ++ kbd->has_turned_off = true; ++ } ++ } ++} ++ ++static void reset_inactivity_timer(struct appletb_kbd *kbd) ++{ ++ if (kbd->backlight_dev && appletb_tb_autodim) { ++ if (kbd->has_dimmed || kbd->has_turned_off) { ++ backlight_device_set_brightness(kbd->backlight_dev, 2); ++ kbd->has_dimmed = false; ++ kbd->has_turned_off = false; ++ } ++ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000)); ++ } ++} ++ ++static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *field, ++ struct hid_usage *usage, __s32 value) ++{ ++ struct appletb_kbd *kbd = hid_get_drvdata(hdev); ++ struct key_entry *translation; ++ struct input_dev *input; ++ int slot; ++ ++ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD || usage->type != EV_KEY) ++ return 0; ++ ++ input = field->hidinput->input; ++ ++ /* ++ * Skip non-touch-bar keys. ++ * ++ * Either the touch bar itself or usbhid generate a slew of key-down ++ * events for all the meta keys. None of which we're at all interested ++ * in. ++ */ ++ slot = appletb_tb_key_to_slot(usage->code); ++ if (slot < 0) ++ return 0; ++ ++ reset_inactivity_timer(kbd); ++ ++ translation = sparse_keymap_entry_from_scancode(input, usage->code); ++ ++ if (translation && kbd->current_mode == APPLETB_KBD_MODE_SPCL) { ++ input_event(input, usage->type, translation->keycode, value); ++ ++ return 1; ++ } ++ ++ return kbd->current_mode == APPLETB_KBD_MODE_OFF; ++} ++ ++static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type, ++ unsigned int code, int value) ++{ ++ struct appletb_kbd *kbd = handle->private; ++ ++ reset_inactivity_timer(kbd); ++ ++ if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle && ++ (kbd->current_mode == APPLETB_KBD_MODE_SPCL || ++ kbd->current_mode == APPLETB_KBD_MODE_FN)) { ++ if (value == 1) { ++ kbd->saved_mode = kbd->current_mode; ++ appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL ++ ? APPLETB_KBD_MODE_FN : APPLETB_KBD_MODE_SPCL); ++ } else if (value == 0) { ++ if (kbd->saved_mode != kbd->current_mode) ++ appletb_kbd_set_mode(kbd, kbd->saved_mode); ++ } ++ } ++} ++ ++static int appletb_kbd_inp_connect(struct input_handler *handler, ++ struct input_dev *dev, ++ const struct input_device_id *id) ++{ ++ struct appletb_kbd *kbd = handler->private; ++ struct input_handle *handle; ++ int rc; ++ ++ if (id->driver_info == APPLETB_DEVID_KEYBOARD) { ++ handle = &kbd->kbd_handle; ++ handle->name = "tbkbd"; ++ } else if (id->driver_info == APPLETB_DEVID_TRACKPAD) { ++ handle = &kbd->tpd_handle; ++ handle->name = "tbtpd"; ++ } else { ++ return -ENOENT; ++ } ++ ++ if (handle->dev) ++ return -EEXIST; ++ ++ handle->open = 0; ++ handle->dev = input_get_device(dev); ++ handle->handler = handler; ++ handle->private = kbd; ++ ++ rc = input_register_handle(handle); ++ if (rc) ++ goto err_free_dev; ++ ++ rc = input_open_device(handle); ++ if (rc) ++ goto err_unregister_handle; ++ ++ return 0; ++ ++ err_unregister_handle: ++ input_unregister_handle(handle); ++ err_free_dev: ++ input_put_device(handle->dev); ++ handle->dev = NULL; ++ return rc; ++} ++ ++static void appletb_kbd_inp_disconnect(struct input_handle *handle) ++{ ++ input_close_device(handle); ++ input_unregister_handle(handle); ++ ++ input_put_device(handle->dev); ++ handle->dev = NULL; ++} ++ ++static int appletb_kbd_input_configured(struct hid_device *hdev, struct hid_input *hidinput) ++{ ++ int idx; ++ struct input_dev *input = hidinput->input; ++ ++ /* ++ * Clear various input capabilities that are blindly set by the hid ++ * driver (usbkbd.c) ++ */ ++ memset(input->evbit, 0, sizeof(input->evbit)); ++ memset(input->keybit, 0, sizeof(input->keybit)); ++ memset(input->ledbit, 0, sizeof(input->ledbit)); ++ ++ __set_bit(EV_REP, input->evbit); ++ ++ sparse_keymap_setup(input, appletb_kbd_keymap, NULL); ++ ++ for (idx = 0; appletb_kbd_keymap[idx].type != KE_END; idx++) ++ input_set_capability(input, EV_KEY, appletb_kbd_keymap[idx].code); ++ ++ return 0; ++} ++ ++static const struct input_device_id appletb_kbd_input_devices[] = { ++ { ++ .flags = INPUT_DEVICE_ID_MATCH_BUS | ++ INPUT_DEVICE_ID_MATCH_VENDOR | ++ INPUT_DEVICE_ID_MATCH_KEYBIT, ++ .bustype = BUS_USB, ++ .vendor = USB_VENDOR_ID_APPLE, ++ .keybit = { [BIT_WORD(KEY_FN)] = BIT_MASK(KEY_FN) }, ++ .driver_info = APPLETB_DEVID_KEYBOARD, ++ }, ++ { ++ .flags = INPUT_DEVICE_ID_MATCH_BUS | ++ INPUT_DEVICE_ID_MATCH_VENDOR | ++ INPUT_DEVICE_ID_MATCH_KEYBIT, ++ .bustype = BUS_USB, ++ .vendor = USB_VENDOR_ID_APPLE, ++ .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, ++ .driver_info = APPLETB_DEVID_TRACKPAD, ++ }, ++ { } ++}; ++ ++static bool appletb_kbd_match_internal_device(struct input_handler *handler, ++ struct input_dev *inp_dev) ++{ ++ struct device *dev = &inp_dev->dev; ++ ++ /* in kernel: dev && !is_usb_device(dev) */ ++ while (dev && !(dev->type && dev->type->name && ++ !strcmp(dev->type->name, "usb_device"))) ++ dev = dev->parent; ++ ++ /* ++ * Apple labels all their internal keyboards and trackpads as such, ++ * instead of maintaining an ever expanding list of product-id's we ++ * just look at the device's product name. ++ */ ++ if (dev) ++ return !!strstr(to_usb_device(dev)->product, "Internal Keyboard"); ++ ++ return false; ++} ++ ++static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) ++{ ++ struct appletb_kbd *kbd; ++ struct device *dev = &hdev->dev; ++ struct hid_field *mode_field; ++ int ret; ++ ++ ret = hid_parse(hdev); ++ if (ret) ++ return dev_err_probe(dev, ret, "HID parse failed\n"); ++ ++ mode_field = hid_find_field(hdev, HID_OUTPUT_REPORT, ++ HID_GD_KEYBOARD, HID_USAGE_MODE); ++ if (!mode_field) ++ return -ENODEV; ++ ++ kbd = devm_kzalloc(dev, sizeof(*kbd), GFP_KERNEL); ++ if (!kbd) ++ return -ENOMEM; ++ ++ kbd->mode_field = mode_field; ++ ++ ret = hid_hw_start(hdev, HID_CONNECT_HIDINPUT); ++ if (ret) ++ return dev_err_probe(dev, ret, "HID hw start failed\n"); ++ ++ ret = hid_hw_open(hdev); ++ if (ret) { ++ dev_err_probe(dev, ret, "HID hw open failed\n"); ++ goto stop_hw; ++ } ++ ++ kbd->backlight_dev = backlight_device_get_by_name("appletb_backlight"); ++ if (!kbd->backlight_dev) { ++ dev_err_probe(dev, -ENODEV, "Failed to get backlight device\n"); ++ } else { ++ backlight_device_set_brightness(kbd->backlight_dev, 2); ++ timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0); ++ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000)); ++ } ++ ++ kbd->inp_handler.event = appletb_kbd_inp_event; ++ kbd->inp_handler.connect = appletb_kbd_inp_connect; ++ kbd->inp_handler.disconnect = appletb_kbd_inp_disconnect; ++ kbd->inp_handler.name = "appletb"; ++ kbd->inp_handler.id_table = appletb_kbd_input_devices; ++ kbd->inp_handler.match = appletb_kbd_match_internal_device; ++ kbd->inp_handler.private = kbd; ++ ++ ret = input_register_handler(&kbd->inp_handler); ++ if (ret) { ++ dev_err_probe(dev, ret, "Unable to register keyboard handler\n"); ++ goto close_hw; ++ } ++ ++ ret = appletb_kbd_set_mode(kbd, appletb_tb_def_mode); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to set touchbar mode\n"); ++ goto close_hw; ++ } ++ ++ hid_set_drvdata(hdev, kbd); ++ ++ return 0; ++ ++close_hw: ++ hid_hw_close(hdev); ++stop_hw: ++ hid_hw_stop(hdev); ++ return ret; ++} ++ ++static void appletb_kbd_remove(struct hid_device *hdev) ++{ ++ struct appletb_kbd *kbd = hid_get_drvdata(hdev); ++ ++ appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF); ++ ++ input_unregister_handler(&kbd->inp_handler); ++ del_timer_sync(&kbd->inactivity_timer); ++ ++ hid_hw_close(hdev); ++ hid_hw_stop(hdev); ++} ++ ++#ifdef CONFIG_PM ++static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg) ++{ ++ struct appletb_kbd *kbd = hid_get_drvdata(hdev); ++ ++ kbd->saved_mode = kbd->current_mode; ++ appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF); ++ ++ return 0; ++} ++ ++static int appletb_kbd_reset_resume(struct hid_device *hdev) ++{ ++ struct appletb_kbd *kbd = hid_get_drvdata(hdev); ++ ++ appletb_kbd_set_mode(kbd, kbd->saved_mode); ++ ++ return 0; ++} ++#endif ++ ++static const struct hid_device_id appletb_kbd_hid_ids[] = { ++ /* MacBook Pro's 2018, 2019, with T2 chip: iBridge Display */ ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, appletb_kbd_hid_ids); ++ ++static struct hid_driver appletb_kbd_hid_driver = { ++ .name = "hid-appletb-kbd", ++ .id_table = appletb_kbd_hid_ids, ++ .probe = appletb_kbd_probe, ++ .remove = appletb_kbd_remove, ++ .event = appletb_kbd_hid_event, ++ .input_configured = appletb_kbd_input_configured, ++#ifdef CONFIG_PM ++ .suspend = appletb_kbd_suspend, ++ .reset_resume = appletb_kbd_reset_resume, ++#endif ++ .driver.dev_groups = appletb_kbd_groups, ++}; ++module_hid_driver(appletb_kbd_hid_driver); ++ ++/* The backlight driver should be loaded before the keyboard driver is initialised */ ++MODULE_SOFTDEP("pre: hid_appletb_bl"); ++ ++MODULE_AUTHOR("Ronald Tschalär"); ++MODULE_AUTHOR("Kerem Karabay "); ++MODULE_AUTHOR("Aditya Garg "); ++MODULE_DESCRIPTION("MacBook Pro Touch Bar Keyboard Mode driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -332,7 +332,6 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, + #endif + #if IS_ENABLED(CONFIG_HID_APPLEIR) + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, +@@ -344,6 +343,9 @@ static const struct hid_device_id hid_have_special_driver[] = { + #if IS_ENABLED(CONFIG_HID_APPLETB_BL) + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) }, + #endif ++#if IS_ENABLED(CONFIG_HID_APPLETB_KBD) ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, ++#endif + #if IS_ENABLED(CONFIG_HID_ASUS) + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) }, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1007-HID-multitouch-Get-the-contact-ID-from-HID_DG_TRANSD.patch b/patch/kernel/archive/uefi-x86-6.12/1007-HID-multitouch-Get-the-contact-ID-from-HID_DG_TRANSD.patch new file mode 100644 index 000000000..fe8fd398b --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1007-HID-multitouch-Get-the-contact-ID-from-HID_DG_TRANSD.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Tue, 27 May 2025 22:13:13 +0530 +Subject: HID: multitouch: Get the contact ID from HID_DG_TRANSDUCER_INDEX + fields in case of Apple Touch Bar + +In Apple Touch Bar, the contact ID is contained in fields with the +HID_DG_TRANSDUCER_INDEX usage rather than HID_DG_CONTACTID, thus differing +from the HID spec. Add a quirk for the same. + +Acked-by: Benjamin Tissoires +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-multitouch.c | 16 +++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -72,6 +72,7 @@ MODULE_LICENSE("GPL"); + #define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) + #define MT_QUIRK_DISABLE_WAKEUP BIT(21) + #define MT_QUIRK_ORIENTATION_INVERT BIT(22) ++#define MT_QUIRK_APPLE_TOUCHBAR BIT(23) + + #define MT_INPUTMODE_TOUCHSCREEN 0x02 + #define MT_INPUTMODE_TOUCHPAD 0x03 +@@ -620,6 +621,7 @@ static struct mt_application *mt_find_application(struct mt_device *td, + static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, + struct hid_report *report) + { ++ struct mt_class *cls = &td->mtclass; + struct mt_report_data *rdata; + struct hid_field *field; + int r, n; +@@ -644,7 +646,11 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, + + if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) { + for (n = 0; n < field->report_count; n++) { +- if (field->usage[n].hid == HID_DG_CONTACTID) { ++ unsigned int hid = field->usage[n].hid; ++ ++ if (hid == HID_DG_CONTACTID || ++ (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && ++ hid == HID_DG_TRANSDUCER_INDEX)) { + rdata->is_mt_collection = true; + break; + } +@@ -822,6 +828,14 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + EV_KEY, BTN_TOUCH); + MT_STORE_FIELD(tip_state); + return 1; ++ case HID_DG_TRANSDUCER_INDEX: ++ /* ++ * Contact ID in case of Apple Touch Bars is contained ++ * in fields with HID_DG_TRANSDUCER_INDEX usage. ++ */ ++ if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)) ++ return 0; ++ fallthrough; + case HID_DG_CONTACTID: + MT_STORE_FIELD(contactid); + app->touches_by_report++; +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1008-HID-multitouch-support-getting-the-tip-state-from-HI.patch b/patch/kernel/archive/uefi-x86-6.12/1008-HID-multitouch-support-getting-the-tip-state-from-HI.patch new file mode 100644 index 000000000..f0f1a3532 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1008-HID-multitouch-support-getting-the-tip-state-from-HI.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Tue, 27 May 2025 22:13:14 +0530 +Subject: HID: multitouch: support getting the tip state from HID_DG_TOUCH + fields in Apple Touch Bar + +In Apple Touch Bar, the tip state is contained in fields with the +HID_DG_TOUCH usage. This feature is gated by a quirk in order to +prevent breaking other devices, see commit c2ef8f21ea8f +("HID: multitouch: add support for trackpads"). + +Acked-by: Benjamin Tissoires +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-multitouch.c | 15 +++++++--- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -822,6 +822,17 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + + MT_STORE_FIELD(confidence_state); + return 1; ++ case HID_DG_TOUCH: ++ /* ++ * Legacy devices use TIPSWITCH and not TOUCH. ++ * One special case here is of the Apple Touch Bars. ++ * In these devices, the tip state is contained in ++ * fields with the HID_DG_TOUCH usage. ++ * Let's just ignore this field for other devices. ++ */ ++ if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)) ++ return -1; ++ fallthrough; + case HID_DG_TIPSWITCH: + if (field->application != HID_GD_SYSTEM_MULTIAXIS) + input_set_capability(hi->input, +@@ -892,10 +903,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + case HID_DG_CONTACTMAX: + /* contact max are global to the report */ + return -1; +- case HID_DG_TOUCH: +- /* Legacy devices use TIPSWITCH and not TOUCH. +- * Let's just ignore this field. */ +- return -1; + } + /* let hid-input decide for the others */ + return 0; +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1009-HID-multitouch-take-cls-maxcontacts-into-account-for.patch b/patch/kernel/archive/uefi-x86-6.12/1009-HID-multitouch-take-cls-maxcontacts-into-account-for.patch new file mode 100644 index 000000000..8abff93a2 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1009-HID-multitouch-take-cls-maxcontacts-into-account-for.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Tue, 27 May 2025 22:13:15 +0530 +Subject: HID: multitouch: take cls->maxcontacts into account for Apple Touch + Bar even without a HID_DG_CONTACTMAX field + +In Apple Touch Bar, the HID_DG_CONTACTMAX is not present, but the maximum +contact count is still greater than the default. Add quirks for the same. + +Acked-by: Benjamin Tissoires +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-multitouch.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1327,6 +1327,13 @@ static int mt_touch_input_configured(struct hid_device *hdev, + struct input_dev *input = hi->input; + int ret; + ++ /* ++ * HID_DG_CONTACTMAX field is not present on Apple Touch Bars, ++ * but the maximum contact count is greater than the default. ++ */ ++ if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && cls->maxcontacts) ++ td->maxcontacts = cls->maxcontacts; ++ + if (!td->maxcontacts) + td->maxcontacts = MT_DEFAULT_MAXCONTACT; + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1010-HID-multitouch-specify-that-Apple-Touch-Bar-is-direc.patch b/patch/kernel/archive/uefi-x86-6.12/1010-HID-multitouch-specify-that-Apple-Touch-Bar-is-direc.patch new file mode 100644 index 000000000..5c31ae426 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1010-HID-multitouch-specify-that-Apple-Touch-Bar-is-direc.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Tue, 27 May 2025 22:13:16 +0530 +Subject: HID: multitouch: specify that Apple Touch Bar is direct + +Currently the driver determines the device type based on the +application, but this value is not reliable on Apple Touch Bar, where +the application is HID_DG_TOUCHPAD even though this device is direct, +so add a quirk for the same. + +Acked-by: Benjamin Tissoires +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-multitouch.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1341,6 +1341,13 @@ static int mt_touch_input_configured(struct hid_device *hdev, + if (td->serial_maybe) + mt_post_parse_default_settings(td, app); + ++ /* ++ * The application for Apple Touch Bars is HID_DG_TOUCHPAD, ++ * but these devices are direct. ++ */ ++ if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR) ++ app->mt_flags |= INPUT_MT_DIRECT; ++ + if (cls->is_indirect) + app->mt_flags |= INPUT_MT_POINTER; + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1011-HID-multitouch-add-device-ID-for-Apple-Touch-Bar.patch b/patch/kernel/archive/uefi-x86-6.12/1011-HID-multitouch-add-device-ID-for-Apple-Touch-Bar.patch new file mode 100644 index 000000000..336f6b597 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1011-HID-multitouch-add-device-ID-for-Apple-Touch-Bar.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Tue, 27 May 2025 22:13:17 +0530 +Subject: HID: multitouch: add device ID for Apple Touch Bar + +This patch adds the device ID of Apple Touch Bar found on x86 MacBook Pros +to the hid-multitouch driver. + +Note that this is device ID is for T2 Macs. Testing on T1 Macs would be +appreciated. + +Signed-off-by: Kerem Karabay +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +--- + drivers/hid/Kconfig | 1 + + drivers/hid/hid-multitouch.c | 17 ++++++++++ + 2 files changed, 18 insertions(+) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -754,6 +754,7 @@ config HID_MULTITOUCH + Say Y here if you have one of the following devices: + - 3M PCT touch screens + - ActionStar dual touch panels ++ - Apple Touch Bar on x86 MacBook Pros + - Atmel panels + - Cando dual touch panels + - Chunghwa panels +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -216,6 +216,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); + #define MT_CLS_GOOGLE 0x0111 + #define MT_CLS_RAZER_BLADE_STEALTH 0x0112 + #define MT_CLS_SMART_TECH 0x0113 ++#define MT_CLS_APPLE_TOUCHBAR 0x0114 + #define MT_CLS_SIS 0x0457 + + #define MT_DEFAULT_MAXCONTACT 10 +@@ -401,6 +402,12 @@ static const struct mt_class mt_classes[] = { + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_SEPARATE_APP_REPORT, + }, ++ { .name = MT_CLS_APPLE_TOUCHBAR, ++ .quirks = MT_QUIRK_HOVERING | ++ MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE | ++ MT_QUIRK_APPLE_TOUCHBAR, ++ .maxcontacts = 11, ++ }, + { .name = MT_CLS_SIS, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | + MT_QUIRK_ALWAYS_VALID | +@@ -1862,6 +1869,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + if (ret != 0) + return ret; + ++ if (mtclass->name == MT_CLS_APPLE_TOUCHBAR && ++ !hid_find_field(hdev, HID_INPUT_REPORT, ++ HID_DG_TOUCHPAD, HID_DG_TRANSDUCER_INDEX)) ++ return -ENODEV; ++ + if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID) + mt_fix_const_fields(hdev, HID_DG_CONTACTID); + +@@ -2349,6 +2361,11 @@ static const struct hid_device_id mt_devices[] = { + MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, + USB_DEVICE_ID_XIROKU_CSR2) }, + ++ /* Apple Touch Bar */ ++ { .driver_data = MT_CLS_APPLE_TOUCHBAR, ++ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, ++ + /* Google MT devices */ + { .driver_data = MT_CLS_GOOGLE, + HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1013-lib-vsprintf-Add-support-for-generic-FourCCs-by-exte.patch b/patch/kernel/archive/uefi-x86-6.12/1013-lib-vsprintf-Add-support-for-generic-FourCCs-by-exte.patch new file mode 100644 index 000000000..94d4f73f8 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1013-lib-vsprintf-Add-support-for-generic-FourCCs-by-exte.patch @@ -0,0 +1,167 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Tue, 8 Apr 2025 12:17:57 +0530 +Subject: lib/vsprintf: Add support for generic FourCCs by extending %p4cc + +%p4cc is designed for DRM/V4L2 FourCCs with their specific quirks, but +it's useful to be able to print generic 4-character codes formatted as +an integer. Extend it to add format specifiers for printing generic +32-bit FourCCs with various endian semantics: + +%p4ch Host byte order +%p4cn Network byte order +%p4cl Little-endian +%p4cb Big-endian + +The endianness determines how bytes are interpreted as a u32, and the +FourCC is then always printed MSByte-first (this is the opposite of +V4L/DRM FourCCs). This covers most practical cases, e.g. %p4cn would +allow printing LSByte-first FourCCs stored in host endian order +(other than the hex form being in character order, not the integer +value). + +Acked-by: Rasmus Villemoes +Reviewed-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Tested-by: Petr Mladek +Signed-off-by: Hector Martin +Signed-off-by: Aditya Garg +Reviewed-by: Kees Cook +--- + Documentation/core-api/printk-formats.rst | 32 ++++++++ + lib/vsprintf.c | 40 ++++++++-- + scripts/checkpatch.pl | 2 +- + 3 files changed, 67 insertions(+), 7 deletions(-) + +diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst +index 111111111111..222222222222 100644 +--- a/Documentation/core-api/printk-formats.rst ++++ b/Documentation/core-api/printk-formats.rst +@@ -630,6 +630,38 @@ Examples:: + %p4cc Y10 little-endian (0x20303159) + %p4cc NV12 big-endian (0xb231564e) + ++Generic FourCC code ++------------------- ++ ++:: ++ %p4c[h[R]lb] gP00 (0x67503030) ++ ++Print a generic FourCC code, as both ASCII characters and its numerical ++value as hexadecimal. ++ ++The generic FourCC code is always printed in the big-endian format, ++the most significant byte first. This is the opposite of V4L/DRM FourCCs. ++ ++The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what ++endianness is used to load the stored bytes. The data might be interpreted ++using the host, reversed host byte order, little-endian, or big-endian. ++ ++Passed by reference. ++ ++Examples for a little-endian machine, given &(u32)0x67503030:: ++ ++ %p4ch gP00 (0x67503030) ++ %p4chR 00Pg (0x30305067) ++ %p4cl gP00 (0x67503030) ++ %p4cb 00Pg (0x30305067) ++ ++Examples for a big-endian machine, given &(u32)0x67503030:: ++ ++ %p4ch gP00 (0x67503030) ++ %p4chR 00Pg (0x30305067) ++ %p4cl 00Pg (0x30305067) ++ %p4cb gP00 (0x67503030) ++ + Rust + ---- + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 111111111111..222222222222 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1760,27 +1760,49 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc, + char output[sizeof("0123 little-endian (0x01234567)")]; + char *p = output; + unsigned int i; ++ bool pixel_fmt = false; + u32 orig, val; + +- if (fmt[1] != 'c' || fmt[2] != 'c') ++ if (fmt[1] != 'c') + return error_string(buf, end, "(%p4?)", spec); + + if (check_pointer(&buf, end, fourcc, spec)) + return buf; + + orig = get_unaligned(fourcc); +- val = orig & ~BIT(31); ++ switch (fmt[2]) { ++ case 'h': ++ if (fmt[3] == 'R') ++ orig = swab32(orig); ++ break; ++ case 'l': ++ orig = (__force u32)cpu_to_le32(orig); ++ break; ++ case 'b': ++ orig = (__force u32)cpu_to_be32(orig); ++ break; ++ case 'c': ++ /* Pixel formats are printed LSB-first */ ++ pixel_fmt = true; ++ break; ++ default: ++ return error_string(buf, end, "(%p4?)", spec); ++ } ++ ++ val = pixel_fmt ? swab32(orig & ~BIT(31)) : orig; + + for (i = 0; i < sizeof(u32); i++) { +- unsigned char c = val >> (i * 8); ++ unsigned char c = val >> ((3 - i) * 8); + + /* Print non-control ASCII characters as-is, dot otherwise */ + *p++ = isascii(c) && isprint(c) ? c : '.'; + } + +- *p++ = ' '; +- strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian"); +- p += strlen(p); ++ if (pixel_fmt) { ++ *p++ = ' '; ++ strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian"); ++ p += strlen(p); ++ } + + *p++ = ' '; + *p++ = '('; +@@ -2334,6 +2356,12 @@ char *rust_fmt_argument(char *buf, char *end, const void *ptr); + * read the documentation (path below) first. + * - 'NF' For a netdev_features_t + * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value. ++ * - '4c[h[R]lb]' For generic FourCC code with raw numerical value. Both are ++ * displayed in the big-endian format. This is the opposite of V4L2 or ++ * DRM FourCCs. ++ * The additional specifiers define what endianness is used to load ++ * the stored bytes. The data might be interpreted using the host, ++ * reversed host byte order, little-endian, or big-endian. + * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with + * a certain separator (' ' by default): + * C colon +diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl +index 111111111111..222222222222 100755 +--- a/scripts/checkpatch.pl ++++ b/scripts/checkpatch.pl +@@ -6912,7 +6912,7 @@ sub process { + ($extension eq "f" && + defined $qualifier && $qualifier !~ /^w/) || + ($extension eq "4" && +- defined $qualifier && $qualifier !~ /^cc/)) { ++ defined $qualifier && $qualifier !~ /^c[hnlbc]/)) { + $bad_specifier = $specifier; + last; + } +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/1015-drm-tiny-add-driver-for-Apple-Touch-Bars-in-x86-Macs.patch b/patch/kernel/archive/uefi-x86-6.12/1015-drm-tiny-add-driver-for-Apple-Touch-Bars-in-x86-Macs.patch new file mode 100644 index 000000000..a2e830045 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/1015-drm-tiny-add-driver-for-Apple-Touch-Bars-in-x86-Macs.patch @@ -0,0 +1,954 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kerem Karabay +Date: Wed, 26 Feb 2025 16:04:36 +0000 +Subject: drm/tiny: add driver for Apple Touch Bars in x86 Macs + +The Touch Bars found on x86 Macs support two USB configurations: one +where the device presents itself as a HID keyboard and can display +predefined sets of keys, and one where the operating system has full +control over what is displayed. + +This commit adds support for the display functionality of the second +configuration. Functionality for the first configuration has been +merged in the HID tree. + +Note that this driver has only been tested on T2 Macs, and only includes +the USB device ID for these devices. Testing on T1 Macs would be +appreciated. + +Credit goes to Ben (Bingxing) Wang on GitHub for reverse engineering +most of the protocol. + +Also, as requested by Andy, I would like to clarify the use of __packed +structs in this driver: + +- All the packed structs are aligned except for appletbdrm_msg_information. +- We have to pack appletbdrm_msg_information since it is requirement of + the protocol. +- We compared binaries compiled by keeping the rest structs __packed and + not __packed using bloat-o-meter, and __packed was not affecting code + generation. +- To maintain consistency, rest structs have been kept __packed. + +I would also like to point out that since the driver was reverse-engineered +the actual data types of the protocol might be different, including, but +not limited to, endianness. + +Link: https://github.com/imbushuo/DFRDisplayKm +Signed-off-by: Kerem Karabay +Co-developed-by: Atharva Tiwari +Signed-off-by: Atharva Tiwari +Co-developed-by: Aditya Garg +Signed-off-by: Aditya Garg +Signed-off-by: Aun-Ali Zaidi +Reviewed-by: Thomas Zimmermann +Signed-off-by: Thomas Zimmermann +Link: https://patchwork.freedesktop.org/patch/msgid/FCAC702C-F84A-47F9-8C78-BBBB34D08500@live.com +--- + MAINTAINERS | 8 + + drivers/gpu/drm/tiny/Kconfig | 12 + + drivers/gpu/drm/tiny/Makefile | 1 + + drivers/gpu/drm/tiny/appletbdrm.c | 840 ++++++++++ + 4 files changed, 861 insertions(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 111111111111..222222222222 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -6998,6 +6998,14 @@ S: Supported + T: git https://gitlab.freedesktop.org/drm/misc/kernel.git + F: drivers/gpu/drm/sun4i/sun8i* + ++DRM DRIVER FOR APPLE TOUCH BARS ++M: Aun-Ali Zaidi ++M: Aditya Garg ++L: dri-devel@lists.freedesktop.org ++S: Maintained ++T: git https://gitlab.freedesktop.org/drm/misc/kernel.git ++F: drivers/gpu/drm/tiny/appletbdrm.c ++ + DRM DRIVER FOR ARM PL111 CLCD + S: Orphan + T: git https://gitlab.freedesktop.org/drm/misc/kernel.git +diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/tiny/Kconfig ++++ b/drivers/gpu/drm/tiny/Kconfig +@@ -1,5 +1,17 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++config DRM_APPLETBDRM ++ tristate "DRM support for Apple Touch Bars" ++ depends on DRM && USB && MMU ++ select DRM_GEM_SHMEM_HELPER ++ select DRM_KMS_HELPER ++ help ++ Say Y here if you want support for the display of Touch Bars on x86 ++ MacBook Pros. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called appletbdrm. ++ + config DRM_ARCPGU + tristate "ARC PGU" + depends on DRM && OF +diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/tiny/Makefile ++++ b/drivers/gpu/drm/tiny/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++obj-$(CONFIG_DRM_APPLETBDRM) += appletbdrm.o + obj-$(CONFIG_DRM_ARCPGU) += arcpgu.o + obj-$(CONFIG_DRM_BOCHS) += bochs.o + obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o +diff --git a/drivers/gpu/drm/tiny/appletbdrm.c b/drivers/gpu/drm/tiny/appletbdrm.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/gpu/drm/tiny/appletbdrm.c +@@ -0,0 +1,840 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Apple Touch Bar DRM Driver ++ * ++ * Copyright (c) 2023 Kerem Karabay ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define APPLETBDRM_PIXEL_FORMAT cpu_to_le32(0x52474241) /* RGBA, the actual format is BGR888 */ ++#define APPLETBDRM_BITS_PER_PIXEL 24 ++ ++#define APPLETBDRM_MSG_CLEAR_DISPLAY cpu_to_le32(0x434c5244) /* CLRD */ ++#define APPLETBDRM_MSG_GET_INFORMATION cpu_to_le32(0x47494e46) /* GINF */ ++#define APPLETBDRM_MSG_UPDATE_COMPLETE cpu_to_le32(0x5544434c) /* UDCL */ ++#define APPLETBDRM_MSG_SIGNAL_READINESS cpu_to_le32(0x52454459) /* REDY */ ++ ++#define APPLETBDRM_BULK_MSG_TIMEOUT 1000 ++ ++#define drm_to_adev(_drm) container_of(_drm, struct appletbdrm_device, drm) ++#define adev_to_udev(adev) interface_to_usbdev(to_usb_interface(adev->dmadev)) ++ ++struct appletbdrm_msg_request_header { ++ __le16 unk_00; ++ __le16 unk_02; ++ __le32 unk_04; ++ __le32 unk_08; ++ __le32 size; ++} __packed; ++ ++struct appletbdrm_msg_response_header { ++ u8 unk_00[16]; ++ __le32 msg; ++} __packed; ++ ++struct appletbdrm_msg_simple_request { ++ struct appletbdrm_msg_request_header header; ++ __le32 msg; ++ u8 unk_14[8]; ++ __le32 size; ++} __packed; ++ ++struct appletbdrm_msg_information { ++ struct appletbdrm_msg_response_header header; ++ u8 unk_14[12]; ++ __le32 width; ++ __le32 height; ++ u8 bits_per_pixel; ++ __le32 bytes_per_row; ++ __le32 orientation; ++ __le32 bitmap_info; ++ __le32 pixel_format; ++ __le32 width_inches; /* floating point */ ++ __le32 height_inches; /* floating point */ ++} __packed; ++ ++struct appletbdrm_frame { ++ __le16 begin_x; ++ __le16 begin_y; ++ __le16 width; ++ __le16 height; ++ __le32 buf_size; ++ u8 buf[]; ++} __packed; ++ ++struct appletbdrm_fb_request_footer { ++ u8 unk_00[12]; ++ __le32 unk_0c; ++ u8 unk_10[12]; ++ __le32 unk_1c; ++ __le64 timestamp; ++ u8 unk_28[12]; ++ __le32 unk_34; ++ u8 unk_38[20]; ++ __le32 unk_4c; ++} __packed; ++ ++struct appletbdrm_fb_request { ++ struct appletbdrm_msg_request_header header; ++ __le16 unk_10; ++ u8 msg_id; ++ u8 unk_13[29]; ++ /* ++ * Contents of `data`: ++ * - struct appletbdrm_frame frames[]; ++ * - struct appletbdrm_fb_request_footer footer; ++ * - padding to make the total size a multiple of 16 ++ */ ++ u8 data[]; ++} __packed; ++ ++struct appletbdrm_fb_request_response { ++ struct appletbdrm_msg_response_header header; ++ u8 unk_14[12]; ++ __le64 timestamp; ++} __packed; ++ ++struct appletbdrm_device { ++ struct device *dmadev; ++ ++ unsigned int in_ep; ++ unsigned int out_ep; ++ ++ unsigned int width; ++ unsigned int height; ++ ++ struct drm_device drm; ++ struct drm_display_mode mode; ++ struct drm_connector connector; ++ struct drm_plane primary_plane; ++ struct drm_crtc crtc; ++ struct drm_encoder encoder; ++}; ++ ++struct appletbdrm_plane_state { ++ struct drm_shadow_plane_state base; ++ struct appletbdrm_fb_request *request; ++ struct appletbdrm_fb_request_response *response; ++ size_t request_size; ++ size_t frames_size; ++}; ++ ++static inline struct appletbdrm_plane_state *to_appletbdrm_plane_state(struct drm_plane_state *state) ++{ ++ return container_of(state, struct appletbdrm_plane_state, base.base); ++} ++ ++static int appletbdrm_send_request(struct appletbdrm_device *adev, ++ struct appletbdrm_msg_request_header *request, size_t size) ++{ ++ struct usb_device *udev = adev_to_udev(adev); ++ struct drm_device *drm = &adev->drm; ++ int ret, actual_size; ++ ++ ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, adev->out_ep), ++ request, size, &actual_size, APPLETBDRM_BULK_MSG_TIMEOUT); ++ if (ret) { ++ drm_err(drm, "Failed to send message (%d)\n", ret); ++ return ret; ++ } ++ ++ if (actual_size != size) { ++ drm_err(drm, "Actual size (%d) doesn't match expected size (%zu)\n", ++ actual_size, size); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int appletbdrm_read_response(struct appletbdrm_device *adev, ++ struct appletbdrm_msg_response_header *response, ++ size_t size, __le32 expected_response) ++{ ++ struct usb_device *udev = adev_to_udev(adev); ++ struct drm_device *drm = &adev->drm; ++ int ret, actual_size; ++ bool readiness_signal_received = false; ++ ++retry: ++ ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, adev->in_ep), ++ response, size, &actual_size, APPLETBDRM_BULK_MSG_TIMEOUT); ++ if (ret) { ++ drm_err(drm, "Failed to read response (%d)\n", ret); ++ return ret; ++ } ++ ++ /* ++ * The device responds to the first request sent in a particular ++ * timeframe after the USB device configuration is set with a readiness ++ * signal, in which case the response should be read again ++ */ ++ if (response->msg == APPLETBDRM_MSG_SIGNAL_READINESS) { ++ if (!readiness_signal_received) { ++ readiness_signal_received = true; ++ goto retry; ++ } ++ ++ drm_err(drm, "Encountered unexpected readiness signal\n"); ++ return -EINTR; ++ } ++ ++ if (actual_size != size) { ++ drm_err(drm, "Actual size (%d) doesn't match expected size (%zu)\n", ++ actual_size, size); ++ return -EBADMSG; ++ } ++ ++ if (response->msg != expected_response) { ++ drm_err(drm, "Unexpected response from device (expected %p4cl found %p4cl)\n", ++ &expected_response, &response->msg); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int appletbdrm_send_msg(struct appletbdrm_device *adev, __le32 msg) ++{ ++ struct appletbdrm_msg_simple_request *request; ++ int ret; ++ ++ request = kzalloc(sizeof(*request), GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ ++ request->header.unk_00 = cpu_to_le16(2); ++ request->header.unk_02 = cpu_to_le16(0x1512); ++ request->header.size = cpu_to_le32(sizeof(*request) - sizeof(request->header)); ++ request->msg = msg; ++ request->size = request->header.size; ++ ++ ret = appletbdrm_send_request(adev, &request->header, sizeof(*request)); ++ ++ kfree(request); ++ ++ return ret; ++} ++ ++static int appletbdrm_clear_display(struct appletbdrm_device *adev) ++{ ++ return appletbdrm_send_msg(adev, APPLETBDRM_MSG_CLEAR_DISPLAY); ++} ++ ++static int appletbdrm_signal_readiness(struct appletbdrm_device *adev) ++{ ++ return appletbdrm_send_msg(adev, APPLETBDRM_MSG_SIGNAL_READINESS); ++} ++ ++static int appletbdrm_get_information(struct appletbdrm_device *adev) ++{ ++ struct appletbdrm_msg_information *info; ++ struct drm_device *drm = &adev->drm; ++ u8 bits_per_pixel; ++ __le32 pixel_format; ++ int ret; ++ ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ ++ ret = appletbdrm_send_msg(adev, APPLETBDRM_MSG_GET_INFORMATION); ++ if (ret) ++ return ret; ++ ++ ret = appletbdrm_read_response(adev, &info->header, sizeof(*info), ++ APPLETBDRM_MSG_GET_INFORMATION); ++ if (ret) ++ goto free_info; ++ ++ bits_per_pixel = info->bits_per_pixel; ++ pixel_format = get_unaligned(&info->pixel_format); ++ ++ adev->width = get_unaligned_le32(&info->width); ++ adev->height = get_unaligned_le32(&info->height); ++ ++ if (bits_per_pixel != APPLETBDRM_BITS_PER_PIXEL) { ++ drm_err(drm, "Encountered unexpected bits per pixel value (%d)\n", bits_per_pixel); ++ ret = -EINVAL; ++ goto free_info; ++ } ++ ++ if (pixel_format != APPLETBDRM_PIXEL_FORMAT) { ++ drm_err(drm, "Encountered unknown pixel format (%p4cl)\n", &pixel_format); ++ ret = -EINVAL; ++ goto free_info; ++ } ++ ++free_info: ++ kfree(info); ++ ++ return ret; ++} ++ ++static u32 rect_size(struct drm_rect *rect) ++{ ++ return drm_rect_width(rect) * drm_rect_height(rect) * ++ (BITS_TO_BYTES(APPLETBDRM_BITS_PER_PIXEL)); ++} ++ ++static int appletbdrm_connector_helper_get_modes(struct drm_connector *connector) ++{ ++ struct appletbdrm_device *adev = drm_to_adev(connector->dev); ++ ++ return drm_connector_helper_get_modes_fixed(connector, &adev->mode); ++} ++ ++static const u32 appletbdrm_primary_plane_formats[] = { ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_XRGB8888, /* emulated */ ++}; ++ ++static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane, ++ struct drm_atomic_state *state) ++{ ++ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); ++ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); ++ struct drm_crtc *new_crtc = new_plane_state->crtc; ++ struct drm_crtc_state *new_crtc_state = NULL; ++ struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(new_plane_state); ++ struct drm_atomic_helper_damage_iter iter; ++ struct drm_rect damage; ++ size_t frames_size = 0; ++ size_t request_size; ++ int ret; ++ ++ if (new_crtc) ++ new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); ++ ++ ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state, ++ DRM_PLANE_NO_SCALING, ++ DRM_PLANE_NO_SCALING, ++ false, false); ++ if (ret) ++ return ret; ++ else if (!new_plane_state->visible) ++ return 0; ++ ++ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, new_plane_state); ++ drm_atomic_for_each_plane_damage(&iter, &damage) { ++ frames_size += struct_size((struct appletbdrm_frame *)0, buf, rect_size(&damage)); ++ } ++ ++ if (!frames_size) ++ return 0; ++ ++ request_size = ALIGN(sizeof(struct appletbdrm_fb_request) + ++ frames_size + ++ sizeof(struct appletbdrm_fb_request_footer), 16); ++ ++ appletbdrm_state->request = kzalloc(request_size, GFP_KERNEL); ++ ++ if (!appletbdrm_state->request) ++ return -ENOMEM; ++ ++ appletbdrm_state->response = kzalloc(sizeof(*appletbdrm_state->response), GFP_KERNEL); ++ ++ if (!appletbdrm_state->response) ++ return -ENOMEM; ++ ++ appletbdrm_state->request_size = request_size; ++ appletbdrm_state->frames_size = frames_size; ++ ++ return 0; ++} ++ ++static int appletbdrm_flush_damage(struct appletbdrm_device *adev, ++ struct drm_plane_state *old_state, ++ struct drm_plane_state *state) ++{ ++ struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state); ++ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); ++ struct appletbdrm_fb_request_response *response = appletbdrm_state->response; ++ struct appletbdrm_fb_request_footer *footer; ++ struct drm_atomic_helper_damage_iter iter; ++ struct drm_framebuffer *fb = state->fb; ++ struct appletbdrm_fb_request *request = appletbdrm_state->request; ++ struct drm_device *drm = &adev->drm; ++ struct appletbdrm_frame *frame; ++ u64 timestamp = ktime_get_ns(); ++ struct drm_rect damage; ++ size_t frames_size = appletbdrm_state->frames_size; ++ size_t request_size = appletbdrm_state->request_size; ++ int ret; ++ ++ if (!frames_size) ++ return 0; ++ ++ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); ++ if (ret) { ++ drm_err(drm, "Failed to start CPU framebuffer access (%d)\n", ret); ++ goto end_fb_cpu_access; ++ } ++ ++ request->header.unk_00 = cpu_to_le16(2); ++ request->header.unk_02 = cpu_to_le16(0x12); ++ request->header.unk_04 = cpu_to_le32(9); ++ request->header.size = cpu_to_le32(request_size - sizeof(request->header)); ++ request->unk_10 = cpu_to_le16(1); ++ request->msg_id = timestamp; ++ ++ frame = (struct appletbdrm_frame *)request->data; ++ ++ drm_atomic_helper_damage_iter_init(&iter, old_state, state); ++ drm_atomic_for_each_plane_damage(&iter, &damage) { ++ struct drm_rect dst_clip = state->dst; ++ struct iosys_map dst = IOSYS_MAP_INIT_VADDR(frame->buf); ++ u32 buf_size = rect_size(&damage); ++ ++ if (!drm_rect_intersect(&dst_clip, &damage)) ++ continue; ++ ++ /* ++ * The coordinates need to be translated to the coordinate ++ * system the device expects, see the comment in ++ * appletbdrm_setup_mode_config ++ */ ++ frame->begin_x = cpu_to_le16(damage.y1); ++ frame->begin_y = cpu_to_le16(adev->height - damage.x2); ++ frame->width = cpu_to_le16(drm_rect_height(&damage)); ++ frame->height = cpu_to_le16(drm_rect_width(&damage)); ++ frame->buf_size = cpu_to_le32(buf_size); ++ ++ switch (fb->format->format) { ++ case DRM_FORMAT_XRGB8888: ++ drm_fb_xrgb8888_to_bgr888(&dst, NULL, &shadow_plane_state->data[0], fb, &damage, &shadow_plane_state->fmtcnv_state); ++ break; ++ default: ++ drm_fb_memcpy(&dst, NULL, &shadow_plane_state->data[0], fb, &damage); ++ break; ++ } ++ ++ frame = (void *)frame + struct_size(frame, buf, buf_size); ++ } ++ ++ footer = (struct appletbdrm_fb_request_footer *)&request->data[frames_size]; ++ ++ footer->unk_0c = cpu_to_le32(0xfffe); ++ footer->unk_1c = cpu_to_le32(0x80001); ++ footer->unk_34 = cpu_to_le32(0x80002); ++ footer->unk_4c = cpu_to_le32(0xffff); ++ footer->timestamp = cpu_to_le64(timestamp); ++ ++ ret = appletbdrm_send_request(adev, &request->header, request_size); ++ if (ret) ++ goto end_fb_cpu_access; ++ ++ ret = appletbdrm_read_response(adev, &response->header, sizeof(*response), ++ APPLETBDRM_MSG_UPDATE_COMPLETE); ++ if (ret) ++ goto end_fb_cpu_access; ++ ++ if (response->timestamp != footer->timestamp) { ++ drm_err(drm, "Response timestamp (%llu) doesn't match request timestamp (%llu)\n", ++ le64_to_cpu(response->timestamp), timestamp); ++ goto end_fb_cpu_access; ++ } ++ ++end_fb_cpu_access: ++ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); ++ ++ return ret; ++} ++ ++static void appletbdrm_primary_plane_helper_atomic_update(struct drm_plane *plane, ++ struct drm_atomic_state *old_state) ++{ ++ struct appletbdrm_device *adev = drm_to_adev(plane->dev); ++ struct drm_device *drm = plane->dev; ++ struct drm_plane_state *plane_state = plane->state; ++ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane); ++ int idx; ++ ++ if (!drm_dev_enter(drm, &idx)) ++ return; ++ ++ appletbdrm_flush_damage(adev, old_plane_state, plane_state); ++ ++ drm_dev_exit(idx); ++} ++ ++static void appletbdrm_primary_plane_helper_atomic_disable(struct drm_plane *plane, ++ struct drm_atomic_state *state) ++{ ++ struct drm_device *dev = plane->dev; ++ struct appletbdrm_device *adev = drm_to_adev(dev); ++ int idx; ++ ++ if (!drm_dev_enter(dev, &idx)) ++ return; ++ ++ appletbdrm_clear_display(adev); ++ ++ drm_dev_exit(idx); ++} ++ ++static void appletbdrm_primary_plane_reset(struct drm_plane *plane) ++{ ++ struct appletbdrm_plane_state *appletbdrm_state; ++ ++ WARN_ON(plane->state); ++ ++ appletbdrm_state = kzalloc(sizeof(*appletbdrm_state), GFP_KERNEL); ++ if (!appletbdrm_state) ++ return; ++ ++ __drm_gem_reset_shadow_plane(plane, &appletbdrm_state->base); ++} ++ ++static struct drm_plane_state *appletbdrm_primary_plane_duplicate_state(struct drm_plane *plane) ++{ ++ struct drm_shadow_plane_state *new_shadow_plane_state; ++ struct appletbdrm_plane_state *appletbdrm_state; ++ ++ if (WARN_ON(!plane->state)) ++ return NULL; ++ ++ appletbdrm_state = kzalloc(sizeof(*appletbdrm_state), GFP_KERNEL); ++ if (!appletbdrm_state) ++ return NULL; ++ ++ /* Request and response are not duplicated and are allocated in .atomic_check */ ++ appletbdrm_state->request = NULL; ++ appletbdrm_state->response = NULL; ++ ++ appletbdrm_state->request_size = 0; ++ appletbdrm_state->frames_size = 0; ++ ++ new_shadow_plane_state = &appletbdrm_state->base; ++ ++ __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); ++ ++ return &new_shadow_plane_state->base; ++} ++ ++static void appletbdrm_primary_plane_destroy_state(struct drm_plane *plane, ++ struct drm_plane_state *state) ++{ ++ struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state); ++ ++ kfree(appletbdrm_state->request); ++ kfree(appletbdrm_state->response); ++ ++ __drm_gem_destroy_shadow_plane_state(&appletbdrm_state->base); ++ ++ kfree(appletbdrm_state); ++} ++ ++static const struct drm_plane_helper_funcs appletbdrm_primary_plane_helper_funcs = { ++ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, ++ .atomic_check = appletbdrm_primary_plane_helper_atomic_check, ++ .atomic_update = appletbdrm_primary_plane_helper_atomic_update, ++ .atomic_disable = appletbdrm_primary_plane_helper_atomic_disable, ++}; ++ ++static const struct drm_plane_funcs appletbdrm_primary_plane_funcs = { ++ .update_plane = drm_atomic_helper_update_plane, ++ .disable_plane = drm_atomic_helper_disable_plane, ++ .reset = appletbdrm_primary_plane_reset, ++ .atomic_duplicate_state = appletbdrm_primary_plane_duplicate_state, ++ .atomic_destroy_state = appletbdrm_primary_plane_destroy_state, ++ .destroy = drm_plane_cleanup, ++}; ++ ++static enum drm_mode_status appletbdrm_crtc_helper_mode_valid(struct drm_crtc *crtc, ++ const struct drm_display_mode *mode) ++{ ++ struct appletbdrm_device *adev = drm_to_adev(crtc->dev); ++ ++ return drm_crtc_helper_mode_valid_fixed(crtc, mode, &adev->mode); ++} ++ ++static const struct drm_mode_config_funcs appletbdrm_mode_config_funcs = { ++ .fb_create = drm_gem_fb_create_with_dirty, ++ .atomic_check = drm_atomic_helper_check, ++ .atomic_commit = drm_atomic_helper_commit, ++}; ++ ++static const struct drm_connector_funcs appletbdrm_connector_funcs = { ++ .reset = drm_atomic_helper_connector_reset, ++ .destroy = drm_connector_cleanup, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, ++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ++}; ++ ++static const struct drm_connector_helper_funcs appletbdrm_connector_helper_funcs = { ++ .get_modes = appletbdrm_connector_helper_get_modes, ++}; ++ ++static const struct drm_crtc_helper_funcs appletbdrm_crtc_helper_funcs = { ++ .mode_valid = appletbdrm_crtc_helper_mode_valid, ++}; ++ ++static const struct drm_crtc_funcs appletbdrm_crtc_funcs = { ++ .reset = drm_atomic_helper_crtc_reset, ++ .destroy = drm_crtc_cleanup, ++ .set_config = drm_atomic_helper_set_config, ++ .page_flip = drm_atomic_helper_page_flip, ++ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, ++}; ++ ++static const struct drm_encoder_funcs appletbdrm_encoder_funcs = { ++ .destroy = drm_encoder_cleanup, ++}; ++ ++static struct drm_gem_object *appletbdrm_driver_gem_prime_import(struct drm_device *dev, ++ struct dma_buf *dma_buf) ++{ ++ struct appletbdrm_device *adev = drm_to_adev(dev); ++ ++ if (!adev->dmadev) ++ return ERR_PTR(-ENODEV); ++ ++ return drm_gem_prime_import_dev(dev, dma_buf, adev->dmadev); ++} ++ ++DEFINE_DRM_GEM_FOPS(appletbdrm_drm_fops); ++ ++static const struct drm_driver appletbdrm_drm_driver = { ++ DRM_GEM_SHMEM_DRIVER_OPS, ++ .gem_prime_import = appletbdrm_driver_gem_prime_import, ++ .name = "appletbdrm", ++ .desc = "Apple Touch Bar DRM Driver", ++ .major = 1, ++ .minor = 0, ++ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, ++ .fops = &appletbdrm_drm_fops, ++}; ++ ++static int appletbdrm_setup_mode_config(struct appletbdrm_device *adev) ++{ ++ struct drm_connector *connector = &adev->connector; ++ struct drm_plane *primary_plane; ++ struct drm_crtc *crtc; ++ struct drm_encoder *encoder; ++ struct drm_device *drm = &adev->drm; ++ int ret; ++ ++ ret = drmm_mode_config_init(drm); ++ if (ret) { ++ drm_err(drm, "Failed to initialize mode configuration\n"); ++ return ret; ++ } ++ ++ primary_plane = &adev->primary_plane; ++ ret = drm_universal_plane_init(drm, primary_plane, 0, ++ &appletbdrm_primary_plane_funcs, ++ appletbdrm_primary_plane_formats, ++ ARRAY_SIZE(appletbdrm_primary_plane_formats), ++ NULL, ++ DRM_PLANE_TYPE_PRIMARY, NULL); ++ if (ret) { ++ drm_err(drm, "Failed to initialize universal plane object\n"); ++ return ret; ++ } ++ ++ drm_plane_helper_add(primary_plane, &appletbdrm_primary_plane_helper_funcs); ++ drm_plane_enable_fb_damage_clips(primary_plane); ++ ++ crtc = &adev->crtc; ++ ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, ++ &appletbdrm_crtc_funcs, NULL); ++ if (ret) { ++ drm_err(drm, "Failed to initialize CRTC object\n"); ++ return ret; ++ } ++ ++ drm_crtc_helper_add(crtc, &appletbdrm_crtc_helper_funcs); ++ ++ encoder = &adev->encoder; ++ ret = drm_encoder_init(drm, encoder, &appletbdrm_encoder_funcs, ++ DRM_MODE_ENCODER_DAC, NULL); ++ if (ret) { ++ drm_err(drm, "Failed to initialize encoder\n"); ++ return ret; ++ } ++ ++ encoder->possible_crtcs = drm_crtc_mask(crtc); ++ ++ /* ++ * The coordinate system used by the device is different from the ++ * coordinate system of the framebuffer in that the x and y axes are ++ * swapped, and that the y axis is inverted; so what the device reports ++ * as the height is actually the width of the framebuffer and vice ++ * versa. ++ */ ++ drm->mode_config.max_width = max(adev->height, DRM_SHADOW_PLANE_MAX_WIDTH); ++ drm->mode_config.max_height = max(adev->width, DRM_SHADOW_PLANE_MAX_HEIGHT); ++ drm->mode_config.preferred_depth = APPLETBDRM_BITS_PER_PIXEL; ++ drm->mode_config.funcs = &appletbdrm_mode_config_funcs; ++ ++ adev->mode = (struct drm_display_mode) { ++ DRM_MODE_INIT(60, adev->height, adev->width, ++ DRM_MODE_RES_MM(adev->height, 218), ++ DRM_MODE_RES_MM(adev->width, 218)) ++ }; ++ ++ ret = drm_connector_init(drm, connector, ++ &appletbdrm_connector_funcs, DRM_MODE_CONNECTOR_USB); ++ if (ret) { ++ drm_err(drm, "Failed to initialize connector\n"); ++ return ret; ++ } ++ ++ drm_connector_helper_add(connector, &appletbdrm_connector_helper_funcs); ++ ++ ret = drm_connector_set_panel_orientation(connector, ++ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP); ++ if (ret) { ++ drm_err(drm, "Failed to set panel orientation\n"); ++ return ret; ++ } ++ ++ connector->display_info.non_desktop = true; ++ ret = drm_object_property_set_value(&connector->base, ++ drm->mode_config.non_desktop_property, true); ++ if (ret) { ++ drm_err(drm, "Failed to set non-desktop property\n"); ++ return ret; ++ } ++ ++ ret = drm_connector_attach_encoder(connector, encoder); ++ ++ if (ret) { ++ drm_err(drm, "Failed to initialize simple display pipe\n"); ++ return ret; ++ } ++ ++ drm_mode_config_reset(drm); ++ ++ return 0; ++} ++ ++static int appletbdrm_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_endpoint_descriptor *bulk_in, *bulk_out; ++ struct device *dev = &intf->dev; ++ struct appletbdrm_device *adev; ++ struct drm_device *drm = NULL; ++ int ret; ++ ++ ret = usb_find_common_endpoints(intf->cur_altsetting, &bulk_in, &bulk_out, NULL, NULL); ++ if (ret) { ++ drm_err(drm, "appletbdrm: Failed to find bulk endpoints\n"); ++ return ret; ++ } ++ ++ adev = devm_drm_dev_alloc(dev, &appletbdrm_drm_driver, struct appletbdrm_device, drm); ++ if (IS_ERR(adev)) ++ return PTR_ERR(adev); ++ ++ adev->in_ep = bulk_in->bEndpointAddress; ++ adev->out_ep = bulk_out->bEndpointAddress; ++ adev->dmadev = dev; ++ ++ drm = &adev->drm; ++ ++ usb_set_intfdata(intf, adev); ++ ++ ret = appletbdrm_get_information(adev); ++ if (ret) { ++ drm_err(drm, "Failed to get display information\n"); ++ return ret; ++ } ++ ++ ret = appletbdrm_signal_readiness(adev); ++ if (ret) { ++ drm_err(drm, "Failed to signal readiness\n"); ++ return ret; ++ } ++ ++ ret = appletbdrm_setup_mode_config(adev); ++ if (ret) { ++ drm_err(drm, "Failed to setup mode config\n"); ++ return ret; ++ } ++ ++ ret = drm_dev_register(drm, 0); ++ if (ret) { ++ drm_err(drm, "Failed to register DRM device\n"); ++ return ret; ++ } ++ ++ ret = appletbdrm_clear_display(adev); ++ if (ret) { ++ drm_err(drm, "Failed to clear display\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void appletbdrm_disconnect(struct usb_interface *intf) ++{ ++ struct appletbdrm_device *adev = usb_get_intfdata(intf); ++ struct drm_device *drm = &adev->drm; ++ ++ drm_dev_unplug(drm); ++ drm_atomic_helper_shutdown(drm); ++} ++ ++static void appletbdrm_shutdown(struct usb_interface *intf) ++{ ++ struct appletbdrm_device *adev = usb_get_intfdata(intf); ++ ++ /* ++ * The framebuffer needs to be cleared on shutdown since its content ++ * persists across boots ++ */ ++ drm_atomic_helper_shutdown(&adev->drm); ++} ++ ++static const struct usb_device_id appletbdrm_usb_id_table[] = { ++ { USB_DEVICE_INTERFACE_CLASS(0x05ac, 0x8302, USB_CLASS_AUDIO_VIDEO) }, ++ {} ++}; ++MODULE_DEVICE_TABLE(usb, appletbdrm_usb_id_table); ++ ++static struct usb_driver appletbdrm_usb_driver = { ++ .name = "appletbdrm", ++ .probe = appletbdrm_probe, ++ .disconnect = appletbdrm_disconnect, ++ .shutdown = appletbdrm_shutdown, ++ .id_table = appletbdrm_usb_id_table, ++}; ++module_usb_driver(appletbdrm_usb_driver); ++ ++MODULE_AUTHOR("Kerem Karabay "); ++MODULE_DESCRIPTION("Apple Touch Bar DRM Driver"); ++MODULE_LICENSE("GPL"); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/2008-i915-4-lane-quirk-for-mbp15-1.patch b/patch/kernel/archive/uefi-x86-6.12/2008-i915-4-lane-quirk-for-mbp15-1.patch new file mode 100644 index 000000000..be9b6fe69 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/2008-i915-4-lane-quirk-for-mbp15-1.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Fri, 28 Jun 2024 04:43:50 +0000 +Subject: i915: 4 lane quirk for mbp15,1 + +Needed to use iGPU when dGPU was boot GPU + +Patch written by Kerem Karabay +--- + drivers/gpu/drm/i915/display/intel_ddi.c | 4 +++ + drivers/gpu/drm/i915/display/intel_quirks.c | 15 ++++++++++ + drivers/gpu/drm/i915/display/intel_quirks.h | 1 + + 3 files changed, 20 insertions(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -4648,6 +4648,7 @@ static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) + + static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) + { ++ struct intel_display *display = to_intel_display(dig_port); + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + + if (dig_port->base.port != PORT_A) +@@ -4656,6 +4657,9 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) + if (dig_port->saved_port_bits & DDI_A_4_LANES) + return false; + ++ if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES)) ++ return true; ++ + /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only + * supported configuration + */ +diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_quirks.c ++++ b/drivers/gpu/drm/i915/display/intel_quirks.c +@@ -64,6 +64,18 @@ static void quirk_increase_ddi_disabled_time(struct intel_display *display) + drm_info(display->drm, "Applying Increase DDI Disabled quirk\n"); + } + ++/* ++ * In some cases, the firmware might not set the lane count to 4 (for example, ++ * when booting in some dual GPU Macs with the dGPU as the default GPU), this ++ * quirk is used to force it as otherwise it might not be possible to compute a ++ * valid link configuration. ++ */ ++static void quirk_ddi_a_force_4_lanes(struct intel_display *display) ++{ ++ intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES); ++ drm_info(display->drm, "Applying DDI A Forced 4 Lanes quirk\n"); ++} ++ + static void quirk_no_pps_backlight_power_hook(struct intel_display *display) + { + intel_set_quirk(display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK); +@@ -229,6 +241,9 @@ static struct intel_quirk intel_quirks[] = { + { 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time }, + /* HP Notebook - 14-r206nv */ + { 0x0f31, 0x103c, 0x220f, quirk_invert_brightness }, ++ ++ /* Apple MacBookPro15,1 */ ++ { 0x3e9b, 0x106b, 0x0176, quirk_ddi_a_force_4_lanes }, + }; + + static struct intel_dpcd_quirk intel_dpcd_quirks[] = { +diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_quirks.h ++++ b/drivers/gpu/drm/i915/display/intel_quirks.h +@@ -20,6 +20,7 @@ enum intel_quirk_id { + QUIRK_LVDS_SSC_DISABLE, + QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK, + QUIRK_FW_SYNC_LEN, ++ QUIRK_DDI_A_FORCE_4_LANES, + }; + + void intel_init_quirks(struct intel_display *display); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch b/patch/kernel/archive/uefi-x86-6.12/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch new file mode 100644 index 000000000..234416ed7 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Fri, 10 Feb 2023 22:45:00 +1100 +Subject: apple-gmux: allow switching to igpu at probe + +This means user don't need to set the gpu-power-prefs efivar to use the +igpu while runtime switching isn't working, so macOS will be unaffected. + +This isn't really upstreamable, what we want upstream is the ability to +switch at runtime (so both gpus need to be able to probe the eDP panel). + +Based off of work by Kerem Karabay +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++ + drivers/gpu/vga/vga_switcheroo.c | 7 +--- + drivers/pci/vgaarb.c | 1 + + drivers/platform/x86/apple-gmux.c | 18 ++++++++++ + 4 files changed, 23 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2262,6 +2262,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, + return -EINVAL; + } + ++ if (vga_switcheroo_client_probe_defer(pdev)) ++ return -EPROBE_DEFER; ++ + /* skip devices which are owned by radeon */ + for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) { + if (amdgpu_unsupported_pciidlist[i] == pdev->device) +diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/vga/vga_switcheroo.c ++++ b/drivers/gpu/vga/vga_switcheroo.c +@@ -438,12 +438,7 @@ find_active_client(struct list_head *head) + bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) + { + if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { +- /* +- * apple-gmux is needed on pre-retina MacBook Pro +- * to probe the panel if pdev is the inactive GPU. +- */ +- if (apple_gmux_present() && pdev != vga_default_device() && +- !vgasr_priv.handler_flags) ++ if (apple_gmux_present() && !vgasr_priv.handler_flags) + return true; + } + +diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c +index 111111111111..222222222222 100644 +--- a/drivers/pci/vgaarb.c ++++ b/drivers/pci/vgaarb.c +@@ -143,6 +143,7 @@ void vga_set_default_device(struct pci_dev *pdev) + pci_dev_put(vga_default); + vga_default = pci_dev_get(pdev); + } ++EXPORT_SYMBOL_GPL(vga_set_default_device); + + /** + * vga_remove_vgacon - deactivate VGA console +diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c +index 111111111111..222222222222 100644 +--- a/drivers/platform/x86/apple-gmux.c ++++ b/drivers/platform/x86/apple-gmux.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -107,6 +108,10 @@ struct apple_gmux_config { + + # define MMIO_GMUX_MAX_BRIGHTNESS 0xffff + ++static bool force_igd; ++module_param(force_igd, bool, 0); ++MODULE_PARM_DESC(force_idg, "Switch gpu to igd on module load. Make sure that you have apple-set-os set up and the iGPU is in `lspci -s 00:02.0`. (default: false) (bool)"); ++ + static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) + { + return inb(gmux_data->iostart + port); +@@ -945,6 +950,19 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) + gmux_enable_interrupts(gmux_data); + gmux_read_switch_state(gmux_data); + ++ if (force_igd) { ++ struct pci_dev *pdev; ++ ++ pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(2, 0)); ++ if (pdev) { ++ pr_info("Switching to IGD"); ++ gmux_switchto(VGA_SWITCHEROO_IGD); ++ vga_set_default_device(pdev); ++ } else { ++ pr_err("force_idg is true, but couldn't find iGPU at 00:02.0! Is apple-set-os working?"); ++ } ++ } ++ + /* + * Retina MacBook Pros cannot switch the panel's AUX separately + * and need eDP pre-calibration. They are distinguishable from +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3001-applesmc-convert-static-structures-to-drvdata.patch b/patch/kernel/archive/uefi-x86-6.12/3001-applesmc-convert-static-structures-to-drvdata.patch new file mode 100644 index 000000000..17c687ecb --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3001-applesmc-convert-static-structures-to-drvdata.patch @@ -0,0 +1,1218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:55 +0100 +Subject: applesmc: convert static structures to drvdata + +All static data structures have been moved to an applesmc_device struct, +which is then associated with the platform device. +This change is intended to ease the migration to an acpi_device, where +static data would preferably be avoided. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 540 ++++++---- + 1 file changed, 319 insertions(+), 221 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -6,6 +6,7 @@ + * + * Copyright (C) 2007 Nicolas Boichat + * Copyright (C) 2010 Henrik Rydberg ++ * Copyright (C) 2019 Paul Pawlowski + * + * Based on hdaps.c driver: + * Copyright (C) 2005 Robert Love +@@ -119,7 +120,7 @@ struct applesmc_entry { + }; + + /* Register lookup and registers common to all SMCs */ +-static struct applesmc_registers { ++struct applesmc_registers { + struct mutex mutex; /* register read/write mutex */ + unsigned int key_count; /* number of SMC registers */ + unsigned int fan_count; /* number of fans */ +@@ -133,26 +134,32 @@ static struct applesmc_registers { + bool init_complete; /* true when fully initialized */ + struct applesmc_entry *cache; /* cached key entries */ + const char **index; /* temperature key index */ +-} smcreg = { +- .mutex = __MUTEX_INITIALIZER(smcreg.mutex), + }; + +-static const int debug; +-static struct platform_device *pdev; +-static s16 rest_x; +-static s16 rest_y; +-static u8 backlight_state[2]; ++struct applesmc_device { ++ struct platform_device *dev; ++ struct applesmc_registers reg; + +-static struct device *hwmon_dev; +-static struct input_dev *applesmc_idev; ++ s16 rest_x; ++ s16 rest_y; + +-/* +- * Last index written to key_at_index sysfs file, and value to use for all other +- * key_at_index_* sysfs files. +- */ +-static unsigned int key_at_index; ++ u8 backlight_state[2]; ++ ++ struct device *hwmon_dev; ++ struct input_dev *idev; ++ ++ /* ++ * Last index written to key_at_index sysfs file, and value to use for all other ++ * key_at_index_* sysfs files. ++ */ ++ unsigned int key_at_index; ++ ++ struct workqueue_struct *backlight_wq; ++ struct work_struct backlight_work; ++ struct led_classdev backlight_dev; ++}; + +-static struct workqueue_struct *applesmc_led_wq; ++static const int debug; + + /* + * Wait for specific status bits with a mask on the SMC. +@@ -338,36 +345,37 @@ static int read_register_count(unsigned int *count) + * All functions below are concurrency safe - callers should NOT hold lock. + */ + +-static int applesmc_read_entry(const struct applesmc_entry *entry, +- u8 *buf, u8 len) ++static int applesmc_read_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + + return ret; + } + +-static int applesmc_write_entry(const struct applesmc_entry *entry, +- const u8 *buf, u8 len) ++static int applesmc_write_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, const u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + return ret; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_index(int index) ++static const struct applesmc_entry *applesmc_get_entry_by_index( ++ struct applesmc_device *smc, int index) + { +- struct applesmc_entry *cache = &smcreg.cache[index]; ++ struct applesmc_entry *cache = &smc->reg.cache[index]; + u8 key[4], info[6]; + __be32 be; + int ret = 0; +@@ -375,7 +383,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + if (cache->valid) + return cache; + +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + + if (cache->valid) + goto out; +@@ -394,20 +402,21 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + cache->valid = true; + + out: +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + if (ret) + return ERR_PTR(ret); + return cache; + } + +-static int applesmc_get_lower_bound(unsigned int *lo, const char *key) ++static int applesmc_get_lower_bound(struct applesmc_device *smc, ++ unsigned int *lo, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { + *lo = 0; + return PTR_ERR(entry); +@@ -422,16 +431,17 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) + return 0; + } + +-static int applesmc_get_upper_bound(unsigned int *hi, const char *key) ++static int applesmc_get_upper_bound(struct applesmc_device *smc, ++ unsigned int *hi, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { +- *hi = smcreg.key_count; ++ *hi = smc->reg.key_count; + return PTR_ERR(entry); + } + if (strcmp(key, entry->key) < 0) +@@ -444,50 +454,54 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) + return 0; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key) ++static const struct applesmc_entry *applesmc_get_entry_by_key( ++ struct applesmc_device *smc, const char *key) + { + int begin, end; + int ret; + +- ret = applesmc_get_lower_bound(&begin, key); ++ ret = applesmc_get_lower_bound(smc, &begin, key); + if (ret) + return ERR_PTR(ret); +- ret = applesmc_get_upper_bound(&end, key); ++ ret = applesmc_get_upper_bound(smc, &end, key); + if (ret) + return ERR_PTR(ret); + if (end - begin != 1) + return ERR_PTR(-EINVAL); + +- return applesmc_get_entry_by_index(begin); ++ return applesmc_get_entry_by_index(smc, begin); + } + +-static int applesmc_read_key(const char *key, u8 *buffer, u8 len) ++static int applesmc_read_key(struct applesmc_device *smc, ++ const char *key, u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_read_entry(entry, buffer, len); ++ return applesmc_read_entry(smc, entry, buffer, len); + } + +-static int applesmc_write_key(const char *key, const u8 *buffer, u8 len) ++static int applesmc_write_key(struct applesmc_device *smc, ++ const char *key, const u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_write_entry(entry, buffer, len); ++ return applesmc_write_entry(smc, entry, buffer, len); + } + +-static int applesmc_has_key(const char *key, bool *value) ++static int applesmc_has_key(struct applesmc_device *smc, ++ const char *key, bool *value) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) + return PTR_ERR(entry); + +@@ -498,12 +512,13 @@ static int applesmc_has_key(const char *key, bool *value) + /* + * applesmc_read_s16 - Read 16-bit signed big endian register + */ +-static int applesmc_read_s16(const char *key, s16 *value) ++static int applesmc_read_s16(struct applesmc_device *smc, ++ const char *key, s16 *value) + { + u8 buffer[2]; + int ret; + +- ret = applesmc_read_key(key, buffer, 2); ++ ret = applesmc_read_key(smc, key, buffer, 2); + if (ret) + return ret; + +@@ -514,28 +529,29 @@ static int applesmc_read_s16(const char *key, s16 *value) + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +-static void applesmc_device_init(void) ++static void applesmc_device_init(struct applesmc_device *smc) + { + int total; + u8 buffer[2]; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; + + for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { +- if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && ++ if (!applesmc_read_key(smc, MOTION_SENSOR_KEY, buffer, 2) && + (buffer[0] != 0x00 || buffer[1] != 0x00)) + return; + buffer[0] = 0xe0; + buffer[1] = 0x00; +- applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); ++ applesmc_write_key(smc, MOTION_SENSOR_KEY, buffer, 2); + msleep(INIT_WAIT_MSECS); + } + + pr_warn("failed to init the device\n"); + } + +-static int applesmc_init_index(struct applesmc_registers *s) ++static int applesmc_init_index(struct applesmc_device *smc, ++ struct applesmc_registers *s) + { + const struct applesmc_entry *entry; + unsigned int i; +@@ -548,7 +564,7 @@ static int applesmc_init_index(struct applesmc_registers *s) + return -ENOMEM; + + for (i = s->temp_begin; i < s->temp_end; i++) { +- entry = applesmc_get_entry_by_index(i); ++ entry = applesmc_get_entry_by_index(smc, i); + if (IS_ERR(entry)) + continue; + if (strcmp(entry->type, TEMP_SENSOR_TYPE)) +@@ -562,9 +578,9 @@ static int applesmc_init_index(struct applesmc_registers *s) + /* + * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. + */ +-static int applesmc_init_smcreg_try(void) ++static int applesmc_init_smcreg_try(struct applesmc_device *smc) + { +- struct applesmc_registers *s = &smcreg; ++ struct applesmc_registers *s = &smc->reg; + bool left_light_sensor = false, right_light_sensor = false; + unsigned int count; + u8 tmp[1]; +@@ -590,35 +606,35 @@ static int applesmc_init_smcreg_try(void) + if (!s->cache) + return -ENOMEM; + +- ret = applesmc_read_key(FANS_COUNT, tmp, 1); ++ ret = applesmc_read_key(smc, FANS_COUNT, tmp, 1); + if (ret) + return ret; + s->fan_count = tmp[0]; + if (s->fan_count > 10) + s->fan_count = 10; + +- ret = applesmc_get_lower_bound(&s->temp_begin, "T"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_begin, "T"); + if (ret) + return ret; +- ret = applesmc_get_lower_bound(&s->temp_end, "U"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_end, "U"); + if (ret) + return ret; + s->temp_count = s->temp_end - s->temp_begin; + +- ret = applesmc_init_index(s); ++ ret = applesmc_init_index(smc, s); + if (ret) + return ret; + +- ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); ++ ret = applesmc_has_key(smc, MOTION_SENSOR_KEY, &s->has_accelerometer); + if (ret) + return ret; +- ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); ++ ret = applesmc_has_key(smc, BACKLIGHT_KEY, &s->has_key_backlight); + if (ret) + return ret; + +@@ -634,13 +650,13 @@ static int applesmc_init_smcreg_try(void) + return 0; + } + +-static void applesmc_destroy_smcreg(void) ++static void applesmc_destroy_smcreg(struct applesmc_device *smc) + { +- kfree(smcreg.index); +- smcreg.index = NULL; +- kfree(smcreg.cache); +- smcreg.cache = NULL; +- smcreg.init_complete = false; ++ kfree(smc->reg.index); ++ smc->reg.index = NULL; ++ kfree(smc->reg.cache); ++ smc->reg.cache = NULL; ++ smc->reg.init_complete = false; + } + + /* +@@ -649,12 +665,12 @@ static void applesmc_destroy_smcreg(void) + * Retries until initialization is successful, or the operation times out. + * + */ +-static int applesmc_init_smcreg(void) ++static int applesmc_init_smcreg(struct applesmc_device *smc) + { + int ms, ret; + + for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) { +- ret = applesmc_init_smcreg_try(); ++ ret = applesmc_init_smcreg_try(smc); + if (!ret) { + if (ms) + pr_info("init_smcreg() took %d ms\n", ms); +@@ -663,21 +679,58 @@ static int applesmc_init_smcreg(void) + msleep(INIT_WAIT_MSECS); + } + +- applesmc_destroy_smcreg(); ++ applesmc_destroy_smcreg(smc); + + return ret; + } + + /* Device model stuff */ ++static int applesmc_create_modules(struct applesmc_device *smc); ++static void applesmc_destroy_modules(struct applesmc_device *smc); + static int applesmc_probe(struct platform_device *dev) + { ++ struct applesmc_device *smc; + int ret; + +- ret = applesmc_init_smcreg(); ++ smc = kzalloc(sizeof(struct applesmc_device), GFP_KERNEL); ++ if (!smc) ++ return -ENOMEM; ++ smc->dev = dev; ++ mutex_init(&smc->reg.mutex); ++ ++ platform_set_drvdata(dev, smc); ++ ++ ret = applesmc_init_smcreg(smc); + if (ret) +- return ret; ++ goto out_mem; ++ ++ applesmc_device_init(smc); ++ ++ ret = applesmc_create_modules(smc); ++ if (ret) ++ goto out_reg; ++ ++ return 0; ++ ++out_reg: ++ applesmc_destroy_smcreg(smc); ++out_mem: ++ platform_set_drvdata(dev, NULL); ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + +- applesmc_device_init(); ++ return ret; ++} ++ ++static int applesmc_remove(struct platform_device *dev) ++{ ++ struct applesmc_device *smc = platform_get_drvdata(dev); ++ ++ applesmc_destroy_modules(smc); ++ applesmc_destroy_smcreg(smc); ++ ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + + return 0; + } +@@ -685,15 +738,21 @@ static int applesmc_probe(struct platform_device *dev) + /* Synchronize device with memorized backlight state */ + static int applesmc_pm_resume(struct device *dev) + { +- if (smcreg.has_key_backlight) +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ if (smc->reg.has_key_backlight) ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); ++ + return 0; + } + + /* Reinitialize device on resume from hibernation */ + static int applesmc_pm_restore(struct device *dev) + { +- applesmc_device_init(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_device_init(smc); ++ + return applesmc_pm_resume(dev); + } + +@@ -704,6 +763,7 @@ static const struct dev_pm_ops applesmc_pm_ops = { + + static struct platform_driver applesmc_driver = { + .probe = applesmc_probe, ++ .remove = applesmc_remove, + .driver = { + .name = "applesmc", + .pm = &applesmc_pm_ops, +@@ -714,25 +774,26 @@ static struct platform_driver applesmc_driver = { + * applesmc_calibrate - Set our "resting" values. Callers must + * hold applesmc_lock. + */ +-static void applesmc_calibrate(void) ++static void applesmc_calibrate(struct applesmc_device *smc) + { +- applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x); +- applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y); +- rest_x = -rest_x; ++ applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &smc->rest_x); ++ applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &smc->rest_y); ++ smc->rest_x = -smc->rest_x; + } + + static void applesmc_idev_poll(struct input_dev *idev) + { ++ struct applesmc_device *smc = dev_get_drvdata(&idev->dev); + s16 x, y; + +- if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x)) + return; +- if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y)) + return; + + x = -x; +- input_report_abs(idev, ABS_X, x - rest_x); +- input_report_abs(idev, ABS_Y, y - rest_y); ++ input_report_abs(idev, ABS_X, x - smc->rest_x); ++ input_report_abs(idev, ABS_Y, y - smc->rest_y); + input_sync(idev); + } + +@@ -747,16 +808,17 @@ static ssize_t applesmc_name_show(struct device *dev, + static ssize_t applesmc_position_show(struct device *dev, + struct device_attribute *attr, char *buf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + s16 x, y, z; + +- ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Z_KEY, &z); + if (ret) + goto out; + +@@ -770,6 +832,7 @@ static ssize_t applesmc_position_show(struct device *dev, + static ssize_t applesmc_light_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + static int data_length; + int ret; +@@ -777,7 +840,7 @@ static ssize_t applesmc_light_show(struct device *dev, + u8 buffer[10]; + + if (!data_length) { +- entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY); ++ entry = applesmc_get_entry_by_key(smc, LIGHT_SENSOR_LEFT_KEY); + if (IS_ERR(entry)) + return PTR_ERR(entry); + if (entry->len > 10) +@@ -786,7 +849,7 @@ static ssize_t applesmc_light_show(struct device *dev, + pr_info("light sensor data length set to %d\n", data_length); + } + +- ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + if (ret) + goto out; + /* newer macbooks report a single 10-bit bigendian value */ +@@ -796,7 +859,7 @@ static ssize_t applesmc_light_show(struct device *dev, + } + left = buffer[2]; + +- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); + if (ret) + goto out; + right = buffer[2]; +@@ -812,7 +875,8 @@ static ssize_t applesmc_light_show(struct device *dev, + static ssize_t applesmc_show_sensor_label(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + + return sysfs_emit(sysfsbuf, "%s\n", key); + } +@@ -821,12 +885,13 @@ static ssize_t applesmc_show_sensor_label(struct device *dev, + static ssize_t applesmc_show_temperature(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + int ret; + s16 value; + int temp; + +- ret = applesmc_read_s16(key, &value); ++ ret = applesmc_read_s16(smc, key, &value); + if (ret) + return ret; + +@@ -838,6 +903,7 @@ static ssize_t applesmc_show_temperature(struct device *dev, + static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -846,7 +912,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 2); ++ ret = applesmc_read_key(smc, newkey, buffer, 2); + if (ret) + return ret; + +@@ -858,6 +924,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned long speed; + char newkey[5]; +@@ -871,7 +938,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + + buffer[0] = (speed >> 6) & 0xff; + buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(newkey, buffer, 2); ++ ret = applesmc_write_key(smc, newkey, buffer, 2); + + if (ret) + return ret; +@@ -882,11 +949,12 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + static ssize_t applesmc_show_fan_manual(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u16 manual = 0; + u8 buffer[2]; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +@@ -898,6 +966,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; + unsigned long input; +@@ -906,7 +975,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + goto out; + +@@ -920,7 +989,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + buffer[0] = (val >> 8) & 0xFF; + buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); + + out: + if (ret) +@@ -932,13 +1001,14 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + static ssize_t applesmc_show_fan_position(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + char newkey[5]; + u8 buffer[17]; + + scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 16); ++ ret = applesmc_read_key(smc, newkey, buffer, 16); + buffer[16] = 0; + + if (ret) +@@ -950,30 +1020,36 @@ static ssize_t applesmc_show_fan_position(struct device *dev, + static ssize_t applesmc_calibrate_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return sysfs_emit(sysfsbuf, "(%d,%d)\n", rest_x, rest_y); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return sysfs_emit(sysfsbuf, "(%d,%d)\n", smc->rest_x, smc->rest_y); + } + + static ssize_t applesmc_calibrate_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { +- applesmc_calibrate(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_calibrate(smc); + + return count; + } + + static void applesmc_backlight_set(struct work_struct *work) + { +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = container_of(work, struct applesmc_device, backlight_work); ++ ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); + } +-static DECLARE_WORK(backlight_work, &applesmc_backlight_set); + + static void applesmc_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) + { ++ struct applesmc_device *smc = dev_get_drvdata(led_cdev->dev); + int ret; + +- backlight_state[0] = value; +- ret = queue_work(applesmc_led_wq, &backlight_work); ++ smc->backlight_state[0] = value; ++ ret = queue_work(smc->backlight_wq, &smc->backlight_work); + + if (debug && (!ret)) + dev_dbg(led_cdev->dev, "work was already on the queue.\n"); +@@ -982,11 +1058,12 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, + static ssize_t applesmc_key_count_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[4]; + u32 count; + +- ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); ++ ret = applesmc_read_key(smc, KEY_COUNT_KEY, buffer, 4); + if (ret) + return ret; + +@@ -998,13 +1075,14 @@ static ssize_t applesmc_key_count_show(struct device *dev, + static ssize_t applesmc_key_at_index_read_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + int ret; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); +- ret = applesmc_read_entry(entry, sysfsbuf, entry->len); ++ ret = applesmc_read_entry(smc, entry, sysfsbuf, entry->len); + if (ret) + return ret; + +@@ -1014,9 +1092,10 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev, + static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1026,9 +1105,10 @@ static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + static ssize_t applesmc_key_at_index_type_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1038,9 +1118,10 @@ static ssize_t applesmc_key_at_index_type_show(struct device *dev, + static ssize_t applesmc_key_at_index_name_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1050,28 +1131,25 @@ static ssize_t applesmc_key_at_index_name_show(struct device *dev, + static ssize_t applesmc_key_at_index_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return sysfs_emit(sysfsbuf, "%d\n", key_at_index); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return sysfs_emit(sysfsbuf, "%d\n", smc->key_at_index); + } + + static ssize_t applesmc_key_at_index_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + unsigned long newkey; + + if (kstrtoul(sysfsbuf, 10, &newkey) < 0 +- || newkey >= smcreg.key_count) ++ || newkey >= smc->reg.key_count) + return -EINVAL; + +- key_at_index = newkey; ++ smc->key_at_index = newkey; + return count; + } + +-static struct led_classdev applesmc_backlight = { +- .name = "smc::kbd_backlight", +- .default_trigger = "nand-disk", +- .brightness_set = applesmc_brightness_set, +-}; +- + static struct applesmc_node_group info_group[] = { + { "name", applesmc_name_show }, + { "key_count", applesmc_key_count_show }, +@@ -1116,14 +1194,15 @@ static struct applesmc_node_group temp_group[] = { + /* + * applesmc_destroy_nodes - remove files and free associated memory + */ +-static void applesmc_destroy_nodes(struct applesmc_node_group *groups) ++static void applesmc_destroy_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; + + for (grp = groups; grp->nodes; grp++) { + for (node = grp->nodes; node->sda.dev_attr.attr.name; node++) +- sysfs_remove_file(&pdev->dev.kobj, ++ sysfs_remove_file(&smc->dev->dev.kobj, + &node->sda.dev_attr.attr); + kfree(grp->nodes); + grp->nodes = NULL; +@@ -1133,7 +1212,8 @@ static void applesmc_destroy_nodes(struct applesmc_node_group *groups) + /* + * applesmc_create_nodes - create a two-dimensional group of sysfs files + */ +-static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) ++static int applesmc_create_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups, int num) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; +@@ -1157,7 +1237,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + sysfs_attr_init(attr); + attr->name = node->name; + attr->mode = 0444 | (grp->store ? 0200 : 0); +- ret = sysfs_create_file(&pdev->dev.kobj, attr); ++ ret = sysfs_create_file(&smc->dev->dev.kobj, attr); + if (ret) { + attr->name = NULL; + goto out; +@@ -1167,57 +1247,57 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + + return 0; + out: +- applesmc_destroy_nodes(groups); ++ applesmc_destroy_nodes(smc, groups); + return ret; + } + + /* Create accelerometer resources */ +-static int applesmc_create_accelerometer(void) ++static int applesmc_create_accelerometer(struct applesmc_device *smc) + { + int ret; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return 0; + +- ret = applesmc_create_nodes(accelerometer_group, 1); ++ ret = applesmc_create_nodes(smc, accelerometer_group, 1); + if (ret) + goto out; + +- applesmc_idev = input_allocate_device(); +- if (!applesmc_idev) { ++ smc->idev = input_allocate_device(); ++ if (!smc->idev) { + ret = -ENOMEM; + goto out_sysfs; + } + + /* initial calibrate for the input device */ +- applesmc_calibrate(); ++ applesmc_calibrate(smc); + + /* initialize the input device */ +- applesmc_idev->name = "applesmc"; +- applesmc_idev->id.bustype = BUS_HOST; +- applesmc_idev->dev.parent = &pdev->dev; +- input_set_abs_params(applesmc_idev, ABS_X, ++ smc->idev->name = "applesmc"; ++ smc->idev->id.bustype = BUS_HOST; ++ smc->idev->dev.parent = &smc->dev->dev; ++ input_set_abs_params(smc->idev, ABS_X, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); +- input_set_abs_params(applesmc_idev, ABS_Y, ++ input_set_abs_params(smc->idev, ABS_Y, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); + +- ret = input_setup_polling(applesmc_idev, applesmc_idev_poll); ++ ret = input_setup_polling(smc->idev, applesmc_idev_poll); + if (ret) + goto out_idev; + +- input_set_poll_interval(applesmc_idev, APPLESMC_POLL_INTERVAL); ++ input_set_poll_interval(smc->idev, APPLESMC_POLL_INTERVAL); + +- ret = input_register_device(applesmc_idev); ++ ret = input_register_device(smc->idev); + if (ret) + goto out_idev; + + return 0; + + out_idev: +- input_free_device(applesmc_idev); ++ input_free_device(smc->idev); + + out_sysfs: +- applesmc_destroy_nodes(accelerometer_group); ++ applesmc_destroy_nodes(smc, accelerometer_group); + + out: + pr_warn("driver init failed (ret=%d)!\n", ret); +@@ -1225,44 +1305,55 @@ static int applesmc_create_accelerometer(void) + } + + /* Release all resources used by the accelerometer */ +-static void applesmc_release_accelerometer(void) ++static void applesmc_release_accelerometer(struct applesmc_device *smc) + { +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; +- input_unregister_device(applesmc_idev); +- applesmc_destroy_nodes(accelerometer_group); ++ input_unregister_device(smc->idev); ++ applesmc_destroy_nodes(smc, accelerometer_group); + } + +-static int applesmc_create_light_sensor(void) ++static int applesmc_create_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return 0; +- return applesmc_create_nodes(light_sensor_group, 1); ++ return applesmc_create_nodes(smc, light_sensor_group, 1); + } + +-static void applesmc_release_light_sensor(void) ++static void applesmc_release_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return; +- applesmc_destroy_nodes(light_sensor_group); ++ applesmc_destroy_nodes(smc, light_sensor_group); + } + +-static int applesmc_create_key_backlight(void) ++static int applesmc_create_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ int ret; ++ ++ if (!smc->reg.has_key_backlight) + return 0; +- applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); +- if (!applesmc_led_wq) ++ smc->backlight_wq = create_singlethread_workqueue("applesmc-led"); ++ if (!smc->backlight_wq) + return -ENOMEM; +- return led_classdev_register(&pdev->dev, &applesmc_backlight); ++ ++ INIT_WORK(&smc->backlight_work, applesmc_backlight_set); ++ smc->backlight_dev.name = "smc::kbd_backlight"; ++ smc->backlight_dev.default_trigger = "nand-disk"; ++ smc->backlight_dev.brightness_set = applesmc_brightness_set; ++ ret = led_classdev_register(&smc->dev->dev, &smc->backlight_dev); ++ if (ret) ++ destroy_workqueue(smc->backlight_wq); ++ ++ return ret; + } + +-static void applesmc_release_key_backlight(void) ++static void applesmc_release_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ if (!smc->reg.has_key_backlight) + return; +- led_classdev_unregister(&applesmc_backlight); +- destroy_workqueue(applesmc_led_wq); ++ led_classdev_unregister(&smc->backlight_dev); ++ destroy_workqueue(smc->backlight_wq); + } + + static int applesmc_dmi_match(const struct dmi_system_id *id) +@@ -1306,86 +1397,100 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = { + { .ident = NULL } + }; + +-static int __init applesmc_init(void) ++static int applesmc_create_modules(struct applesmc_device *smc) + { + int ret; + +- if (!dmi_check_system(applesmc_whitelist)) { +- pr_warn("supported laptop not found!\n"); +- ret = -ENODEV; +- goto out; +- } +- +- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, +- "applesmc")) { +- ret = -ENXIO; +- goto out; +- } +- +- ret = platform_driver_register(&applesmc_driver); +- if (ret) +- goto out_region; +- +- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, +- NULL, 0); +- if (IS_ERR(pdev)) { +- ret = PTR_ERR(pdev); +- goto out_driver; +- } +- +- /* create register cache */ +- ret = applesmc_init_smcreg(); +- if (ret) +- goto out_device; +- +- ret = applesmc_create_nodes(info_group, 1); ++ ret = applesmc_create_nodes(smc, info_group, 1); + if (ret) +- goto out_smcreg; ++ goto out; + +- ret = applesmc_create_nodes(fan_group, smcreg.fan_count); ++ ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count); + if (ret) + goto out_info; + +- ret = applesmc_create_nodes(temp_group, smcreg.index_count); ++ ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count); + if (ret) + goto out_fans; + +- ret = applesmc_create_accelerometer(); ++ ret = applesmc_create_accelerometer(smc); + if (ret) + goto out_temperature; + +- ret = applesmc_create_light_sensor(); ++ ret = applesmc_create_light_sensor(smc); + if (ret) + goto out_accelerometer; + +- ret = applesmc_create_key_backlight(); ++ ret = applesmc_create_key_backlight(smc); + if (ret) + goto out_light_sysfs; + +- hwmon_dev = hwmon_device_register(&pdev->dev); +- if (IS_ERR(hwmon_dev)) { +- ret = PTR_ERR(hwmon_dev); ++ smc->hwmon_dev = hwmon_device_register(&smc->dev->dev); ++ if (IS_ERR(smc->hwmon_dev)) { ++ ret = PTR_ERR(smc->hwmon_dev); + goto out_light_ledclass; + } + + return 0; + + out_light_ledclass: +- applesmc_release_key_backlight(); ++ applesmc_release_key_backlight(smc); + out_light_sysfs: +- applesmc_release_light_sensor(); ++ applesmc_release_light_sensor(smc); + out_accelerometer: +- applesmc_release_accelerometer(); ++ applesmc_release_accelerometer(smc); + out_temperature: +- applesmc_destroy_nodes(temp_group); ++ applesmc_destroy_nodes(smc, temp_group); + out_fans: +- applesmc_destroy_nodes(fan_group); ++ applesmc_destroy_nodes(smc, fan_group); + out_info: +- applesmc_destroy_nodes(info_group); +-out_smcreg: +- applesmc_destroy_smcreg(); +-out_device: +- platform_device_unregister(pdev); ++ applesmc_destroy_nodes(smc, info_group); ++out: ++ return ret; ++} ++ ++static void applesmc_destroy_modules(struct applesmc_device *smc) ++{ ++ hwmon_device_unregister(smc->hwmon_dev); ++ applesmc_release_key_backlight(smc); ++ applesmc_release_light_sensor(smc); ++ applesmc_release_accelerometer(smc); ++ applesmc_destroy_nodes(smc, temp_group); ++ applesmc_destroy_nodes(smc, fan_group); ++ applesmc_destroy_nodes(smc, info_group); ++} ++ ++static struct platform_device *pdev; ++ ++static int __init applesmc_init(void) ++{ ++ int ret; ++ ++ if (!dmi_check_system(applesmc_whitelist)) { ++ pr_warn("supported laptop not found!\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, ++ "applesmc")) { ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ ret = platform_driver_register(&applesmc_driver); ++ if (ret) ++ goto out_region; ++ ++ pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, ++ NULL, 0); ++ if (IS_ERR(pdev)) { ++ ret = PTR_ERR(pdev); ++ goto out_driver; ++ } ++ ++ return 0; ++ + out_driver: + platform_driver_unregister(&applesmc_driver); + out_region: +@@ -1397,14 +1502,6 @@ static int __init applesmc_init(void) + + static void __exit applesmc_exit(void) + { +- hwmon_device_unregister(hwmon_dev); +- applesmc_release_key_backlight(); +- applesmc_release_light_sensor(); +- applesmc_release_accelerometer(); +- applesmc_destroy_nodes(temp_group); +- applesmc_destroy_nodes(fan_group); +- applesmc_destroy_nodes(info_group); +- applesmc_destroy_smcreg(); + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); + release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); +@@ -1414,6 +1511,7 @@ module_init(applesmc_init); + module_exit(applesmc_exit); + + MODULE_AUTHOR("Nicolas Boichat"); ++MODULE_AUTHOR("Paul Pawlowski"); + MODULE_DESCRIPTION("Apple SMC"); + MODULE_LICENSE("GPL v2"); + MODULE_DEVICE_TABLE(dmi, applesmc_whitelist); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3002-applesmc-make-io-port-base-addr-dynamic.patch b/patch/kernel/archive/uefi-x86-6.12/3002-applesmc-make-io-port-base-addr-dynamic.patch new file mode 100644 index 000000000..c6640a593 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3002-applesmc-make-io-port-base-addr-dynamic.patch @@ -0,0 +1,312 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:11:56 +0100 +Subject: applesmc: make io port base addr dynamic + +This change makes the port base runtime configurable. +The reason why this change is made is so that when we switch to an +acpi_device we can resolve the port base addr from ACPI. + +This change is not strictly required for T2 support - the base +address is still 0x300 on T2 Macs. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 91 +++++----- + 1 file changed, 49 insertions(+), 42 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -35,10 +35,11 @@ + #include + #include + ++#define APPLESMC_PORT_BASE 0x300 + /* data port used by Apple SMC */ +-#define APPLESMC_DATA_PORT 0x300 ++#define APPLESMC_DATA_PORT 0 + /* command/status port used by Apple SMC */ +-#define APPLESMC_CMD_PORT 0x304 ++#define APPLESMC_CMD_PORT 4 + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + +@@ -140,6 +141,8 @@ struct applesmc_device { + struct platform_device *dev; + struct applesmc_registers reg; + ++ u16 port_base; ++ + s16 rest_x; + s16 rest_y; + +@@ -169,7 +172,7 @@ static const int debug; + * run out past 500ms. + */ + +-static int wait_status(u8 val, u8 mask) ++static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) + { + u8 status; + int us; +@@ -177,7 +180,7 @@ static int wait_status(u8 val, u8 mask) + + us = APPLESMC_MIN_WAIT; + for (i = 0; i < 24 ; i++) { +- status = inb(APPLESMC_CMD_PORT); ++ status = inb(smc->port_base + APPLESMC_CMD_PORT); + if ((status & mask) == val) + return 0; + usleep_range(us, us * 2); +@@ -189,11 +192,11 @@ static int wait_status(u8 val, u8 mask) + + /* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ + +-static int send_byte(u8 cmd, u16 port) ++static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + { + int status; + +- status = wait_status(0, SMC_STATUS_IB_CLOSED); ++ status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (status) + return status; + /* +@@ -202,24 +205,24 @@ static int send_byte(u8 cmd, u16 port) + * this extra read may not happen if status returns both + * simultaneously and this would appear to be required. + */ +- status = wait_status(SMC_STATUS_BUSY, SMC_STATUS_BUSY); ++ status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); + if (status) + return status; + +- outb(cmd, port); ++ outb(cmd, smc->port_base + port); + return 0; + } + + /* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ + +-static int send_command(u8 cmd) ++static int send_command(struct applesmc_device *smc, u8 cmd) + { + int ret; + +- ret = wait_status(0, SMC_STATUS_IB_CLOSED); ++ ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (ret) + return ret; +- outb(cmd, APPLESMC_CMD_PORT); ++ outb(cmd, smc->port_base + APPLESMC_CMD_PORT); + return 0; + } + +@@ -229,108 +232,112 @@ static int send_command(u8 cmd) + * If busy is stuck high after the command then the SMC is jammed. + */ + +-static int smc_sane(void) ++static int smc_sane(struct applesmc_device *smc) + { + int ret; + +- ret = wait_status(0, SMC_STATUS_BUSY); ++ ret = wait_status(smc, 0, SMC_STATUS_BUSY); + if (!ret) + return ret; +- ret = send_command(APPLESMC_READ_CMD); ++ ret = send_command(smc, APPLESMC_READ_CMD); + if (ret) + return ret; +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int send_argument(const char *key) ++static int send_argument(struct applesmc_device *smc, const char *key) + { + int i; + + for (i = 0; i < 4; i++) +- if (send_byte(key[i], APPLESMC_DATA_PORT)) ++ if (send_byte(smc, key[i], APPLESMC_DATA_PORT)) + return -EIO; + return 0; + } + +-static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) ++static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ u8 *buffer, u8 len) + { + u8 status, data = 0; + int i; + int ret; + +- ret = smc_sane(); ++ ret = smc_sane(smc); + if (ret) + return ret; + +- if (send_command(cmd) || send_argument(key)) { ++ if (send_command(smc, cmd) || send_argument(smc, key)) { + pr_warn("%.4s: read arg fail\n", key); + return -EIO; + } + + /* This has no effect on newer (2012) SMCs */ +- if (send_byte(len, APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (wait_status(SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, ++ if (wait_status(smc, ++ SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) { + pr_warn("%.4s: read data[%d] fail\n", key, i); + return -EIO; + } +- buffer[i] = inb(APPLESMC_DATA_PORT); ++ buffer[i] = inb(smc->port_base + APPLESMC_DATA_PORT); + } + + /* Read the data port until bit0 is cleared */ + for (i = 0; i < 16; i++) { + udelay(APPLESMC_MIN_WAIT); +- status = inb(APPLESMC_CMD_PORT); ++ status = inb(smc->port_base + APPLESMC_CMD_PORT); + if (!(status & SMC_STATUS_AWAITING_DATA)) + break; +- data = inb(APPLESMC_DATA_PORT); ++ data = inb(smc->port_base + APPLESMC_DATA_PORT); + } + if (i) + pr_warn("flushed %d bytes, last value is: %d\n", i, data); + +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len) ++static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ const u8 *buffer, u8 len) + { + int i; + int ret; + +- ret = smc_sane(); ++ ret = smc_sane(smc); + if (ret) + return ret; + +- if (send_command(cmd) || send_argument(key)) { ++ if (send_command(smc, cmd) || send_argument(smc, key)) { + pr_warn("%s: write arg fail\n", key); + return -EIO; + } + +- if (send_byte(len, APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: write len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (send_byte(buffer[i], APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { + pr_warn("%s: write data fail\n", key); + return -EIO; + } + } + +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int read_register_count(unsigned int *count) ++static int read_register_count(struct applesmc_device *smc, ++ unsigned int *count) + { + __be32 be; + int ret; + +- ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); ++ ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); + if (ret) + return ret; + +@@ -353,7 +360,7 @@ static int applesmc_read_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); ++ ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + + return ret; +@@ -367,7 +374,7 @@ static int applesmc_write_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); ++ ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + return ret; + } +@@ -388,10 +395,10 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + if (cache->valid) + goto out; + be = cpu_to_be32(index); +- ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); ++ ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); + if (ret) + goto out; +- ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); ++ ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); + if (ret) + goto out; + +@@ -589,7 +596,7 @@ static int applesmc_init_smcreg_try(struct applesmc_device *smc) + if (s->init_complete) + return 0; + +- ret = read_register_count(&count); ++ ret = read_register_count(smc, &count); + if (ret) + return ret; + +@@ -1472,7 +1479,7 @@ static int __init applesmc_init(void) + goto out; + } + +- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, ++ if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS, + "applesmc")) { + ret = -ENXIO; + goto out; +@@ -1494,7 +1501,7 @@ static int __init applesmc_init(void) + out_driver: + platform_driver_unregister(&applesmc_driver); + out_region: +- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); ++ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + out: + pr_warn("driver init failed (ret=%d)!\n", ret); + return ret; +@@ -1504,7 +1511,7 @@ static void __exit applesmc_exit(void) + { + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); +- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); ++ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + } + + module_init(applesmc_init); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3003-applesmc-switch-to-acpi_device-from-platform.patch b/patch/kernel/archive/uefi-x86-6.12/3003-applesmc-switch-to-acpi_device-from-platform.patch new file mode 100644 index 000000000..21b04a5a5 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3003-applesmc-switch-to-acpi_device-from-platform.patch @@ -0,0 +1,265 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sat, 29 Jun 2024 04:49:16 +0000 +Subject: applesmc: switch to acpi_device (from platform) + +This change makes the change from platform_device +to acpi_device. The rationale for this change is +that on T2 Macs, an additional FixedMemory32 +region is needed for device operation, and it can +be easily resolved via ACPI tables (this will be +done in another commit). + +Additionally, on older Macs, the OS X driver also +looks for the specified ACPI device to resolve +its memory regions, and therefore this change +should not result in any incompatibilities. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 124 +++++++--- + 1 file changed, 84 insertions(+), 40 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -19,7 +19,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include +-#include ++#include + #include + #include + #include +@@ -35,7 +35,6 @@ + #include + #include + +-#define APPLESMC_PORT_BASE 0x300 + /* data port used by Apple SMC */ + #define APPLESMC_DATA_PORT 0 + /* command/status port used by Apple SMC */ +@@ -138,9 +137,10 @@ struct applesmc_registers { + }; + + struct applesmc_device { +- struct platform_device *dev; ++ struct acpi_device *dev; + struct applesmc_registers reg; + ++ bool port_base_set; + u16 port_base; + + s16 rest_x; +@@ -692,9 +692,13 @@ static int applesmc_init_smcreg(struct applesmc_device *smc) + } + + /* Device model stuff */ ++ ++static int applesmc_init_resources(struct applesmc_device *smc); ++static void applesmc_free_resources(struct applesmc_device *smc); + static int applesmc_create_modules(struct applesmc_device *smc); + static void applesmc_destroy_modules(struct applesmc_device *smc); +-static int applesmc_probe(struct platform_device *dev) ++ ++static int applesmc_add(struct acpi_device *dev) + { + struct applesmc_device *smc; + int ret; +@@ -705,12 +709,16 @@ static int applesmc_probe(struct platform_device *dev) + smc->dev = dev; + mutex_init(&smc->reg.mutex); + +- platform_set_drvdata(dev, smc); ++ dev_set_drvdata(&dev->dev, smc); + +- ret = applesmc_init_smcreg(smc); ++ ret = applesmc_init_resources(smc); + if (ret) + goto out_mem; + ++ ret = applesmc_init_smcreg(smc); ++ if (ret) ++ goto out_res; ++ + applesmc_device_init(smc); + + ret = applesmc_create_modules(smc); +@@ -721,20 +729,23 @@ static int applesmc_probe(struct platform_device *dev) + + out_reg: + applesmc_destroy_smcreg(smc); ++out_res: ++ applesmc_free_resources(smc); + out_mem: +- platform_set_drvdata(dev, NULL); ++ dev_set_drvdata(&dev->dev, NULL); + mutex_destroy(&smc->reg.mutex); + kfree(smc); + + return ret; + } + +-static int applesmc_remove(struct platform_device *dev) ++static int applesmc_remove(struct acpi_device *dev) + { +- struct applesmc_device *smc = platform_get_drvdata(dev); ++ struct applesmc_device *smc = dev_get_drvdata(&dev->dev); + + applesmc_destroy_modules(smc); + applesmc_destroy_smcreg(smc); ++ applesmc_free_resources(smc); + + mutex_destroy(&smc->reg.mutex); + kfree(smc); +@@ -742,6 +753,52 @@ static int applesmc_remove(struct platform_device *dev) + return 0; + } + ++static acpi_status applesmc_walk_resources(struct acpi_resource *res, ++ void *data) ++{ ++ struct applesmc_device *smc = data; ++ ++ switch (res->type) { ++ case ACPI_RESOURCE_TYPE_IO: ++ if (!smc->port_base_set) { ++ if (res->data.io.address_length < APPLESMC_NR_PORTS) ++ return AE_ERROR; ++ smc->port_base = res->data.io.minimum; ++ smc->port_base_set = true; ++ } ++ return AE_OK; ++ ++ case ACPI_RESOURCE_TYPE_END_TAG: ++ if (smc->port_base_set) ++ return AE_OK; ++ else ++ return AE_NOT_FOUND; ++ ++ default: ++ return AE_OK; ++ } ++} ++ ++static int applesmc_init_resources(struct applesmc_device *smc) ++{ ++ int ret; ++ ++ ret = acpi_walk_resources(smc->dev->handle, METHOD_NAME__CRS, ++ applesmc_walk_resources, smc); ++ if (ACPI_FAILURE(ret)) ++ return -ENXIO; ++ ++ if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc")) ++ return -ENXIO; ++ ++ return 0; ++} ++ ++static void applesmc_free_resources(struct applesmc_device *smc) ++{ ++ release_region(smc->port_base, APPLESMC_NR_PORTS); ++} ++ + /* Synchronize device with memorized backlight state */ + static int applesmc_pm_resume(struct device *dev) + { +@@ -763,17 +820,26 @@ static int applesmc_pm_restore(struct device *dev) + return applesmc_pm_resume(dev); + } + ++static const struct acpi_device_id applesmc_ids[] = { ++ {"APP0001", 0}, ++ {"", 0}, ++}; ++ + static const struct dev_pm_ops applesmc_pm_ops = { + .resume = applesmc_pm_resume, + .restore = applesmc_pm_restore, + }; + +-static struct platform_driver applesmc_driver = { +- .probe = applesmc_probe, +- .remove = applesmc_remove, +- .driver = { +- .name = "applesmc", +- .pm = &applesmc_pm_ops, ++static struct acpi_driver applesmc_driver = { ++ .name = "applesmc", ++ .class = "applesmc", ++ .ids = applesmc_ids, ++ .ops = { ++ .add = applesmc_add, ++ .remove = applesmc_remove ++ }, ++ .drv = { ++ .pm = &applesmc_pm_ops + }, + }; + +@@ -1262,7 +1328,6 @@ static int applesmc_create_nodes(struct applesmc_device *smc, + static int applesmc_create_accelerometer(struct applesmc_device *smc) + { + int ret; +- + if (!smc->reg.has_accelerometer) + return 0; + +@@ -1467,8 +1532,6 @@ static void applesmc_destroy_modules(struct applesmc_device *smc) + applesmc_destroy_nodes(smc, info_group); + } + +-static struct platform_device *pdev; +- + static int __init applesmc_init(void) + { + int ret; +@@ -1479,29 +1542,12 @@ static int __init applesmc_init(void) + goto out; + } + +- if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS, +- "applesmc")) { +- ret = -ENXIO; +- goto out; +- } +- +- ret = platform_driver_register(&applesmc_driver); ++ ret = acpi_bus_register_driver(&applesmc_driver); + if (ret) +- goto out_region; +- +- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, +- NULL, 0); +- if (IS_ERR(pdev)) { +- ret = PTR_ERR(pdev); +- goto out_driver; +- } ++ goto out; + + return 0; + +-out_driver: +- platform_driver_unregister(&applesmc_driver); +-out_region: +- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + out: + pr_warn("driver init failed (ret=%d)!\n", ret); + return ret; +@@ -1509,9 +1555,7 @@ static int __init applesmc_init(void) + + static void __exit applesmc_exit(void) + { +- platform_device_unregister(pdev); +- platform_driver_unregister(&applesmc_driver); +- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); ++ acpi_bus_unregister_driver(&applesmc_driver); + } + + module_init(applesmc_init); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3004-applesmc-key-interface-wrappers.patch b/patch/kernel/archive/uefi-x86-6.12/3004-applesmc-key-interface-wrappers.patch new file mode 100644 index 000000000..ad7e3105f --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3004-applesmc-key-interface-wrappers.patch @@ -0,0 +1,298 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:14 +0100 +Subject: applesmc: key interface wrappers + +This change replaces the read_smc and write_smc +methods with wrappers, additionally removing the +command id parameter from them (and introducing +get_smc_key_by_index and get_smc_key_info). + +This is done as to allow simple implementation +replacement on T2 Macs. The newly introduced +methods mentioned in the previous paragraph need +special handling on T2 and as such had to be +separated. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 119 ++++++---- + 1 file changed, 79 insertions(+), 40 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -172,7 +172,7 @@ static const int debug; + * run out past 500ms. + */ + +-static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) ++static int port_wait_status(struct applesmc_device *smc, u8 val, u8 mask) + { + u8 status; + int us; +@@ -190,13 +190,13 @@ static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) + return -EIO; + } + +-/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ ++/* port_send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ + +-static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) ++static int port_send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + { + int status; + +- status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); ++ status = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (status) + return status; + /* +@@ -205,7 +205,7 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + * this extra read may not happen if status returns both + * simultaneously and this would appear to be required. + */ +- status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); ++ status = port_wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); + if (status) + return status; + +@@ -213,15 +213,16 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + return 0; + } + +-/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ ++/* port_send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ + +-static int send_command(struct applesmc_device *smc, u8 cmd) ++static int port_send_command(struct applesmc_device *smc, u8 cmd) + { + int ret; + +- ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); ++ ret = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (ret) + return ret; ++ + outb(cmd, smc->port_base + APPLESMC_CMD_PORT); + return 0; + } +@@ -232,53 +233,53 @@ static int send_command(struct applesmc_device *smc, u8 cmd) + * If busy is stuck high after the command then the SMC is jammed. + */ + +-static int smc_sane(struct applesmc_device *smc) ++static int port_smc_sane(struct applesmc_device *smc) + { + int ret; + +- ret = wait_status(smc, 0, SMC_STATUS_BUSY); ++ ret = port_wait_status(smc, 0, SMC_STATUS_BUSY); + if (!ret) + return ret; +- ret = send_command(smc, APPLESMC_READ_CMD); ++ ret = port_send_command(smc, APPLESMC_READ_CMD); + if (ret) + return ret; +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int send_argument(struct applesmc_device *smc, const char *key) ++static int port_send_argument(struct applesmc_device *smc, const char *key) + { + int i; + + for (i = 0; i < 4; i++) +- if (send_byte(smc, key[i], APPLESMC_DATA_PORT)) ++ if (port_send_byte(smc, key[i], APPLESMC_DATA_PORT)) + return -EIO; + return 0; + } + +-static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++static int port_read_smc(struct applesmc_device *smc, u8 cmd, const char *key, + u8 *buffer, u8 len) + { + u8 status, data = 0; + int i; + int ret; + +- ret = smc_sane(smc); ++ ret = port_smc_sane(smc); + if (ret) + return ret; + +- if (send_command(smc, cmd) || send_argument(smc, key)) { ++ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) { + pr_warn("%.4s: read arg fail\n", key); + return -EIO; + } + + /* This has no effect on newer (2012) SMCs */ +- if (send_byte(smc, len, APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (wait_status(smc, ++ if (port_wait_status(smc, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) { + pr_warn("%.4s: read data[%d] fail\n", key, i); +@@ -298,37 +299,80 @@ static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, + if (i) + pr_warn("flushed %d bytes, last value is: %d\n", i, data); + +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++static int port_write_smc(struct applesmc_device *smc, u8 cmd, const char *key, + const u8 *buffer, u8 len) + { + int i; + int ret; + +- ret = smc_sane(smc); ++ ret = port_smc_sane(smc); + if (ret) + return ret; + +- if (send_command(smc, cmd) || send_argument(smc, key)) { ++ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) { + pr_warn("%s: write arg fail\n", key); + return -EIO; + } + +- if (send_byte(smc, len, APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: write len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { + pr_warn("%s: write data fail\n", key); + return -EIO; + } + } + +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); ++} ++ ++static int port_get_smc_key_info(struct applesmc_device *smc, ++ const char *key, struct applesmc_entry *info) ++{ ++ int ret; ++ u8 raw[6]; ++ ++ ret = port_read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, raw, 6); ++ if (ret) ++ return ret; ++ info->len = raw[0]; ++ memcpy(info->type, &raw[1], 4); ++ info->flags = raw[5]; ++ return 0; ++} ++ ++static int read_smc(struct applesmc_device *smc, const char *key, ++ u8 *buffer, u8 len) ++{ ++ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++} ++ ++static int write_smc(struct applesmc_device *smc, const char *key, ++ const u8 *buffer, u8 len) ++{ ++ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++} ++ ++static int get_smc_key_by_index(struct applesmc_device *smc, ++ unsigned int index, char *key) ++{ ++ __be32 be; ++ ++ be = cpu_to_be32(index); ++ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); ++} ++ ++static int get_smc_key_info(struct applesmc_device *smc, const char *key, ++ struct applesmc_entry *info) ++{ ++ return port_get_smc_key_info(smc, key, info); + } + + static int read_register_count(struct applesmc_device *smc, +@@ -337,8 +381,8 @@ static int read_register_count(struct applesmc_device *smc, + __be32 be; + int ret; + +- ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); +- if (ret) ++ ret = read_smc(smc, KEY_COUNT_KEY, (u8 *)&be, 4); ++ if (ret < 0) + return ret; + + *count = be32_to_cpu(be); +@@ -360,7 +404,7 @@ static int applesmc_read_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len); ++ ret = read_smc(smc, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + + return ret; +@@ -374,7 +418,7 @@ static int applesmc_write_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len); ++ ret = write_smc(smc, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + return ret; + } +@@ -383,8 +427,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + struct applesmc_device *smc, int index) + { + struct applesmc_entry *cache = &smc->reg.cache[index]; +- u8 key[4], info[6]; +- __be32 be; ++ char key[4]; + int ret = 0; + + if (cache->valid) +@@ -394,18 +437,14 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + + if (cache->valid) + goto out; +- be = cpu_to_be32(index); +- ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); ++ ret = get_smc_key_by_index(smc, index, key); + if (ret) + goto out; +- ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); ++ memcpy(cache->key, key, 4); ++ ++ ret = get_smc_key_info(smc, key, cache); + if (ret) + goto out; +- +- memcpy(cache->key, key, 4); +- cache->len = info[0]; +- memcpy(cache->type, &info[1], 4); +- cache->flags = info[5]; + cache->valid = true; + + out: +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3005-applesmc-basic-mmio-interface-implementation.patch b/patch/kernel/archive/uefi-x86-6.12/3005-applesmc-basic-mmio-interface-implementation.patch new file mode 100644 index 000000000..230656989 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3005-applesmc-basic-mmio-interface-implementation.patch @@ -0,0 +1,343 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 17 Nov 2019 23:12:16 +0100 +Subject: applesmc: basic mmio interface implementation + +This change introduces a basic MMIO-based +interface implementation required to communicate +with the SMC on T2 Macs. The MMIO interface is +enabled only when it's supported on the running +system. + +The MMIO interface replaces legacy port-based SMC +key reads, writes and metadata requests (getting +key by index and getting key info). + +(Based on patch by @mcmrarm) + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 237 +++++++++- + 1 file changed, 231 insertions(+), 6 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -42,6 +42,18 @@ + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + ++#define APPLESMC_IOMEM_KEY_DATA 0 ++#define APPLESMC_IOMEM_KEY_STATUS 0x4005 ++#define APPLESMC_IOMEM_KEY_NAME 0x78 ++#define APPLESMC_IOMEM_KEY_DATA_LEN 0x7D ++#define APPLESMC_IOMEM_KEY_SMC_ID 0x7E ++#define APPLESMC_IOMEM_KEY_CMD 0x7F ++#define APPLESMC_IOMEM_MIN_SIZE 0x4006 ++ ++#define APPLESMC_IOMEM_KEY_TYPE_CODE 0 ++#define APPLESMC_IOMEM_KEY_TYPE_DATA_LEN 5 ++#define APPLESMC_IOMEM_KEY_TYPE_FLAGS 6 ++ + #define APPLESMC_MAX_DATA_LENGTH 32 + + /* Apple SMC status bits */ +@@ -138,10 +150,13 @@ struct applesmc_registers { + + struct applesmc_device { + struct acpi_device *dev; ++ struct device *ldev; + struct applesmc_registers reg; + +- bool port_base_set; ++ bool port_base_set, iomem_base_set; + u16 port_base; ++ u8 *__iomem iomem_base; ++ u32 iomem_base_addr, iomem_base_size; + + s16 rest_x; + s16 rest_y; +@@ -347,16 +362,156 @@ static int port_get_smc_key_info(struct applesmc_device *smc, + return 0; + } + ++ ++/* ++ * MMIO based communication. ++ * TODO: Use updated mechanism for cmd timeout/retry ++ */ ++ ++static void iomem_clear_status(struct applesmc_device *smc) ++{ ++ if (ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS)) ++ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++} ++ ++static int iomem_wait_read(struct applesmc_device *smc) ++{ ++ u8 status; ++ int us; ++ int i; ++ ++ us = APPLESMC_MIN_WAIT; ++ for (i = 0; i < 24 ; i++) { ++ status = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (status & 0x20) ++ return 0; ++ usleep_range(us, us * 2); ++ if (i > 9) ++ us <<= 1; ++ } ++ ++ dev_warn(smc->ldev, "%s... timeout\n", __func__); ++ return -EIO; ++} ++ ++static int iomem_read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ u8 *buffer, u8 len) ++{ ++ u8 err, remote_len; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "read_smc_mmio(%x %8x/%.4s) failed: %u\n", ++ cmd, key_int, key, err); ++ return -EIO; ++ } ++ ++ if (cmd == APPLESMC_READ_CMD) { ++ remote_len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ if (remote_len != len) { ++ dev_warn(smc->ldev, ++ "read_smc_mmio(%x %8x/%.4s) failed: buffer length mismatch (remote = %u, requested = %u)\n", ++ cmd, key_int, key, remote_len, len); ++ return -EINVAL; ++ } ++ } else { ++ remote_len = len; ++ } ++ ++ memcpy_fromio(buffer, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, ++ remote_len); ++ ++ dev_dbg(smc->ldev, "read_smc_mmio(%x %8x/%.4s): buflen=%u reslen=%u\n", ++ cmd, key_int, key, len, remote_len); ++ print_hex_dump_bytes("read_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, remote_len); ++ return 0; ++} ++ ++static int iomem_get_smc_key_type(struct applesmc_device *smc, const char *key, ++ struct applesmc_entry *e) ++{ ++ u8 err; ++ u8 cmd = APPLESMC_GET_KEY_TYPE_CMD; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "get_smc_key_type_mmio(%.4s) failed: %u\n", key, err); ++ return -EIO; ++ } ++ ++ e->len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_DATA_LEN); ++ *((uint32_t *) e->type) = ioread32( ++ smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_CODE); ++ e->flags = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_FLAGS); ++ ++ dev_dbg(smc->ldev, "get_smc_key_type_mmio(%.4s): len=%u type=%.4s flags=%x\n", ++ key, e->len, e->type, e->flags); ++ return 0; ++} ++ ++static int iomem_write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ const u8 *buffer, u8 len) ++{ ++ u8 err; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ memcpy_toio(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, buffer, len); ++ iowrite32(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "write_smc_mmio(%x %.4s) failed: %u\n", cmd, key, err); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return -EIO; ++ } ++ ++ dev_dbg(smc->ldev, "write_smc_mmio(%x %.4s): buflen=%u\n", cmd, key, len); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return 0; ++} ++ ++ + static int read_smc(struct applesmc_device *smc, const char *key, + u8 *buffer, u8 len) + { +- return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ else ++ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); + } + + static int write_smc(struct applesmc_device *smc, const char *key, + const u8 *buffer, u8 len) + { +- return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ else ++ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); + } + + static int get_smc_key_by_index(struct applesmc_device *smc, +@@ -365,14 +520,21 @@ static int get_smc_key_by_index(struct applesmc_device *smc, + __be32 be; + + be = cpu_to_be32(index); +- return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, +- (const char *) &be, (u8 *) key, 4); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); ++ else ++ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); + } + + static int get_smc_key_info(struct applesmc_device *smc, const char *key, + struct applesmc_entry *info) + { +- return port_get_smc_key_info(smc, key, info); ++ if (smc->iomem_base_set) ++ return iomem_get_smc_key_type(smc, key, info); ++ else ++ return port_get_smc_key_info(smc, key, info); + } + + static int read_register_count(struct applesmc_device *smc, +@@ -746,6 +908,7 @@ static int applesmc_add(struct acpi_device *dev) + if (!smc) + return -ENOMEM; + smc->dev = dev; ++ smc->ldev = &dev->dev; + mutex_init(&smc->reg.mutex); + + dev_set_drvdata(&dev->dev, smc); +@@ -807,6 +970,20 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + return AE_OK; + ++ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: ++ if (!smc->iomem_base_set) { ++ if (res->data.fixed_memory32.address_length < ++ APPLESMC_IOMEM_MIN_SIZE) { ++ dev_warn(smc->ldev, "found iomem but it's too small: %u\n", ++ res->data.fixed_memory32.address_length); ++ return AE_OK; ++ } ++ smc->iomem_base_addr = res->data.fixed_memory32.address; ++ smc->iomem_base_size = res->data.fixed_memory32.address_length; ++ smc->iomem_base_set = true; ++ } ++ return AE_OK; ++ + case ACPI_RESOURCE_TYPE_END_TAG: + if (smc->port_base_set) + return AE_OK; +@@ -818,6 +995,8 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc); ++ + static int applesmc_init_resources(struct applesmc_device *smc) + { + int ret; +@@ -830,11 +1009,57 @@ static int applesmc_init_resources(struct applesmc_device *smc) + if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc")) + return -ENXIO; + ++ if (smc->iomem_base_set) { ++ if (applesmc_try_enable_iomem(smc)) ++ smc->iomem_base_set = false; ++ } ++ + return 0; + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc) ++{ ++ u8 test_val, ldkn_version; ++ ++ dev_dbg(smc->ldev, "Trying to enable iomem based communication\n"); ++ smc->iomem_base = ioremap(smc->iomem_base_addr, smc->iomem_base_size); ++ if (!smc->iomem_base) ++ goto out; ++ ++ /* Apple's driver does this check for some reason */ ++ test_val = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (test_val == 0xff) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: initial status is 0xff (is %x)\n", ++ test_val); ++ goto out_iomem; ++ } ++ ++ if (read_smc(smc, "LDKN", &ldkn_version, 1)) { ++ dev_warn(smc->ldev, "iomem enable failed: ldkn read failed\n"); ++ goto out_iomem; ++ } ++ ++ if (ldkn_version < 2) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: ldkn version %u is less than minimum (2)\n", ++ ldkn_version); ++ goto out_iomem; ++ } ++ ++ return 0; ++ ++out_iomem: ++ iounmap(smc->iomem_base); ++ ++out: ++ return -ENXIO; ++} ++ + static void applesmc_free_resources(struct applesmc_device *smc) + { ++ if (smc->iomem_base_set) ++ iounmap(smc->iomem_base); + release_region(smc->port_base, APPLESMC_NR_PORTS); + } + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3006-applesmc-fan-support-on-T2-Macs.patch b/patch/kernel/archive/uefi-x86-6.12/3006-applesmc-fan-support-on-T2-Macs.patch new file mode 100644 index 000000000..4d2cbb318 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3006-applesmc-fan-support-on-T2-Macs.patch @@ -0,0 +1,227 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:18 +0100 +Subject: applesmc: fan support on T2 Macs + +T2 Macs changed the fan values from shorts to +floats, and changed the fan manual override +setting from a bitmask to a per-fan boolean +named F0Md (thanks to @kleuter for mentioning +it). + +A minimal soft-float implementation has been +written for convert floats to integers (and vice +versa). + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 119 ++++++++-- + 1 file changed, 102 insertions(+), 17 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -87,6 +87,7 @@ + #define FAN_ID_FMT "F%dID" /* r-o char[16] */ + + #define TEMP_SENSOR_TYPE "sp78" ++#define FLOAT_TYPE "flt " + + /* List of keys used to read/write fan speeds */ + static const char *const fan_speed_fmt[] = { +@@ -96,6 +97,7 @@ static const char *const fan_speed_fmt[] = { + "F%dSf", /* safe speed - not all models */ + "F%dTg", /* target speed (manual: rw) */ + }; ++#define FAN_MANUAL_FMT "F%dMd" + + #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ + #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ +@@ -734,6 +736,42 @@ static int applesmc_read_s16(struct applesmc_device *smc, + return 0; + } + ++/** ++ * applesmc_float_to_u32 - Retrieve the integral part of a float. ++ * This is needed because Apple made fans use float values in the T2. ++ * The fractional point is not significantly useful though, and the integral ++ * part can be easily extracted. ++ */ ++static inline u32 applesmc_float_to_u32(u32 d) ++{ ++ u8 sign = (u8) ((d >> 31) & 1); ++ s32 exp = (s32) ((d >> 23) & 0xff) - 0x7f; ++ u32 fr = d & ((1u << 23) - 1); ++ ++ if (sign || exp < 0) ++ return 0; ++ ++ return (u32) ((1u << exp) + (fr >> (23 - exp))); ++} ++ ++/** ++ * applesmc_u32_to_float - Convert an u32 into a float. ++ * See applesmc_float_to_u32 for a rationale. ++ */ ++static inline u32 applesmc_u32_to_float(u32 d) ++{ ++ u32 dc = d, bc = 0, exp; ++ ++ if (!d) ++ return 0; ++ ++ while (dc >>= 1) ++ ++bc; ++ exp = 0x7f + bc; ++ ++ return (u32) ((exp << 23) | ++ ((d << (23 - (exp - 0x7f))) & ((1u << 23) - 1))); ++} + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +@@ -1241,6 +1279,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -1249,11 +1288,21 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ ret = applesmc_read_entry(smc, entry, (u8 *) &speed, 4); ++ speed = applesmc_float_to_u32(speed); ++ } else { ++ ret = applesmc_read_entry(smc, entry, buffer, 2); ++ speed = ((buffer[0] << 8 | buffer[1]) >> 2); ++ } ++ + if (ret) + return ret; + +- speed = ((buffer[0] << 8 | buffer[1]) >> 2); + return sysfs_emit(sysfsbuf, "%u\n", speed); + } + +@@ -1262,6 +1311,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + const char *sysfsbuf, size_t count) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned long speed; + char newkey[5]; +@@ -1273,9 +1323,18 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- buffer[0] = (speed >> 6) & 0xff; +- buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ speed = applesmc_u32_to_float(speed); ++ ret = applesmc_write_entry(smc, entry, (u8 *) &speed, 4); ++ } else { ++ buffer[0] = (speed >> 6) & 0xff; ++ buffer[1] = (speed << 2) & 0xff; ++ ret = applesmc_write_key(smc, newkey, buffer, 2); ++ } + + if (ret) + return ret; +@@ -1290,12 +1349,26 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, + int ret; + u16 manual = 0; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; ++ ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); ++ if (ret) ++ return ret; ++ ++ if (has_newkey) { ++ ret = applesmc_read_key(smc, newkey, buffer, 1); ++ manual = buffer[0]; ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; ++ } + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +- manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + return sysfs_emit(sysfsbuf, "%d\n", manual); + } + +@@ -1306,27 +1379,39 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; + unsigned long input; + u16 val; + + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); + if (ret) +- goto out; ++ return ret; + +- val = (buffer[0] << 8 | buffer[1]); ++ if (has_newkey) { ++ buffer[0] = input & 1; ++ ret = applesmc_write_key(smc, newkey, buffer, 1); ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ val = (buffer[0] << 8 | buffer[1]); ++ if (ret) ++ goto out; + +- if (input) +- val = val | (0x01 << to_index(attr)); +- else +- val = val & ~(0x01 << to_index(attr)); ++ if (input) ++ val = val | (0x01 << to_index(attr)); ++ else ++ val = val & ~(0x01 << to_index(attr)); + +- buffer[0] = (val >> 8) & 0xFF; +- buffer[1] = val & 0xFF; ++ buffer[0] = (val >> 8) & 0xFF; ++ buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ } + + out: + if (ret) +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch b/patch/kernel/archive/uefi-x86-6.12/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch new file mode 100644 index 000000000..ea124754f --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Sun, 9 Oct 2022 15:59:01 +0530 +Subject: applesmc: Add iMacPro to applesmc_whitelist + +The iMacPro1,1 is the only iMacPro released before the line was +discontinued. Add it to the applesmc_whitelist. + +Signed-off-by: Orlando Chamberlain +--- + drivers/hwmon/applesmc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1803,6 +1803,10 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") }, + }, ++ { applesmc_dmi_match, "Apple iMacPro", { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "iMacPro") }, ++ }, + { applesmc_dmi_match, "Apple MacPro", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3008-applesmc-make-applesmc_remove-void.patch b/patch/kernel/archive/uefi-x86-6.12/3008-applesmc-make-applesmc_remove-void.patch new file mode 100644 index 000000000..6ad7f1422 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3008-applesmc-make-applesmc_remove-void.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Tue, 24 Jan 2023 15:46:48 +1100 +Subject: applesmc: make applesmc_remove void + +for linux6.2 compatibility +--- + drivers/hwmon/applesmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -979,7 +979,7 @@ static int applesmc_add(struct acpi_device *dev) + return ret; + } + +-static int applesmc_remove(struct acpi_device *dev) ++static void applesmc_remove(struct acpi_device *dev) + { + struct applesmc_device *smc = dev_get_drvdata(&dev->dev); + +@@ -990,7 +990,7 @@ static int applesmc_remove(struct acpi_device *dev) + mutex_destroy(&smc->reg.mutex); + kfree(smc); + +- return 0; ++ return; + } + + static acpi_status applesmc_walk_resources(struct acpi_resource *res, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/3009-applesmc-battery-charge-limiter.patch b/patch/kernel/archive/uefi-x86-6.12/3009-applesmc-battery-charge-limiter.patch new file mode 100644 index 000000000..d485b1ca2 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/3009-applesmc-battery-charge-limiter.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Mon, 30 Jan 2023 18:42:21 +1100 +Subject: applesmc: battery charge limiter + +--- + drivers/hwmon/applesmc.c | 42 +++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1477,6 +1477,35 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, + dev_dbg(led_cdev->dev, "work was already on the queue.\n"); + } + ++static ssize_t applesmc_BCLM_store(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf, size_t count) ++{ ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ u8 val; ++ ++ if (kstrtou8(sysfsbuf, 10, &val) < 0) ++ return -EINVAL; ++ ++ if (val < 0 || val > 100) ++ return -EINVAL; ++ ++ if (applesmc_write_key(smc, "BCLM", &val, 1)) ++ return -ENODEV; ++ return count; ++} ++ ++static ssize_t applesmc_BCLM_show(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ u8 val; ++ ++ if (applesmc_read_key(smc, "BCLM", &val, 1)) ++ return -ENODEV; ++ ++ return sysfs_emit(sysfsbuf, "%d\n", val); ++} ++ + static ssize_t applesmc_key_count_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +@@ -1611,6 +1640,11 @@ static struct applesmc_node_group temp_group[] = { + { } + }; + ++static struct applesmc_node_group BCLM_group[] = { ++ { "battery_charge_limit", applesmc_BCLM_show, applesmc_BCLM_store }, ++ { } ++}; ++ + /* Module stuff */ + + /* +@@ -1829,10 +1863,13 @@ static int applesmc_create_modules(struct applesmc_device *smc) + ret = applesmc_create_nodes(smc, info_group, 1); + if (ret) + goto out; ++ ret = applesmc_create_nodes(smc, BCLM_group, 1); ++ if (ret) ++ goto out_info; + + ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count); + if (ret) +- goto out_info; ++ goto out_bclm; + + ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count); + if (ret) +@@ -1868,6 +1905,8 @@ static int applesmc_create_modules(struct applesmc_device *smc) + applesmc_destroy_nodes(smc, temp_group); + out_fans: + applesmc_destroy_nodes(smc, fan_group); ++out_bclm: ++ applesmc_destroy_nodes(smc, BCLM_group); + out_info: + applesmc_destroy_nodes(smc, info_group); + out: +@@ -1882,6 +1921,7 @@ static void applesmc_destroy_modules(struct applesmc_device *smc) + applesmc_release_accelerometer(smc); + applesmc_destroy_nodes(smc, temp_group); + applesmc_destroy_nodes(smc, fan_group); ++ applesmc_destroy_nodes(smc, BCLM_group); + applesmc_destroy_nodes(smc, info_group); + } + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4001-asahi-trackpad.patch b/patch/kernel/archive/uefi-x86-6.12/4001-asahi-trackpad.patch new file mode 100644 index 000000000..e56347e1b --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4001-asahi-trackpad.patch @@ -0,0 +1,5547 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Asahi Lina +Date: Sun, 2 Feb 2025 22:48:47 +0900 +Subject: soc: apple: rtkit: Pass the crashlog to the crashed() callback + +Client drivers might want a copy of the crashlog to stash into a +devcoredump blob. Since device memory management can be very variable, +the actual devcoredump implementation is left to client drivers. Pass +the raw crashlog buffer to the client callback so it can use it if +desired. + +Signed-off-by: Asahi Lina +Reviewed-by: Jens Axboe +Reviewed-by: Sven Peter +--- + drivers/nvme/host/apple.c | 2 +- + drivers/soc/apple/rtkit.c | 2 +- + include/linux/soc/apple/rtkit.h | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c +index 111111111111..222222222222 100644 +--- a/drivers/nvme/host/apple.c ++++ b/drivers/nvme/host/apple.c +@@ -221,7 +221,7 @@ static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q) + return APPLE_ANS_MAX_QUEUE_DEPTH; + } + +-static void apple_nvme_rtkit_crashed(void *cookie) ++static void apple_nvme_rtkit_crashed(void *cookie, const void *crashlog, size_t crashlog_size) + { + struct apple_nvme *anv = cookie; + +diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/rtkit.c ++++ b/drivers/soc/apple/rtkit.c +@@ -385,7 +385,7 @@ static void apple_rtkit_crashlog_rx(struct apple_rtkit *rtk, u64 msg) + + rtk->crashed = true; + if (rtk->ops->crashed) +- rtk->ops->crashed(rtk->cookie); ++ rtk->ops->crashed(rtk->cookie, bfr, rtk->crashlog_buffer.size); + } + + static void apple_rtkit_ioreport_rx(struct apple_rtkit *rtk, u64 msg) +diff --git a/include/linux/soc/apple/rtkit.h b/include/linux/soc/apple/rtkit.h +index 111111111111..222222222222 100644 +--- a/include/linux/soc/apple/rtkit.h ++++ b/include/linux/soc/apple/rtkit.h +@@ -56,7 +56,7 @@ struct apple_rtkit_shmem { + * context. + */ + struct apple_rtkit_ops { +- void (*crashed)(void *cookie); ++ void (*crashed)(void *cookie, const void *crashlog, size_t crashlog_size); + void (*recv_message)(void *cookie, u8 endpoint, u64 message); + bool (*recv_message_early)(void *cookie, u8 endpoint, u64 message); + int (*shmem_setup)(void *cookie, struct apple_rtkit_shmem *bfr); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 12 Dec 2021 20:40:04 +0100 +Subject: HID: add device IDs for Apple SPI HID devices + +Apple Silicon based laptop use SPI as transport for HID. Add support for +SPI-based HID devices and and Apple keyboard and trackpad devices. +Intel based laptops using the keyboard input driver applespi use the +same HID over SPI protocol and can be supported later. + +This requires SPI keyboard/mouse HID types since Apple's intenal +keyboards/trackpads use the same product id. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-core.c | 3 +++ + drivers/hid/hid-ids.h | 5 +++++ + include/linux/hid.h | 6 +++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2292,6 +2292,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) + case BUS_I2C: + bus = "I2C"; + break; ++ case BUS_SPI: ++ bus = "SPI"; ++ break; + case BUS_VIRTUAL: + bus = "VIRTUAL"; + break; +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -93,6 +93,7 @@ + + #define USB_VENDOR_ID_APPLE 0x05ac + #define BT_VENDOR_ID_APPLE 0x004c ++#define SPI_VENDOR_ID_APPLE 0x05ac + #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 + #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d + #define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269 +@@ -193,6 +194,10 @@ + #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f + #define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102 + #define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_AIR_2020 0x0281 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020 0x0341 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021 0x0342 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021 0x0343 + + #define USB_VENDOR_ID_ASETEK 0x2433 + #define USB_DEVICE_ID_ASETEK_INVICTA 0xf300 +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 111111111111..222222222222 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -590,7 +590,9 @@ struct hid_input { + enum hid_type { + HID_TYPE_OTHER = 0, + HID_TYPE_USBMOUSE, +- HID_TYPE_USBNONE ++ HID_TYPE_USBNONE, ++ HID_TYPE_SPI_KEYBOARD, ++ HID_TYPE_SPI_MOUSE, + }; + + enum hid_battery_status { +@@ -749,6 +751,8 @@ struct hid_descriptor { + .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod) + #define HID_I2C_DEVICE(ven, prod) \ + .bus = BUS_I2C, .vendor = (ven), .product = (prod) ++#define HID_SPI_DEVICE(ven, prod) \ ++ .bus = BUS_SPI, .vendor = (ven), .product = (prod) + + #define HID_REPORT_ID(rep) \ + .report_type = (rep) +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 21:15:31 +0100 +Subject: HID: apple: add support for internal keyboards + +Apple MacBook keyboards started using HID over SPI in 2015. With the +addition of the SPI HID transport they can be supported by this driver. +Support all product ids over with the Apple SPI vendor id for now. +Individual product ids will have to be added for a correct Fn/function +key mapping. + +Enable by default on the Apple Arm platform. + +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 2 +- + drivers/hid/hid-apple.c | 6 ++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -129,7 +129,7 @@ config HID_APPLE + tristate "Apple {i,Power,Mac}Books" + depends on LEDS_CLASS + depends on NEW_LEDS +- default !EXPERT ++ default !EXPERT || SPI_HID_APPLE + help + Support for some Apple devices which less or more break + HID specification. +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -911,6 +911,10 @@ static int apple_probe(struct hid_device *hdev, + struct apple_sc *asc; + int ret; + ++ if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ hdev->type != HID_TYPE_SPI_KEYBOARD) ++ return -ENODEV; ++ + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); + if (asc == NULL) { + hid_err(hdev, "can't alloc apple descriptor\n"); +@@ -1175,6 +1179,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), + .driver_data = APPLE_MAGIC_BACKLIGHT }, + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 19 Dec 2021 18:08:15 +0100 +Subject: HID: apple: add Fn key mapping for Apple silicon MacBooks + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-apple.c | 25 ++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -276,6 +276,28 @@ static const struct apple_key_translation apple_fn_keys[] = { + { } + }; + ++static const struct apple_key_translation apple_fn_keys_spi[] = { ++ { KEY_BACKSPACE, KEY_DELETE }, ++ { KEY_ENTER, KEY_INSERT }, ++ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, ++ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, ++ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, ++ { KEY_F4, KEY_SEARCH, APPLE_FLAG_FKEY }, ++ { KEY_F5, KEY_RECORD, APPLE_FLAG_FKEY }, ++ { KEY_F6, KEY_SLEEP, APPLE_FLAG_FKEY }, ++ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, ++ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, ++ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, ++ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, ++ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, ++ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, ++ { KEY_UP, KEY_PAGEUP }, ++ { KEY_DOWN, KEY_PAGEDOWN }, ++ { KEY_LEFT, KEY_HOME }, ++ { KEY_RIGHT, KEY_END }, ++ { } ++}; ++ + static const struct apple_key_translation powerbook_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, +@@ -498,6 +520,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table = macbookair_fn_keys; ++ else if (hid->vendor == SPI_VENDOR_ID_APPLE) ++ table = apple_fn_keys_spi; + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; + else +@@ -677,6 +701,7 @@ static void apple_setup_input(struct input_dev *input) + + /* Enable all needed keys */ + apple_setup_key_translation(input, apple_fn_keys); ++ apple_setup_key_translation(input, apple_fn_keys_spi); + apple_setup_key_translation(input, powerbook_fn_keys); + apple_setup_key_translation(input, powerbook_numlock_keys); + apple_setup_key_translation(input, apple_iso_keyboard); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Wed, 5 Jan 2022 23:27:34 +0100 +Subject: HID: apple: add Fn key mapping for Macbook Pro with touchbar + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-apple.c | 26 ++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -298,6 +298,28 @@ static const struct apple_key_translation apple_fn_keys_spi[] = { + { } + }; + ++static const struct apple_key_translation apple_fn_keys_mbp13[] = { ++ { KEY_BACKSPACE, KEY_DELETE }, ++ { KEY_ENTER, KEY_INSERT }, ++ { KEY_UP, KEY_PAGEUP }, ++ { KEY_DOWN, KEY_PAGEDOWN }, ++ { KEY_LEFT, KEY_HOME }, ++ { KEY_RIGHT, KEY_END }, ++ { KEY_1, KEY_F1 }, ++ { KEY_2, KEY_F2 }, ++ { KEY_3, KEY_F3 }, ++ { KEY_4, KEY_F4 }, ++ { KEY_5, KEY_F5 }, ++ { KEY_6, KEY_F6 }, ++ { KEY_7, KEY_F7 }, ++ { KEY_8, KEY_F8 }, ++ { KEY_9, KEY_F9 }, ++ { KEY_0, KEY_F10 }, ++ { KEY_MINUS, KEY_F11 }, ++ { KEY_EQUAL, KEY_F12 }, ++ { } ++}; ++ + static const struct apple_key_translation powerbook_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, +@@ -520,6 +542,9 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table = macbookair_fn_keys; ++ else if (hid->vendor == SPI_VENDOR_ID_APPLE && ++ hid->product == SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020) ++ table = apple_fn_keys_mbp13; + else if (hid->vendor == SPI_VENDOR_ID_APPLE) + table = apple_fn_keys_spi; + else if (hid->product < 0x21d || hid->product >= 0x300) +@@ -702,6 +727,7 @@ static void apple_setup_input(struct input_dev *input) + /* Enable all needed keys */ + apple_setup_key_translation(input, apple_fn_keys); + apple_setup_key_translation(input, apple_fn_keys_spi); ++ apple_setup_key_translation(input, apple_fn_keys_mbp13); + apple_setup_key_translation(input, powerbook_fn_keys); + apple_setup_key_translation(input, powerbook_numlock_keys); + apple_setup_key_translation(input, apple_iso_keyboard); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:10:51 +0100 +Subject: HID: magicmouse: use a define of the max number of touch contacts + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -61,6 +61,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define DOUBLE_REPORT_ID 0xf7 + #define USB_BATTERY_TIMEOUT_MS 60000 + ++#define MAX_CONTACTS 16 ++ + /* These definitions are not precise, but they're close enough. (Bits + * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem + * to be some kind of bit mask -- 0x20 may be a near-field reading, +@@ -142,8 +144,8 @@ struct magicmouse_sc { + u8 size; + bool scroll_x_active; + bool scroll_y_active; +- } touches[16]; +- int tracking_ids[16]; ++ } touches[MAX_CONTACTS]; ++ int tracking_ids[MAX_CONTACTS]; + + struct hid_device *hdev; + struct delayed_work work; +@@ -606,7 +608,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd + + __set_bit(EV_ABS, input->evbit); + +- error = input_mt_init_slots(input, 16, mt_flags); ++ error = input_mt_init_slots(input, MAX_CONTACTS, mt_flags); + if (error) + return error; + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:12:35 +0100 +Subject: HID: magicmouse: use struct input_mt_pos for X/Y + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -120,6 +120,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + * @ntouches: Number of touches in most recent touch report. + * @scroll_accel: Number of consecutive scroll motions. + * @scroll_jiffies: Time of last scroll motion. ++ * @pos: multi touch position data of the last report. + * @touches: Most recent data for a touch, indexed by tracking ID. + * @tracking_ids: Mapping of current touch input data to @touches. + * @hdev: Pointer to the underlying HID device. +@@ -134,9 +135,8 @@ struct magicmouse_sc { + int scroll_accel; + unsigned long scroll_jiffies; + ++ struct input_mt_pos pos[MAX_CONTACTS]; + struct { +- short x; +- short y; + short scroll_x; + short scroll_y; + short scroll_x_hr; +@@ -193,7 +193,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) + } else if (last_state != 0) { + state = last_state; + } else if ((id = magicmouse_firm_touch(msc)) >= 0) { +- int x = msc->touches[id].x; ++ int x = msc->pos[id].x; + if (x < middle_button_start) + state = 1; + else if (x > middle_button_stop) +@@ -256,8 +256,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda + + /* Store tracking ID and other fields. */ + msc->tracking_ids[raw_id] = id; +- msc->touches[id].x = x; +- msc->touches[id].y = y; ++ msc->pos[id].x = x; ++ msc->pos[id].y = y; + msc->touches[id].size = size; + + /* If requested, emulate a scroll wheel by detecting small +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:15:30 +0100 +Subject: HID: magicmouse: use ops function pointers for input functionality + +Will be used for supporting MacBook trackpads connected via SPI. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 32 +++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -113,6 +113,13 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++ ++struct magicmouse_input_ops { ++ int (*raw_event)(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size); ++ int (*setup_input)(struct input_dev *input, struct hid_device *hdev); ++}; ++ + /** + * struct magicmouse_sc - Tracks Magic Mouse-specific data. + * @input: Input device through which we report events. +@@ -126,6 +133,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + * @hdev: Pointer to the underlying HID device. + * @work: Workqueue to handle initialization retry for quirky devices. + * @battery_timer: Timer for obtaining battery level information. ++ * @input_ops: Input ops based on device type. + */ + struct magicmouse_sc { + struct input_dev *input; +@@ -150,6 +158,7 @@ struct magicmouse_sc { + struct hid_device *hdev; + struct delayed_work work; + struct timer_list battery_timer; ++ struct magicmouse_input_ops input_ops; + }; + + static int magicmouse_firm_touch(struct magicmouse_sc *msc) +@@ -386,6 +395,14 @@ static int magicmouse_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { + struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ ++ return msc->input_ops.raw_event(hdev, report, data, size); ++} ++ ++static int magicmouse_raw_event_usb(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + struct input_dev *input = msc->input; + int x = 0, y = 0, ii, clicks = 0, npoints; + +@@ -533,7 +550,17 @@ static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + return 0; + } + +-static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) ++ ++static int magicmouse_setup_input(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ ++ return msc->input_ops.setup_input(input, hdev); ++} ++ ++static int magicmouse_setup_input_usb(struct input_dev *input, ++ struct hid_device *hdev) + { + int error; + int mt_flags = 0; +@@ -843,6 +870,9 @@ static int magicmouse_probe(struct hid_device *hdev, + return -ENOMEM; + } + ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; + msc->hdev = hdev; + INIT_DEFERRABLE_WORK(&msc->work, magicmouse_enable_mt_work); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 01:17:48 +0100 +Subject: HID: magicmouse: add support for Macbook trackpads + +The trackpads in Macbooks beginning in 2015 are HID devices connected +over SPI. On Intel Macbooks they are currently supported by applespi.c. +This chang adds support for the trackpads on Apple Silicon Macbooks +starting in late 2020. They use a new HID over SPI transport driver. +The touch report format differs from USB/BT Magic Trackpads. It is the +same format as the type 4 format supported by bcm5974.c. + +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 4 +- + drivers/hid/hid-magicmouse.c | 259 +++++++++- + 2 files changed, 260 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -700,11 +700,13 @@ config LOGIWHEELS_FF + + config HID_MAGICMOUSE + tristate "Apple Magic Mouse/Trackpad multi-touch support" ++ default SPI_HID_APPLE + help + Support for the Apple Magic Mouse/Trackpad multi-touch. + + Say Y here if you want support for the multi-touch features of the +- Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. ++ Apple Wireless "Magic" Mouse, the Apple Wireless "Magic" Trackpad and ++ force touch Trackpads in Macbooks starting from 2015. + + config HID_MALTRON + tristate "Maltron L90 keyboard" +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -113,6 +113,18 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++#define J314_TP_DIMENSION_X (float)13000 ++#define J314_TP_MIN_X -5900 ++#define J314_TP_MAX_X 6500 ++#define J314_TP_RES_X \ ++ ((J314_TP_MAX_X - J314_TP_MIN_X) / (J314_TP_DIMENSION_X / 100)) ++#define J314_TP_DIMENSION_Y (float)8100 ++#define J314_TP_MIN_Y -200 ++#define J314_TP_MAX_Y 7400 ++#define J314_TP_RES_Y \ ++ ((J314_TP_MAX_Y - J314_TP_MIN_Y) / (J314_TP_DIMENSION_Y / 100)) ++ ++#define J314_TP_MAX_FINGER_ORIENTATION 16384 + + struct magicmouse_input_ops { + int (*raw_event)(struct hid_device *hdev, +@@ -533,6 +545,157 @@ static int magicmouse_raw_event_usb(struct hid_device *hdev, + return 1; + } + ++/** ++ * struct tp_finger - single trackpad finger structure, le16-aligned ++ * ++ * @unknown1: unknown ++ * @unknown2: unknown ++ * @abs_x: absolute x coordinate ++ * @abs_y: absolute y coordinate ++ * @rel_x: relative x coordinate ++ * @rel_y: relative y coordinate ++ * @tool_major: tool area, major axis ++ * @tool_minor: tool area, minor axis ++ * @orientation: 16384 when point, else 15 bit angle ++ * @touch_major: touch area, major axis ++ * @touch_minor: touch area, minor axis ++ * @unused: zeros ++ * @pressure: pressure on forcetouch touchpad ++ * @multi: one finger: varies, more fingers: constant ++ * @crc16: on last finger: crc over the whole message struct ++ * (i.e. message header + this struct) minus the last ++ * @crc16 field; unknown on all other fingers. ++ */ ++struct tp_finger { ++ __le16 unknown1; ++ __le16 unknown2; ++ __le16 abs_x; ++ __le16 abs_y; ++ __le16 rel_x; ++ __le16 rel_y; ++ __le16 tool_major; ++ __le16 tool_minor; ++ __le16 orientation; ++ __le16 touch_major; ++ __le16 touch_minor; ++ __le16 unused[2]; ++ __le16 pressure; ++ __le16 multi; ++} __attribute__((packed, aligned(2))); ++ ++/** ++ * struct trackpad report ++ * ++ * @report_id: reportid ++ * @buttons: HID Usage Buttons 3 1-bit reports ++ * @num_fingers: the number of fingers being reported in @fingers ++ * @clicked: same as @buttons ++ */ ++struct tp_header { ++ // HID mouse report ++ u8 report_id; ++ u8 buttons; ++ u8 rel_x; ++ u8 rel_y; ++ u8 padding[4]; ++ // HID vendor part, up to 1751 bytes ++ u8 unknown[22]; ++ u8 num_fingers; ++ u8 clicked; ++ u8 unknown3[14]; ++}; ++ ++static inline int le16_to_int(__le16 x) ++{ ++ return (signed short)le16_to_cpu(x); ++} ++ ++static void report_finger_data(struct input_dev *input, int slot, ++ const struct input_mt_pos *pos, ++ const struct tp_finger *f) ++{ ++ input_mt_slot(input, slot); ++ input_mt_report_slot_state(input, MT_TOOL_FINGER, true); ++ ++ input_report_abs(input, ABS_MT_TOUCH_MAJOR, ++ le16_to_int(f->touch_major) << 1); ++ input_report_abs(input, ABS_MT_TOUCH_MINOR, ++ le16_to_int(f->touch_minor) << 1); ++ input_report_abs(input, ABS_MT_WIDTH_MAJOR, ++ le16_to_int(f->tool_major) << 1); ++ input_report_abs(input, ABS_MT_WIDTH_MINOR, ++ le16_to_int(f->tool_minor) << 1); ++ input_report_abs(input, ABS_MT_ORIENTATION, ++ J314_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); ++ input_report_abs(input, ABS_MT_PRESSURE, le16_to_int(f->pressure)); ++ input_report_abs(input, ABS_MT_POSITION_X, pos->x); ++ input_report_abs(input, ABS_MT_POSITION_Y, pos->y); ++} ++ ++static int magicmouse_raw_event_spi(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ struct input_dev *input = msc->input; ++ struct tp_header *tp_hdr; ++ struct tp_finger *f; ++ int i, n; ++ u32 npoints; ++ const size_t hdr_sz = sizeof(struct tp_header); ++ const size_t touch_sz = sizeof(struct tp_finger); ++ u8 map_contacs[MAX_CONTACTS]; ++ ++ // hid_warn(hdev, "%s\n", __func__); ++ // print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data, ++ // size, false); ++ ++ if (data[0] != TRACKPAD2_USB_REPORT_ID) ++ return 0; ++ ++ /* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */ ++ if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0) ++ return 0; ++ ++ tp_hdr = (struct tp_header *)data; ++ ++ npoints = (size - hdr_sz) / touch_sz; ++ if (npoints < tp_hdr->num_fingers || npoints > MAX_CONTACTS) { ++ hid_warn(hdev, ++ "unexpected number of touches (%u) for " ++ "report\n", ++ npoints); ++ return 0; ++ } ++ ++ n = 0; ++ for (i = 0; i < tp_hdr->num_fingers; i++) { ++ f = (struct tp_finger *)(data + hdr_sz + i * touch_sz); ++ if (le16_to_int(f->touch_major) == 0) ++ continue; ++ ++ hid_dbg(hdev, "ev x:%04x y:%04x\n", le16_to_int(f->abs_x), ++ le16_to_int(f->abs_y)); ++ msc->pos[n].x = le16_to_int(f->abs_x); ++ msc->pos[n].y = -le16_to_int(f->abs_y); ++ map_contacs[n] = i; ++ n++; ++ } ++ ++ input_mt_assign_slots(input, msc->tracking_ids, msc->pos, n, 0); ++ ++ for (i = 0; i < n; i++) { ++ int idx = map_contacs[i]; ++ f = (struct tp_finger *)(data + hdr_sz + idx * touch_sz); ++ report_finger_data(input, msc->tracking_ids[i], &msc->pos[i], f); ++ } ++ ++ input_mt_sync_frame(input); ++ input_report_key(input, BTN_MOUSE, data[1] & 1); ++ ++ input_sync(input); ++ return 1; ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -717,6 +880,79 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + return 0; + } + ++static int magicmouse_setup_input_spi(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int error; ++ int mt_flags = 0; ++ ++ __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); ++ __clear_bit(BTN_0, input->keybit); ++ __clear_bit(BTN_RIGHT, input->keybit); ++ __clear_bit(BTN_MIDDLE, input->keybit); ++ __clear_bit(EV_REL, input->evbit); ++ __clear_bit(REL_X, input->relbit); ++ __clear_bit(REL_Y, input->relbit); ++ ++ mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK; ++ ++ /* finger touch area */ ++ input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 5000, 0, 0); ++ input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 5000, 0, 0); ++ ++ /* finger approach area */ ++ input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 5000, 0, 0); ++ input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 5000, 0, 0); ++ ++ /* Note: Touch Y position from the device is inverted relative ++ * to how pointer motion is reported (and relative to how USB ++ * HID recommends the coordinates work). This driver keeps ++ * the origin at the same position, and just uses the additive ++ * inverse of the reported Y. ++ */ ++ ++ input_set_abs_params(input, ABS_MT_PRESSURE, 0, 6000, 0, 0); ++ ++ /* ++ * This makes libinput recognize this as a PressurePad and ++ * stop trying to use pressure for touch size. Pressure unit ++ * seems to be ~grams on these touchpads. ++ */ ++ input_abs_set_res(input, ABS_MT_PRESSURE, 1); ++ ++ /* finger orientation */ ++ input_set_abs_params(input, ABS_MT_ORIENTATION, -J314_TP_MAX_FINGER_ORIENTATION, ++ J314_TP_MAX_FINGER_ORIENTATION, 0, 0); ++ ++ /* finger position */ ++ input_set_abs_params(input, ABS_MT_POSITION_X, J314_TP_MIN_X, J314_TP_MAX_X, ++ 0, 0); ++ /* Y axis is inverted */ ++ input_set_abs_params(input, ABS_MT_POSITION_Y, -J314_TP_MAX_Y, -J314_TP_MIN_Y, ++ 0, 0); ++ ++ /* X/Y resolution */ ++ input_abs_set_res(input, ABS_MT_POSITION_X, J314_TP_RES_X); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, J314_TP_RES_Y); ++ ++ input_set_events_per_packet(input, 60); ++ ++ /* touchpad button */ ++ input_set_capability(input, EV_KEY, BTN_MOUSE); ++ ++ /* ++ * hid-input may mark device as using autorepeat, but the trackpad does ++ * not actually want it. ++ */ ++ __clear_bit(EV_REP, input->evbit); ++ ++ error = input_mt_init_slots(input, MAX_CONTACTS, mt_flags); ++ if (error) ++ return error; ++ ++ return 0; ++} ++ + static int magicmouse_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +@@ -775,6 +1011,9 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + feature_size = sizeof(feature_mt_trackpad2_usb); + feature = feature_mt_trackpad2_usb; + } ++ } else if (hdev->vendor == SPI_VENDOR_ID_APPLE) { ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; + } else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { + feature_size = sizeof(feature_mt_mouse2); + feature = feature_mt_mouse2; +@@ -864,14 +1103,26 @@ static int magicmouse_probe(struct hid_device *hdev, + struct hid_report *report; + int ret; + ++ if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ hdev->type != HID_TYPE_SPI_MOUSE) ++ return -ENODEV; ++ + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { + hid_err(hdev, "can't alloc magicmouse descriptor\n"); + return -ENOMEM; + } + +- msc->input_ops.raw_event = magicmouse_raw_event_usb; +- msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ // internal trackpad use a data format use input ops to avoid ++ // conflicts with the report ID. ++ if (id->vendor == SPI_VENDOR_ID_APPLE) { ++ msc->input_ops.raw_event = magicmouse_raw_event_spi; ++ msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ ++ } else { ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ } + + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; + msc->hdev = hdev; +@@ -925,6 +1176,8 @@ static int magicmouse_probe(struct hid_device *hdev, + else /* USB_VENDOR_ID_APPLE */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD2_USB_REPORT_ID, 0); ++ } else if (id->vendor == SPI_VENDOR_ID_APPLE) { ++ report = hid_register_report(hdev, HID_INPUT_REPORT, 2, 0); + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD_REPORT_ID, 0); +@@ -1027,6 +1280,8 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, ++ { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = 0 }, + { } + }; + MODULE_DEVICE_TABLE(hid, magic_mice); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Fri, 10 Dec 2021 19:38:43 +0100 +Subject: WIP: HID: transport: spi: add Apple SPI transport + +Keyboard and trackpad of Apple Sillicon SoCs (M1, M1 Pro/Max) laptops +are are HID devices connected via SPI. + +This is the same protocol as implemented by applespi.c. It was not +noticed that protocol is a transport for HID. Adding support for ACPI +based Intel MacBooks will be done in a separate commit. + +How HID is mapped in this protocol is not yet fully understood. + +Microsoft has a specification for HID over SPI [1] incompatible with the +transport protocol used by Apple. + +[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/hid-over-spi + +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 2 + + drivers/hid/spi-hid/Kconfig | 26 + + drivers/hid/spi-hid/Makefile | 10 + + drivers/hid/spi-hid/spi-hid-apple-core.c | 1033 ++++++++++ + drivers/hid/spi-hid/spi-hid-apple-of.c | 136 ++ + drivers/hid/spi-hid/spi-hid-apple.h | 31 + + 7 files changed, 1240 insertions(+) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1416,4 +1416,6 @@ source "drivers/hid/amd-sfh-hid/Kconfig" + + source "drivers/hid/surface-hid/Kconfig" + ++source "drivers/hid/spi-hid/Kconfig" ++ + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -172,3 +172,5 @@ obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-hid/ + obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ ++ ++obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ +diff --git a/drivers/hid/spi-hid/Kconfig b/drivers/hid/spi-hid/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/Kconfig +@@ -0,0 +1,26 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++menu "SPI HID support" ++ depends on SPI ++ ++config SPI_HID_APPLE_OF ++ tristate "HID over SPI transport layer for Apple Silicon SoCs" ++ default ARCH_APPLE ++ depends on SPI && INPUT && OF ++ help ++ Say Y here if you use Apple Silicon based laptop. The keyboard and ++ touchpad are HID based devices connected via SPI. ++ ++ If unsure, say N. ++ ++ This support is also available as a module. If so, the module ++ will be called spi-hid-apple-of. It will also build/depend on the ++ module spi-hid-apple. ++ ++endmenu ++ ++config SPI_HID_APPLE_CORE ++ tristate ++ default y if SPI_HID_APPLE_OF=y ++ default m if SPI_HID_APPLE_OF=m ++ select HID ++ select CRC16 +diff --git a/drivers/hid/spi-hid/Makefile b/drivers/hid/spi-hid/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/Makefile +@@ -0,0 +1,10 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Makefile for SPI HID tarnsport drivers ++# ++ ++obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid-apple.o ++ ++spi-hid-apple-objs = spi-hid-apple-core.o ++ ++obj-$(CONFIG_SPI_HID_APPLE_OF) += spi-hid-apple-of.o +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -0,0 +1,1033 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 ++ * ++ * Apple SPI HID transport driver ++ * ++ * Copyright (C) The Asahi Linux Contributors ++ * ++ * Based on: drivers/input/applespi.c ++ * ++ * MacBook (Pro) SPI keyboard and touchpad driver ++ * ++ * Copyright (c) 2015-2018 Federico Lorenzi ++ * Copyright (c) 2017-2018 Ronald Tschalär ++ * ++ */ ++ ++//#define DEBUG 2 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "spi-hid-apple.h" ++ ++#define SPIHID_DEF_WAIT msecs_to_jiffies(1000) ++ ++#define SPIHID_MAX_INPUT_REPORT_SIZE 0x800 ++ ++/* support only keyboard, trackpad and management dev for now */ ++#define SPIHID_MAX_DEVICES 3 ++ ++#define SPIHID_DEVICE_ID_MNGT 0x0 ++#define SPIHID_DEVICE_ID_KBD 0x1 ++#define SPIHID_DEVICE_ID_TP 0x2 ++#define SPIHID_DEVICE_ID_INFO 0xd0 ++ ++#define SPIHID_READ_PACKET 0x20 ++#define SPIHID_WRITE_PACKET 0x40 ++ ++#define SPIHID_DESC_MAX 512 ++ ++#define SPIHID_SET_LEDS 0x0151 /* caps lock */ ++ ++#define SPI_RW_CHG_DELAY_US 200 /* 'Inter Stage Us'? */ ++ ++static const u8 spi_hid_apple_booted[4] = { 0xa0, 0x80, 0x00, 0x00 }; ++static const u8 spi_hid_apple_status_ok[4] = { 0xac, 0x27, 0x68, 0xd5 }; ++ ++struct spihid_interface { ++ struct hid_device *hid; ++ u8 *hid_desc; ++ u32 hid_desc_len; ++ u32 id; ++ unsigned country; ++ u32 max_control_report_len; ++ u32 max_input_report_len; ++ u32 max_output_report_len; ++ u8 name[32]; ++ bool ready; ++}; ++ ++struct spihid_input_report { ++ u8 *buf; ++ u32 length; ++ u32 offset; ++ u8 device; ++ u8 flags; ++}; ++ ++struct spihid_apple { ++ struct spi_device *spidev; ++ ++ struct spihid_apple_ops *ops; ++ ++ struct spihid_interface mngt; ++ struct spihid_interface kbd; ++ struct spihid_interface tp; ++ ++ wait_queue_head_t wait; ++ struct mutex tx_lock; //< protects against concurrent SPI writes ++ ++ struct spi_message rx_msg; ++ struct spi_message tx_msg; ++ struct spi_transfer rx_transfer; ++ struct spi_transfer tx_transfer; ++ struct spi_transfer status_transfer; ++ ++ u8 *rx_buf; ++ u8 *tx_buf; ++ u8 *status_buf; ++ ++ u8 vendor[32]; ++ u8 product[64]; ++ u8 serial[32]; ++ ++ u32 num_devices; ++ ++ u32 vendor_id; ++ u32 product_id; ++ u32 version_number; ++ ++ u8 msg_id; ++ ++ /* fragmented HID report */ ++ struct spihid_input_report report; ++ ++ /* state tracking flags */ ++ bool status_booted; ++}; ++ ++/** ++ * struct spihid_msg_hdr - common header of protocol messages. ++ * ++ * Each message begins with fixed header, followed by a message-type specific ++ * payload, and ends with a 16-bit crc. Because of the varying lengths of the ++ * payload, the crc is defined at the end of each payload struct, rather than ++ * in this struct. ++ * ++ * @unknown0: request type? output, input (0x10), feature, protocol ++ * @unknown1: maybe report id? ++ * @unknown2: mostly zero, in info request maybe device num ++ * @msgid: incremented on each message, rolls over after 255; there is a ++ * separate counter for each message type. ++ * @rsplen: response length (the exact nature of this field is quite ++ * speculative). On a request/write this is often the same as ++ * @length, though in some cases it has been seen to be much larger ++ * (e.g. 0x400); on a response/read this the same as on the ++ * request; for reads that are not responses it is 0. ++ * @length: length of the remainder of the data in the whole message ++ * structure (after re-assembly in case of being split over ++ * multiple spi-packets), minus the trailing crc. The total size ++ * of a message is therefore @length + 10. ++ */ ++ ++struct spihid_msg_hdr { ++ u8 unknown0; ++ u8 unknown1; ++ u8 unknown2; ++ u8 id; ++ __le16 rsplen; ++ __le16 length; ++}; ++ ++/** ++ * struct spihid_transfer_packet - a complete spi packet; always 256 bytes. This carries ++ * the (parts of the) message in the data. But note that this does not ++ * necessarily contain a complete message, as in some cases (e.g. many ++ * fingers pressed) the message is split over multiple packets (see the ++ * @offset, @remain, and @length fields). In general the data parts in ++ * spihid_transfer_packet's are concatenated until @remaining is 0, and the ++ * result is an message. ++ * ++ * @flags: 0x40 = write (to device), 0x20 = read (from device); note that ++ * the response to a write still has 0x40. ++ * @device: 1 = keyboard, 2 = touchpad ++ * @offset: specifies the offset of this packet's data in the complete ++ * message; i.e. > 0 indicates this is a continuation packet (in ++ * the second packet for a message split over multiple packets ++ * this would then be the same as the @length in the first packet) ++ * @remain: number of message bytes remaining in subsequents packets (in ++ * the first packet of a message split over two packets this would ++ * then be the same as the @length in the second packet) ++ * @length: length of the valid data in the @data in this packet ++ * @data: all or part of a message ++ * @crc16: crc over this whole structure minus this @crc16 field. This ++ * covers just this packet, even on multi-packet messages (in ++ * contrast to the crc in the message). ++ */ ++struct spihid_transfer_packet { ++ u8 flags; ++ u8 device; ++ __le16 offset; ++ __le16 remain; ++ __le16 length; ++ u8 data[246]; ++ __le16 crc16; ++}; ++ ++/* ++ * how HID is mapped onto the protocol is not fully clear. This are the known ++ * reports/request: ++ * ++ * pkt.flags pkt.dev? msg.u0 msg.u1 msg.u2 ++ * info 0x40 0xd0 0x20 0x01 0xd0 ++ * ++ * info mngt: 0x40 0xd0 0x20 0x10 0x00 ++ * info kbd: 0x40 0xd0 0x20 0x10 0x01 ++ * info tp: 0x40 0xd0 0x20 0x10 0x02 ++ * ++ * desc kbd: 0x40 0xd0 0x20 0x10 0x01 ++ * desc trackpad: 0x40 0xd0 0x20 0x10 0x02 ++ * ++ * mt mode: 0x40 0x02 0x52 0x02 0x00 set protocol? ++ * capslock led 0x40 0x01 0x51 0x01 0x00 output report ++ * ++ * report kbd: 0x20 0x01 0x10 0x01 0x00 input report ++ * report tp: 0x20 0x02 0x10 0x02 0x00 input report ++ * ++ */ ++ ++ ++static int spihid_apple_request(struct spihid_apple *spihid, u8 target, u8 unk0, ++ u8 unk1, u8 unk2, u16 resp_len, u8 *buf, ++ size_t len) ++{ ++ struct spihid_transfer_packet *pkt; ++ struct spihid_msg_hdr *hdr; ++ u16 crc; ++ int err; ++ ++ /* know reports are small enoug to fit in a single packet */ ++ if (len > sizeof(pkt->data) - sizeof(*hdr) - sizeof(__le16)) ++ return -EINVAL; ++ ++ err = mutex_lock_interruptible(&spihid->tx_lock); ++ if (err < 0) ++ return err; ++ ++ pkt = (struct spihid_transfer_packet *)spihid->tx_buf; ++ ++ memset(pkt, 0, sizeof(*pkt)); ++ pkt->flags = SPIHID_WRITE_PACKET; ++ pkt->device = target; ++ pkt->length = cpu_to_le16(sizeof(*hdr) + len + sizeof(__le16)); ++ ++ hdr = (struct spihid_msg_hdr *)&pkt->data[0]; ++ hdr->unknown0 = unk0; ++ hdr->unknown1 = unk1; ++ hdr->unknown2 = unk2; ++ hdr->id = spihid->msg_id++; ++ hdr->rsplen = cpu_to_le16(resp_len); ++ hdr->length = cpu_to_le16(len); ++ ++ if (len) ++ memcpy(pkt->data + sizeof(*hdr), buf, len); ++ crc = crc16(0, &pkt->data[0], sizeof(*hdr) + len); ++ put_unaligned_le16(crc, pkt->data + sizeof(*hdr) + len); ++ ++ pkt->crc16 = cpu_to_le16(crc16(0, spihid->tx_buf, ++ offsetof(struct spihid_transfer_packet, crc16))); ++ ++ err = spi_sync(spihid->spidev, &spihid->tx_msg); ++ mutex_unlock(&spihid->tx_lock); ++ if (err < 0) ++ return err; ++ ++ return (int)len; ++} ++ ++static struct spihid_apple *spihid_get_data(struct spihid_interface *idev) ++{ ++ switch (idev->id) { ++ case SPIHID_DEVICE_ID_KBD: ++ return container_of(idev, struct spihid_apple, kbd); ++ case SPIHID_DEVICE_ID_TP: ++ return container_of(idev, struct spihid_apple, tp); ++ default: ++ return NULL; ++ } ++} ++ ++static int apple_ll_start(struct hid_device *hdev) ++{ ++ /* no-op SPI transport is already setup */ ++ return 0; ++}; ++ ++static void apple_ll_stop(struct hid_device *hdev) ++{ ++ /* no-op, devices will be desstroyed on driver destruction */ ++} ++ ++static int apple_ll_open(struct hid_device *hdev) ++{ ++ struct spihid_apple *spihid; ++ struct spihid_interface *idev = hdev->driver_data; ++ ++ if (idev->hid_desc_len == 0) { ++ spihid = spihid_get_data(idev); ++ dev_warn(&spihid->spidev->dev, ++ "HID descriptor missing for dev %u", idev->id); ++ } else ++ idev->ready = true; ++ ++ return 0; ++} ++ ++static void apple_ll_close(struct hid_device *hdev) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ idev->ready = false; ++} ++ ++static int apple_ll_parse(struct hid_device *hdev) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ ++ return hid_parse_report(hdev, idev->hid_desc, idev->hid_desc_len); ++} ++ ++static int apple_ll_raw_request(struct hid_device *hdev, ++ unsigned char reportnum, __u8 *buf, size_t len, ++ unsigned char rtype, int reqtype) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ struct spihid_apple *spihid = spihid_get_data(idev); ++ ++ dev_dbg(&spihid->spidev->dev, ++ "apple_ll_raw_request: device:%u reportnum:%hhu rtype:%hhu", ++ idev->id, reportnum, rtype); ++ ++ switch (reqtype) { ++ case HID_REQ_GET_REPORT: ++ return -EINVAL; // spihid_get_raw_report(); ++ case HID_REQ_SET_REPORT: ++ if (buf[0] != reportnum) ++ return -EINVAL; ++ if (reportnum != idev->id) { ++ dev_warn(&spihid->spidev->dev, ++ "device:%u reportnum:" ++ "%hhu mismatch", ++ idev->id, reportnum); ++ return -EINVAL; ++ } ++ return spihid_apple_request(spihid, idev->id, 0x52, reportnum, 0x00, 2, buf, len); ++ default: ++ return -EIO; ++ } ++} ++ ++static int apple_ll_output_report(struct hid_device *hdev, __u8 *buf, ++ size_t len) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ struct spihid_apple *spihid = spihid_get_data(idev); ++ if (!spihid) ++ return -1; ++ ++ dev_dbg(&spihid->spidev->dev, ++ "apple_ll_output_report: device:%u len:%zu:", ++ idev->id, len); ++ // second idev->id should maybe be buf[0]? ++ return spihid_apple_request(spihid, idev->id, 0x51, idev->id, 0x00, 0, buf, len); ++} ++ ++static struct hid_ll_driver apple_hid_ll = { ++ .start = &apple_ll_start, ++ .stop = &apple_ll_stop, ++ .open = &apple_ll_open, ++ .close = &apple_ll_close, ++ .parse = &apple_ll_parse, ++ .raw_request = &apple_ll_raw_request, ++ .output_report = &apple_ll_output_report, ++}; ++ ++static struct spihid_interface *spihid_get_iface(struct spihid_apple *spihid, ++ u32 iface) ++{ ++ switch (iface) { ++ case SPIHID_DEVICE_ID_MNGT: ++ return &spihid->mngt; ++ case SPIHID_DEVICE_ID_KBD: ++ return &spihid->kbd; ++ case SPIHID_DEVICE_ID_TP: ++ return &spihid->tp; ++ default: ++ return NULL; ++ } ++} ++ ++static int spihid_verify_msg(struct spihid_apple *spihid, u8 *buf, size_t len) ++{ ++ u16 msg_crc, crc; ++ struct device *dev = &spihid->spidev->dev; ++ ++ crc = crc16(0, buf, len - sizeof(__le16)); ++ msg_crc = get_unaligned_le16(buf + len - sizeof(__le16)); ++ if (crc != msg_crc) { ++ dev_warn_ratelimited(dev, "Read message crc mismatch\n"); ++ return 0; ++ } ++ return 1; ++} ++ ++static bool spihid_status_report(struct spihid_apple *spihid, u8 *pl, ++ size_t len) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ dev_dbg(dev, "%s: len: %zu", __func__, len); ++ if (len == 5 && pl[0] == 0xe0) ++ return true; ++ ++ return false; ++} ++ ++static bool spihid_process_input_report(struct spihid_apple *spihid, u32 device, ++ struct spihid_msg_hdr *hdr, u8 *payload, ++ size_t len) ++{ ++ //dev_dbg(&spihid>spidev->dev, "input report: req:%hx iface:%u ", hdr->unknown0, device); ++ if (hdr->unknown0 != 0x10) ++ return false; ++ ++ /* HID device as well but Vendor usage only, handle it internally for now */ ++ if (device == 0) { ++ if (hdr->unknown1 == 0xe0) { ++ return spihid_status_report(spihid, payload, len); ++ } ++ } else if (device < SPIHID_MAX_DEVICES) { ++ struct spihid_interface *iface = ++ spihid_get_iface(spihid, device); ++ if (iface && iface->hid && iface->ready) { ++ hid_input_report(iface->hid, HID_INPUT_REPORT, payload, ++ len, 1); ++ return true; ++ } ++ } else ++ dev_dbg(&spihid->spidev->dev, ++ "unexpected iface:%u for input report", device); ++ ++ return false; ++} ++ ++struct spihid_device_info { ++ __le16 u0[2]; ++ __le16 num_devices; ++ __le16 vendor_id; ++ __le16 product_id; ++ __le16 version_number; ++ __le16 vendor_str[2]; //< offset and string length ++ __le16 product_str[2]; //< offset and string length ++ __le16 serial_str[2]; //< offset and string length ++}; ++ ++static bool spihid_process_device_info(struct spihid_apple *spihid, u32 iface, ++ u8 *payload, size_t len) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ ++ if (iface != SPIHID_DEVICE_ID_INFO) ++ return false; ++ ++ if (spihid->vendor_id == 0 && ++ len >= sizeof(struct spihid_device_info)) { ++ struct spihid_device_info *info = ++ (struct spihid_device_info *)payload; ++ u16 voff, vlen, poff, plen, soff, slen; ++ u32 num_devices; ++ ++ num_devices = __le16_to_cpu(info->num_devices); ++ ++ if (num_devices < SPIHID_MAX_DEVICES) { ++ dev_err(dev, ++ "Device info reports %u devices, expecting at least 3", ++ num_devices); ++ return false; ++ } ++ spihid->num_devices = num_devices; ++ ++ if (spihid->num_devices > SPIHID_MAX_DEVICES) { ++ dev_info( ++ dev, ++ "limiting the number of devices to mngt, kbd and mouse"); ++ spihid->num_devices = SPIHID_MAX_DEVICES; ++ } ++ ++ spihid->vendor_id = __le16_to_cpu(info->vendor_id); ++ spihid->product_id = __le16_to_cpu(info->product_id); ++ spihid->version_number = __le16_to_cpu(info->version_number); ++ ++ voff = __le16_to_cpu(info->vendor_str[0]); ++ vlen = __le16_to_cpu(info->vendor_str[1]); ++ ++ if (voff < len && vlen <= len - voff && ++ vlen < sizeof(spihid->vendor)) { ++ memcpy(spihid->vendor, payload + voff, vlen); ++ spihid->vendor[vlen] = '\0'; ++ } ++ ++ poff = __le16_to_cpu(info->product_str[0]); ++ plen = __le16_to_cpu(info->product_str[1]); ++ ++ if (poff < len && plen <= len - poff && ++ plen < sizeof(spihid->product)) { ++ memcpy(spihid->product, payload + poff, plen); ++ spihid->product[plen] = '\0'; ++ } ++ ++ soff = __le16_to_cpu(info->serial_str[0]); ++ slen = __le16_to_cpu(info->serial_str[1]); ++ ++ if (soff < len && slen <= len - soff && ++ slen < sizeof(spihid->serial)) { ++ memcpy(spihid->vendor, payload + soff, slen); ++ spihid->serial[slen] = '\0'; ++ } ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ return true; ++} ++ ++struct spihid_iface_info { ++ u8 u_0; ++ u8 interface_num; ++ u8 u_2; ++ u8 u_3; ++ u8 u_4; ++ u8 country_code; ++ __le16 max_input_report_len; ++ __le16 max_output_report_len; ++ __le16 max_control_report_len; ++ __le16 name_offset; ++ __le16 name_length; ++}; ++ ++static bool spihid_process_iface_info(struct spihid_apple *spihid, u32 num, ++ u8 *payload, size_t len) ++{ ++ struct spihid_iface_info *info; ++ struct spihid_interface *iface = spihid_get_iface(spihid, num); ++ u32 name_off, name_len; ++ ++ if (!iface) ++ return false; ++ ++ if (!iface->max_input_report_len) { ++ if (len < sizeof(*info)) ++ return false; ++ ++ info = (struct spihid_iface_info *)payload; ++ ++ iface->max_input_report_len = ++ le16_to_cpu(info->max_input_report_len); ++ iface->max_output_report_len = ++ le16_to_cpu(info->max_output_report_len); ++ iface->max_control_report_len = ++ le16_to_cpu(info->max_control_report_len); ++ iface->country = info->country_code; ++ ++ name_off = le16_to_cpu(info->name_offset); ++ name_len = le16_to_cpu(info->name_length); ++ ++ if (name_off < len && name_len <= len - name_off && ++ name_len < sizeof(iface->name)) { ++ memcpy(iface->name, payload + name_off, name_len); ++ iface->name[name_len] = '\0'; ++ } ++ ++ dev_dbg(&spihid->spidev->dev, "Info for %s, country code: 0x%x", ++ iface->name, iface->country); ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ ++ return true; ++} ++ ++static int spihid_register_hid_device(struct spihid_apple *spihid, ++ struct spihid_interface *idev, u8 device); ++ ++static bool spihid_process_iface_hid_report_desc(struct spihid_apple *spihid, ++ u32 num, u8 *payload, ++ size_t len) ++{ ++ struct spihid_interface *iface = spihid_get_iface(spihid, num); ++ ++ if (!iface) ++ return false; ++ ++ if (iface->hid_desc_len == 0) { ++ if (len > SPIHID_DESC_MAX) ++ return false; ++ memcpy(iface->hid_desc, payload, len); ++ iface->hid_desc_len = len; ++ ++ /* do not register the mngt iface as HID device */ ++ if (num > 0) ++ spihid_register_hid_device(spihid, iface, num); ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ return true; ++} ++ ++static bool spihid_process_response(struct spihid_apple *spihid, ++ struct spihid_msg_hdr *hdr, u8 *payload, ++ size_t len) ++{ ++ if (hdr->unknown0 == 0x20) { ++ switch (hdr->unknown1) { ++ case 0x01: ++ return spihid_process_device_info(spihid, hdr->unknown2, ++ payload, len); ++ case 0x02: ++ return spihid_process_iface_info(spihid, hdr->unknown2, ++ payload, len); ++ case 0x10: ++ return spihid_process_iface_hid_report_desc( ++ spihid, hdr->unknown2, payload, len); ++ default: ++ break; ++ } ++ } ++ ++ return false; ++} ++ ++static void spihid_process_message(struct spihid_apple *spihid, u8 *data, ++ size_t length, u8 device, u8 flags) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_msg_hdr *hdr; ++ bool handled = false; ++ size_t payload_len; ++ u8 *payload; ++ ++ if (!spihid_verify_msg(spihid, data, length)) ++ return; ++ ++ hdr = (struct spihid_msg_hdr *)data; ++ payload_len = le16_to_cpu(hdr->length); ++ ++ if (payload_len == 0 || ++ (payload_len + sizeof(struct spihid_msg_hdr) + 2) > length) ++ return; ++ ++ payload = data + sizeof(struct spihid_msg_hdr); ++ ++ switch (flags) { ++ case SPIHID_READ_PACKET: ++ handled = spihid_process_input_report(spihid, device, hdr, ++ payload, payload_len); ++ break; ++ case SPIHID_WRITE_PACKET: ++ handled = spihid_process_response(spihid, hdr, payload, ++ payload_len); ++ break; ++ default: ++ break; ++ } ++ ++#if defined(DEBUG) && DEBUG > 1 ++ { ++ dev_dbg(dev, ++ "R msg: req:%02hhx rep:%02hhx dev:%02hhx id:%hu len:%hu\n", ++ hdr->unknown0, hdr->unknown1, hdr->unknown2, hdr->id, ++ hdr->length); ++ print_hex_dump_debug("spihid msg: ", DUMP_PREFIX_OFFSET, 16, 1, ++ payload, le16_to_cpu(hdr->length), true); ++ } ++#else ++ if (!handled) { ++ dev_dbg(dev, ++ "R unhandled msg: req:%02hhx rep:%02hhx dev:%02hhx id:%hu len:%hu\n", ++ hdr->unknown0, hdr->unknown1, hdr->unknown2, hdr->id, ++ hdr->length); ++ print_hex_dump_debug("spihid msg: ", DUMP_PREFIX_OFFSET, 16, 1, ++ payload, le16_to_cpu(hdr->length), true); ++ } ++#endif ++} ++ ++static void spihid_assemble_message(struct spihid_apple *spihid, ++ struct spihid_transfer_packet *pkt) ++{ ++ size_t length, offset, remain; ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_input_report *rep = &spihid->report; ++ ++ length = le16_to_cpu(pkt->length); ++ remain = le16_to_cpu(pkt->remain); ++ offset = le16_to_cpu(pkt->offset); ++ ++ if (offset + length + remain > U16_MAX) { ++ return; ++ } ++ ++ if (pkt->device != rep->device || pkt->flags != rep->flags || ++ offset != rep->offset) { ++ rep->device = 0; ++ rep->flags = 0; ++ rep->offset = 0; ++ rep->length = 0; ++ } ++ ++ if (offset == 0) { ++ if (rep->offset != 0) { ++ dev_warn(dev, "incomplete report off:%u len:%u", ++ rep->offset, rep->length); ++ } ++ memcpy(rep->buf, pkt->data, length); ++ rep->offset = length; ++ rep->length = length + remain; ++ rep->device = pkt->device; ++ rep->flags = pkt->flags; ++ } else if (offset == rep->offset) { ++ if (offset + length + remain != rep->length) { ++ dev_warn(dev, "incomplete report off:%u len:%u", ++ rep->offset, rep->length); ++ return; ++ } ++ memcpy(rep->buf + offset, pkt->data, length); ++ rep->offset += length; ++ ++ if (rep->offset == rep->length) { ++ spihid_process_message(spihid, rep->buf, rep->length, ++ rep->device, rep->flags); ++ rep->device = 0; ++ rep->flags = 0; ++ rep->offset = 0; ++ rep->length = 0; ++ } ++ } ++} ++ ++static void spihid_process_read(struct spihid_apple *spihid) ++{ ++ u16 crc; ++ size_t length; ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_transfer_packet *pkt; ++ ++ pkt = (struct spihid_transfer_packet *)spihid->rx_buf; ++ ++ /* check transfer packet crc */ ++ crc = crc16(0, spihid->rx_buf, ++ offsetof(struct spihid_transfer_packet, crc16)); ++ if (crc != le16_to_cpu(pkt->crc16)) { ++ dev_warn_ratelimited(dev, "Read package crc mismatch\n"); ++ return; ++ } ++ ++ length = le16_to_cpu(pkt->length); ++ ++ if (length < sizeof(struct spihid_msg_hdr) + 2) { ++ if (length == sizeof(spi_hid_apple_booted) && ++ !memcmp(pkt->data, spi_hid_apple_booted, length)) { ++ if (!spihid->status_booted) { ++ spihid->status_booted = true; ++ wake_up_interruptible(&spihid->wait); ++ } ++ } else { ++ dev_info(dev, "R short packet: len:%zu\n", length); ++ print_hex_dump(KERN_INFO, "spihid pkt:", ++ DUMP_PREFIX_OFFSET, 16, 1, pkt->data, ++ length, false); ++ } ++ return; ++ } ++ ++#if defined(DEBUG) && DEBUG > 1 ++ dev_dbg(dev, ++ "R pkt: flags:%02hhx dev:%02hhx off:%hu remain:%hu, len:%zu\n", ++ pkt->flags, pkt->device, pkt->offset, pkt->remain, length); ++#if defined(DEBUG) && DEBUG > 2 ++ print_hex_dump_debug("spihid pkt: ", DUMP_PREFIX_OFFSET, 16, 1, ++ spihid->rx_buf, ++ sizeof(struct spihid_transfer_packet), true); ++#endif ++#endif ++ ++ if (length > sizeof(pkt->data)) { ++ dev_warn_ratelimited(dev, "Invalid pkt len:%zu", length); ++ return; ++ } ++ ++ /* short message */ ++ if (pkt->offset == 0 && pkt->remain == 0) { ++ spihid_process_message(spihid, pkt->data, length, pkt->device, ++ pkt->flags); ++ } else { ++ spihid_assemble_message(spihid, pkt); ++ } ++} ++ ++static void spihid_read_packet_sync(struct spihid_apple *spihid) ++{ ++ int err; ++ ++ err = spi_sync(spihid->spidev, &spihid->rx_msg); ++ if (!err) { ++ spihid_process_read(spihid); ++ } else { ++ dev_warn(&spihid->spidev->dev, "RX failed: %d\n", err); ++ } ++} ++ ++irqreturn_t spihid_apple_core_irq(int irq, void *data) ++{ ++ struct spi_device *spi = data; ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ spihid_read_packet_sync(spihid); ++ ++ return IRQ_HANDLED; ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_irq); ++ ++static void spihid_apple_setup_spi_msgs(struct spihid_apple *spihid) ++{ ++ memset(&spihid->rx_transfer, 0, sizeof(spihid->rx_transfer)); ++ ++ spihid->rx_transfer.rx_buf = spihid->rx_buf; ++ spihid->rx_transfer.len = sizeof(struct spihid_transfer_packet); ++ ++ spi_message_init(&spihid->rx_msg); ++ spi_message_add_tail(&spihid->rx_transfer, &spihid->rx_msg); ++ ++ memset(&spihid->tx_transfer, 0, sizeof(spihid->rx_transfer)); ++ memset(&spihid->status_transfer, 0, sizeof(spihid->status_transfer)); ++ ++ spihid->tx_transfer.tx_buf = spihid->tx_buf; ++ spihid->tx_transfer.len = sizeof(struct spihid_transfer_packet); ++ spihid->tx_transfer.delay.unit = SPI_DELAY_UNIT_USECS; ++ spihid->tx_transfer.delay.value = SPI_RW_CHG_DELAY_US; ++ ++ spihid->status_transfer.rx_buf = spihid->status_buf; ++ spihid->status_transfer.len = sizeof(spi_hid_apple_status_ok); ++ ++ spi_message_init(&spihid->tx_msg); ++ spi_message_add_tail(&spihid->tx_transfer, &spihid->tx_msg); ++ spi_message_add_tail(&spihid->status_transfer, &spihid->tx_msg); ++} ++ ++static int spihid_apple_setup_spi(struct spihid_apple *spihid) ++{ ++ spihid_apple_setup_spi_msgs(spihid); ++ ++ return spihid->ops->power_on(spihid->ops); ++} ++ ++static int spihid_register_hid_device(struct spihid_apple *spihid, ++ struct spihid_interface *iface, u8 device) ++{ ++ int ret; ++ struct hid_device *hid; ++ ++ iface->id = device; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return PTR_ERR(hid); ++ ++ strscpy(hid->name, spihid->product, sizeof(hid->name)); ++ snprintf(hid->phys, sizeof(hid->phys), "%s (%hhx)", ++ dev_name(&spihid->spidev->dev), device); ++ strscpy(hid->uniq, spihid->serial, sizeof(hid->uniq)); ++ ++ hid->ll_driver = &apple_hid_ll; ++ hid->bus = BUS_SPI; ++ hid->vendor = spihid->vendor_id; ++ hid->product = spihid->product_id; ++ hid->version = spihid->version_number; ++ ++ if (device == SPIHID_DEVICE_ID_KBD) ++ hid->type = HID_TYPE_SPI_KEYBOARD; ++ else if (device == SPIHID_DEVICE_ID_TP) ++ hid->type = HID_TYPE_SPI_MOUSE; ++ ++ hid->country = iface->country; ++ hid->dev.parent = &spihid->spidev->dev; ++ hid->driver_data = iface; ++ ++ ret = hid_add_device(hid); ++ if (ret < 0) { ++ hid_destroy_device(hid); ++ dev_warn(&spihid->spidev->dev, ++ "Failed to register hid device %hhu", device); ++ return ret; ++ } ++ ++ iface->hid = hid; ++ ++ return 0; ++} ++ ++static void spihid_destroy_hid_device(struct spihid_interface *iface) ++{ ++ if (iface->hid) { ++ hid_destroy_device(iface->hid); ++ iface->hid = NULL; ++ } ++ iface->ready = false; ++} ++ ++int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops) ++{ ++ struct device *dev = &spi->dev; ++ struct spihid_apple *spihid; ++ int err, i; ++ ++ if (!ops || !ops->power_on || !ops->power_off || !ops->enable_irq || !ops->disable_irq) ++ return -EINVAL; ++ ++ spihid = devm_kzalloc(dev, sizeof(*spihid), GFP_KERNEL); ++ if (!spihid) ++ return -ENOMEM; ++ ++ spihid->ops = ops; ++ spihid->spidev = spi; ++ ++ // init spi ++ spi_set_drvdata(spi, spihid); ++ ++ /* allocate SPI buffers */ ++ spihid->rx_buf = devm_kmalloc( ++ &spi->dev, sizeof(struct spihid_transfer_packet), GFP_KERNEL); ++ spihid->tx_buf = devm_kmalloc( ++ &spi->dev, sizeof(struct spihid_transfer_packet), GFP_KERNEL); ++ spihid->status_buf = devm_kmalloc( ++ &spi->dev, sizeof(spi_hid_apple_status_ok), GFP_KERNEL); ++ ++ if (!spihid->rx_buf || !spihid->tx_buf || !spihid->status_buf) ++ return -ENOMEM; ++ ++ spihid->report.buf = ++ devm_kmalloc(dev, SPIHID_MAX_INPUT_REPORT_SIZE, GFP_KERNEL); ++ ++ spihid->kbd.hid_desc = devm_kmalloc(dev, SPIHID_DESC_MAX, GFP_KERNEL); ++ spihid->tp.hid_desc = devm_kmalloc(dev, SPIHID_DESC_MAX, GFP_KERNEL); ++ ++ if (!spihid->report.buf || !spihid->kbd.hid_desc || ++ !spihid->tp.hid_desc) ++ return -ENOMEM; ++ ++ init_waitqueue_head(&spihid->wait); ++ ++ mutex_init(&spihid->tx_lock); ++ ++ /* Init spi transfer buffers and power device on */ ++ err = spihid_apple_setup_spi(spihid); ++ if (err < 0) ++ goto error; ++ ++ /* enable HID irq */ ++ spihid->ops->enable_irq(spihid->ops); ++ ++ // wait for boot message ++ err = wait_event_interruptible_timeout(spihid->wait, ++ spihid->status_booted, ++ msecs_to_jiffies(1000)); ++ if (err == 0) ++ err = -ENODEV; ++ if (err < 0) { ++ dev_err(dev, "waiting for device boot failed: %d", err); ++ goto error; ++ } ++ ++ /* request device information */ ++ dev_dbg(dev, "request device info"); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x01, 0xd0, 0, NULL, 0); ++ err = wait_event_interruptible_timeout(spihid->wait, spihid->vendor_id, ++ SPIHID_DEF_WAIT); ++ if (err == 0) ++ err = -ENODEV; ++ if (err < 0) { ++ dev_err(dev, "waiting for device info failed: %d", err); ++ goto error; ++ } ++ ++ /* request interface information */ ++ for (i = 0; i < spihid->num_devices; i++) { ++ struct spihid_interface *iface = spihid_get_iface(spihid, i); ++ if (!iface) ++ continue; ++ dev_dbg(dev, "request interface info 0x%02x", i); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x02, i, ++ SPIHID_DESC_MAX, NULL, 0); ++ err = wait_event_interruptible_timeout( ++ spihid->wait, iface->max_input_report_len, ++ SPIHID_DEF_WAIT); ++ } ++ ++ /* request HID report descriptors */ ++ for (i = 1; i < spihid->num_devices; i++) { ++ struct spihid_interface *iface = spihid_get_iface(spihid, i); ++ if (!iface) ++ continue; ++ dev_dbg(dev, "request hid report desc 0x%02x", i); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x10, i, ++ SPIHID_DESC_MAX, NULL, 0); ++ wait_event_interruptible_timeout( ++ spihid->wait, iface->hid_desc_len, SPIHID_DEF_WAIT); ++ } ++ ++ return 0; ++error: ++ return err; ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_probe); ++ ++void spihid_apple_core_remove(struct spi_device *spi) ++{ ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ /* destroy input devices */ ++ ++ spihid_destroy_hid_device(&spihid->tp); ++ spihid_destroy_hid_device(&spihid->kbd); ++ ++ /* disable irq */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++ /* power SPI device down */ ++ spihid->ops->power_off(spihid->ops); ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_remove); ++ ++void spihid_apple_core_shutdown(struct spi_device *spi) ++{ ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ /* disable irq */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++ /* power SPI device down */ ++ spihid->ops->power_off(spihid->ops); ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_shutdown); ++ ++MODULE_DESCRIPTION("Apple SPI HID transport driver"); ++MODULE_AUTHOR("Janne Grunau "); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/spi-hid/spi-hid-apple-of.c b/drivers/hid/spi-hid/spi-hid-apple-of.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple-of.c +@@ -0,0 +1,136 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 ++ * ++ * Apple SPI HID transport driver - Open Firmware ++ * ++ * Copyright (C) The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "spi-hid-apple.h" ++ ++ ++struct spihid_apple_of { ++ struct spihid_apple_ops ops; ++ ++ struct gpio_desc *enable_gpio; ++ int irq; ++}; ++ ++static int spihid_apple_of_power_on(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ /* reset the controller on boot */ ++ gpiod_direction_output(sh_of->enable_gpio, 1); ++ msleep(5); ++ gpiod_direction_output(sh_of->enable_gpio, 0); ++ msleep(5); ++ /* turn SPI device on */ ++ gpiod_direction_output(sh_of->enable_gpio, 1); ++ msleep(50); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_power_off(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ /* turn SPI device off */ ++ gpiod_direction_output(sh_of->enable_gpio, 0); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_enable_irq(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ enable_irq(sh_of->irq); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_disable_irq(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ disable_irq(sh_of->irq); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_probe(struct spi_device *spi) ++{ ++ struct device *dev = &spi->dev; ++ struct spihid_apple_of *spihid_of; ++ int err; ++ ++ spihid_of = devm_kzalloc(dev, sizeof(*spihid_of), GFP_KERNEL); ++ if (!spihid_of) ++ return -ENOMEM; ++ ++ spihid_of->ops.power_on = spihid_apple_of_power_on; ++ spihid_of->ops.power_off = spihid_apple_of_power_off; ++ spihid_of->ops.enable_irq = spihid_apple_of_enable_irq; ++ spihid_of->ops.disable_irq = spihid_apple_of_disable_irq; ++ ++ spihid_of->enable_gpio = devm_gpiod_get_index(dev, "spien", 0, 0); ++ if (IS_ERR(spihid_of->enable_gpio)) { ++ err = PTR_ERR(spihid_of->enable_gpio); ++ dev_err(dev, "failed to get 'spien' gpio pin: %d", err); ++ return err; ++ } ++ ++ spihid_of->irq = of_irq_get(dev->of_node, 0); ++ if (spihid_of->irq < 0) { ++ err = spihid_of->irq; ++ dev_err(dev, "failed to get 'extended-irq': %d", err); ++ return err; ++ } ++ err = devm_request_threaded_irq(dev, spihid_of->irq, NULL, ++ spihid_apple_core_irq, IRQF_ONESHOT | IRQF_NO_AUTOEN, ++ "spi-hid-apple-irq", spi); ++ if (err < 0) { ++ dev_err(dev, "failed to request extended-irq %d: %d", ++ spihid_of->irq, err); ++ return err; ++ } ++ ++ return spihid_apple_core_probe(spi, &spihid_of->ops); ++} ++ ++static const struct of_device_id spihid_apple_of_match[] = { ++ { .compatible = "apple,spi-hid-transport" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, spihid_apple_of_match); ++ ++static struct spi_device_id spihid_apple_of_id[] = { ++ { "spi-hid-transport", 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(spi, spihid_apple_of_id); ++ ++static struct spi_driver spihid_apple_of_driver = { ++ .driver = { ++ .name = "spi-hid-apple-of", ++ //.pm = &spi_hid_apple_of_pm, ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(spihid_apple_of_match), ++ }, ++ ++ .id_table = spihid_apple_of_id, ++ .probe = spihid_apple_of_probe, ++ .remove = spihid_apple_core_remove, ++ .shutdown = spihid_apple_core_shutdown, ++}; ++ ++module_spi_driver(spihid_apple_of_driver); ++ ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/spi-hid/spi-hid-apple.h b/drivers/hid/spi-hid/spi-hid-apple.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ ++ ++#ifndef SPI_HID_APPLE_H ++#define SPI_HID_APPLE_H ++ ++#include ++#include ++ ++/** ++ * struct spihid_apple_ops - Ops to control the device from the core driver. ++ * ++ * @power_on: reset and power the device on. ++ * @power_off: power the device off. ++ * @enable_irq: enable irq or ACPI gpe. ++ * @disable_irq: disable irq or ACPI gpe. ++ */ ++ ++struct spihid_apple_ops { ++ int (*power_on)(struct spihid_apple_ops *ops); ++ int (*power_off)(struct spihid_apple_ops *ops); ++ int (*enable_irq)(struct spihid_apple_ops *ops); ++ int (*disable_irq)(struct spihid_apple_ops *ops); ++}; ++ ++irqreturn_t spihid_apple_core_irq(int irq, void *data); ++ ++int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops); ++void spihid_apple_core_remove(struct spi_device *spi); ++void spihid_apple_core_shutdown(struct spi_device *spi); ++ ++#endif /* SPI_HID_APPLE_H */ +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 00:29:43 +0900 +Subject: HID: add HOST vendor/device IDs for Apple MTP devices + +Apple M2 chips have an embedded MTP processor that handles all HID +functions, and does not go over a traditional bus like SPI. The devices +still have real IDs, so add them here. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-ids.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -94,6 +94,7 @@ + #define USB_VENDOR_ID_APPLE 0x05ac + #define BT_VENDOR_ID_APPLE 0x004c + #define SPI_VENDOR_ID_APPLE 0x05ac ++#define HOST_VENDOR_ID_APPLE 0x05ac + #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 + #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d + #define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269 +@@ -198,6 +199,8 @@ + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020 0x0341 + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021 0x0342 + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021 0x0343 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_AIR13_2022 0x0351 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022 0x0354 + + #define USB_VENDOR_ID_ASETEK 0x2433 + #define USB_DEVICE_ID_ASETEK_INVICTA 0xf300 +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:06:15 +0900 +Subject: HID: core: Handle HOST bus type when announcing devices + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2295,6 +2295,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) + case BUS_SPI: + bus = "SPI"; + break; ++ case BUS_HOST: ++ bus = "HOST"; ++ break; + case BUS_VIRTUAL: + bus = "VIRTUAL"; + break; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:12:24 +0900 +Subject: hid: apple: Bind to HOST devices for MTP + +We use BUS_HOST for MTP HID subdevices + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-apple.c | 19 +++++++--- + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -542,11 +542,16 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table = macbookair_fn_keys; +- else if (hid->vendor == SPI_VENDOR_ID_APPLE && +- hid->product == SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020) +- table = apple_fn_keys_mbp13; +- else if (hid->vendor == SPI_VENDOR_ID_APPLE) +- table = apple_fn_keys_spi; ++ else if (hid->bus == BUS_HOST || hid->bus == BUS_SPI) ++ switch (hid->product) { ++ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020: ++ case HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022: ++ table = apple_fn_keys_mbp13; ++ break; ++ default: ++ table = apple_fn_keys_spi; ++ break; ++ } + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; + else +@@ -962,7 +967,7 @@ static int apple_probe(struct hid_device *hdev, + struct apple_sc *asc; + int ret; + +- if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && + hdev->type != HID_TYPE_SPI_KEYBOARD) + return -ENODEV; + +@@ -1232,6 +1237,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), + .driver_data = APPLE_MAGIC_BACKLIGHT }, + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:12:57 +0900 +Subject: hid: magicmouse: Add MTP multi-touch device support + +Apple M2 devices expose the multi-touch device over the HID over +DockChannel transport, which we represent as the HOST bus type. The +report format is the same, except the legacy mouse header is gone and +there is no enable request needed. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 67 +++++++--- + 1 file changed, 49 insertions(+), 18 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -59,6 +59,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define MOUSE_REPORT_ID 0x29 + #define MOUSE2_REPORT_ID 0x12 + #define DOUBLE_REPORT_ID 0xf7 ++#define SPI_REPORT_ID 0x02 ++#define MTP_REPORT_ID 0x75 + #define USB_BATTERY_TIMEOUT_MS 60000 + + #define MAX_CONTACTS 16 +@@ -584,25 +586,32 @@ struct tp_finger { + } __attribute__((packed, aligned(2))); + + /** +- * struct trackpad report ++ * vendor trackpad report + * +- * @report_id: reportid +- * @buttons: HID Usage Buttons 3 1-bit reports + * @num_fingers: the number of fingers being reported in @fingers +- * @clicked: same as @buttons ++ * @buttons: same as HID buttons + */ + struct tp_header { ++ // HID vendor part, up to 1751 bytes ++ u8 unknown[22]; ++ u8 num_fingers; ++ u8 buttons; ++ u8 unknown3[14]; ++}; ++ ++/** ++ * standard HID mouse report ++ * ++ * @report_id: reportid ++ * @buttons: HID Usage Buttons 3 1-bit reports ++ */ ++struct tp_mouse_report { + // HID mouse report + u8 report_id; + u8 buttons; + u8 rel_x; + u8 rel_y; + u8 padding[4]; +- // HID vendor part, up to 1751 bytes +- u8 unknown[22]; +- u8 num_fingers; +- u8 clicked; +- u8 unknown3[14]; + }; + + static inline int le16_to_int(__le16 x) +@@ -632,7 +641,7 @@ static void report_finger_data(struct input_dev *input, int slot, + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); + } + +-static int magicmouse_raw_event_spi(struct hid_device *hdev, ++static int magicmouse_raw_event_mtp(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { + struct magicmouse_sc *msc = hid_get_drvdata(hdev); +@@ -649,9 +658,6 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + // print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data, + // size, false); + +- if (data[0] != TRACKPAD2_USB_REPORT_ID) +- return 0; +- + /* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */ + if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0) + return 0; +@@ -690,12 +696,26 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + } + + input_mt_sync_frame(input); +- input_report_key(input, BTN_MOUSE, data[1] & 1); ++ input_report_key(input, BTN_MOUSE, tp_hdr->buttons & 1); + + input_sync(input); + return 1; + } + ++static int magicmouse_raw_event_spi(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ const size_t hdr_sz = sizeof(struct tp_mouse_report); ++ ++ if (size < hdr_sz) ++ return 0; ++ ++ if (data[0] != TRACKPAD2_USB_REPORT_ID) ++ return 0; ++ ++ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -1103,7 +1123,7 @@ static int magicmouse_probe(struct hid_device *hdev, + struct hid_report *report; + int ret; + +- if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && + hdev->type != HID_TYPE_SPI_MOUSE) + return -ENODEV; + +@@ -1115,7 +1135,10 @@ static int magicmouse_probe(struct hid_device *hdev, + + // internal trackpad use a data format use input ops to avoid + // conflicts with the report ID. +- if (id->vendor == SPI_VENDOR_ID_APPLE) { ++ if (id->bus == BUS_HOST) { ++ msc->input_ops.raw_event = magicmouse_raw_event_mtp; ++ msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ } else if (id->bus == BUS_SPI) { + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; + +@@ -1176,8 +1199,10 @@ static int magicmouse_probe(struct hid_device *hdev, + else /* USB_VENDOR_ID_APPLE */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD2_USB_REPORT_ID, 0); +- } else if (id->vendor == SPI_VENDOR_ID_APPLE) { +- report = hid_register_report(hdev, HID_INPUT_REPORT, 2, 0); ++ } else if (id->bus == BUS_SPI) { ++ report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0); ++ } else if (id->bus == BUS_HOST) { ++ report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0); + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD_REPORT_ID, 0); +@@ -1192,6 +1217,10 @@ static int magicmouse_probe(struct hid_device *hdev, + } + report->size = 6; + ++ /* MTP devices do not need the MT enable, this is handled by the MTP driver */ ++ if (id->bus == BUS_HOST) ++ return 0; ++ + /* + * Some devices repond with 'invalid report id' when feature + * report switching it into multitouch mode is sent to it. +@@ -1282,6 +1311,8 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = 0 }, ++ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, ++ HID_ANY_ID), .driver_data = 0 }, + { } + }; + MODULE_DEVICE_TABLE(hid, magic_mice); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:09:24 +0900 +Subject: soc: apple: Add DockChannel driver + +DockChannel is a simple FIFO interface used to communicate between SoC +blocks. Add a driver that represents the shared interrupt controller for +the DockChannel block, and then exposes probe and data transfer +functions that child device drivers can use to instantiate individual +FIFOs. + +Signed-off-by: Hector Martin +--- + drivers/soc/apple/Kconfig | 10 + + drivers/soc/apple/Makefile | 3 + + drivers/soc/apple/dockchannel.c | 406 ++++++++++ + include/linux/soc/apple/dockchannel.h | 26 + + 4 files changed, 445 insertions(+) + +diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Kconfig ++++ b/drivers/soc/apple/Kconfig +@@ -4,6 +4,16 @@ if ARCH_APPLE || COMPILE_TEST + + menu "Apple SoC drivers" + ++config APPLE_DOCKCHANNEL ++ tristate "Apple DockChannel FIFO" ++ depends on ARCH_APPLE || COMPILE_TEST ++ default ARCH_APPLE ++ help ++ DockChannel is a simple FIFO used on Apple SoCs for debug and inter-processor ++ communications. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_MAILBOX + tristate "Apple SoC mailboxes" + depends on PM +diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Makefile ++++ b/drivers/soc/apple/Makefile +@@ -1,5 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++obj-$(CONFIG_APPLE_DOCKCHANNEL) += apple-dockchannel.o ++apple-dockchannel-y = dockchannel.o ++ + obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o + apple-mailbox-y = mailbox.o + +diff --git a/drivers/soc/apple/dockchannel.c b/drivers/soc/apple/dockchannel.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/soc/apple/dockchannel.c +@@ -0,0 +1,406 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Apple DockChannel FIFO driver ++ * Copyright The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DOCKCHANNEL_MAX_IRQ 32 ++ ++#define DOCKCHANNEL_TX_TIMEOUT_MS 1000 ++#define DOCKCHANNEL_RX_TIMEOUT_MS 1000 ++ ++#define IRQ_MASK 0x0 ++#define IRQ_FLAG 0x4 ++ ++#define IRQ_TX BIT(0) ++#define IRQ_RX BIT(1) ++ ++#define CONFIG_TX_THRESH 0x0 ++#define CONFIG_RX_THRESH 0x4 ++ ++#define DATA_TX8 0x4 ++#define DATA_TX16 0x8 ++#define DATA_TX24 0xc ++#define DATA_TX32 0x10 ++#define DATA_TX_FREE 0x14 ++#define DATA_RX8 0x1c ++#define DATA_RX16 0x20 ++#define DATA_RX24 0x24 ++#define DATA_RX32 0x28 ++#define DATA_RX_COUNT 0x2c ++ ++struct dockchannel { ++ struct device *dev; ++ int tx_irq; ++ int rx_irq; ++ ++ void __iomem *config_base; ++ void __iomem *data_base; ++ ++ u32 fifo_size; ++ bool awaiting; ++ struct completion tx_comp; ++ struct completion rx_comp; ++ ++ void *cookie; ++ void (*data_available)(void *cookie, size_t avail); ++}; ++ ++struct dockchannel_common { ++ struct device *dev; ++ struct irq_domain *domain; ++ int irq; ++ ++ void __iomem *irq_base; ++}; ++ ++/* Dockchannel FIFO functions */ ++ ++static irqreturn_t dockchannel_tx_irq(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ ++ disable_irq_nosync(irq); ++ complete(&dockchannel->tx_comp); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t dockchannel_rx_irq(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ ++ disable_irq_nosync(irq); ++ ++ if (dockchannel->awaiting) { ++ return IRQ_WAKE_THREAD; ++ } else { ++ complete(&dockchannel->rx_comp); ++ return IRQ_HANDLED; ++ } ++} ++ ++static irqreturn_t dockchannel_rx_irq_thread(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_RX_COUNT); ++ ++ dockchannel->awaiting = false; ++ dockchannel->data_available(dockchannel->cookie, avail); ++ ++ return IRQ_HANDLED; ++} ++ ++int dockchannel_send(struct dockchannel *dockchannel, const void *buf, size_t count) ++{ ++ size_t left = count; ++ const u8 *p = buf; ++ ++ while (left > 0) { ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_TX_FREE); ++ size_t block = min(left, avail); ++ ++ if (avail == 0) { ++ size_t threshold = min((size_t)(dockchannel->fifo_size / 2), left); ++ ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_TX_THRESH); ++ reinit_completion(&dockchannel->tx_comp); ++ enable_irq(dockchannel->tx_irq); ++ ++ if (!wait_for_completion_timeout(&dockchannel->tx_comp, ++ msecs_to_jiffies(DOCKCHANNEL_TX_TIMEOUT_MS))) { ++ disable_irq(dockchannel->tx_irq); ++ return -ETIMEDOUT; ++ } ++ ++ continue; ++ } ++ ++ while (block >= 4) { ++ writel_relaxed(get_unaligned_le32(p), dockchannel->data_base + DATA_TX32); ++ p += 4; ++ left -= 4; ++ block -= 4; ++ } ++ while (block > 0) { ++ writeb_relaxed(*p++, dockchannel->data_base + DATA_TX8); ++ left--; ++ block--; ++ } ++ } ++ ++ return count; ++} ++EXPORT_SYMBOL(dockchannel_send); ++ ++int dockchannel_recv(struct dockchannel *dockchannel, void *buf, size_t count) ++{ ++ size_t left = count; ++ u8 *p = buf; ++ ++ while (left > 0) { ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_RX_COUNT); ++ size_t block = min(left, avail); ++ ++ if (avail == 0) { ++ size_t threshold = min((size_t)(dockchannel->fifo_size / 2), left); ++ ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_RX_THRESH); ++ reinit_completion(&dockchannel->rx_comp); ++ enable_irq(dockchannel->rx_irq); ++ ++ if (!wait_for_completion_timeout(&dockchannel->rx_comp, ++ msecs_to_jiffies(DOCKCHANNEL_RX_TIMEOUT_MS))) { ++ disable_irq(dockchannel->rx_irq); ++ return -ETIMEDOUT; ++ } ++ ++ continue; ++ } ++ ++ while (block >= 4) { ++ put_unaligned_le32(readl_relaxed(dockchannel->data_base + DATA_RX32), p); ++ p += 4; ++ left -= 4; ++ block -= 4; ++ } ++ while (block > 0) { ++ *p++ = readl_relaxed(dockchannel->data_base + DATA_RX8) >> 8; ++ left--; ++ block--; ++ } ++ } ++ ++ return count; ++} ++EXPORT_SYMBOL(dockchannel_recv); ++ ++int dockchannel_await(struct dockchannel *dockchannel, ++ void (*callback)(void *cookie, size_t avail), ++ void *cookie, size_t count) ++{ ++ size_t threshold = min((size_t)dockchannel->fifo_size, count); ++ ++ if (!count) { ++ dockchannel->awaiting = false; ++ disable_irq(dockchannel->rx_irq); ++ return 0; ++ } ++ ++ dockchannel->data_available = callback; ++ dockchannel->cookie = cookie; ++ dockchannel->awaiting = true; ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_RX_THRESH); ++ enable_irq(dockchannel->rx_irq); ++ ++ return threshold; ++} ++EXPORT_SYMBOL(dockchannel_await); ++ ++struct dockchannel *dockchannel_init(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel *dockchannel; ++ int ret; ++ ++ dockchannel = devm_kzalloc(dev, sizeof(*dockchannel), GFP_KERNEL); ++ if (!dockchannel) ++ return ERR_PTR(-ENOMEM); ++ ++ dockchannel->dev = dev; ++ dockchannel->config_base = devm_platform_ioremap_resource_byname(pdev, "config"); ++ if (IS_ERR(dockchannel->config_base)) ++ return (__force void *)dockchannel->config_base; ++ ++ dockchannel->data_base = devm_platform_ioremap_resource_byname(pdev, "data"); ++ if (IS_ERR(dockchannel->data_base)) ++ return (__force void *)dockchannel->data_base; ++ ++ ret = of_property_read_u32(dev->of_node, "apple,fifo-size", &dockchannel->fifo_size); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Missing apple,fifo-size property")); ++ ++ init_completion(&dockchannel->tx_comp); ++ init_completion(&dockchannel->rx_comp); ++ ++ dockchannel->tx_irq = platform_get_irq_byname(pdev, "tx"); ++ if (dockchannel->tx_irq <= 0) { ++ return ERR_PTR(dev_err_probe(dev, dockchannel->tx_irq, ++ "Failed to get TX IRQ")); ++ } ++ ++ dockchannel->rx_irq = platform_get_irq_byname(pdev, "rx"); ++ if (dockchannel->rx_irq <= 0) { ++ return ERR_PTR(dev_err_probe(dev, dockchannel->rx_irq, ++ "Failed to get RX IRQ")); ++ } ++ ++ ret = devm_request_irq(dev, dockchannel->tx_irq, dockchannel_tx_irq, IRQF_NO_AUTOEN, ++ "apple-dockchannel-tx", dockchannel); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Failed to request TX IRQ")); ++ ++ ret = devm_request_threaded_irq(dev, dockchannel->rx_irq, dockchannel_rx_irq, ++ dockchannel_rx_irq_thread, IRQF_NO_AUTOEN, ++ "apple-dockchannel-rx", dockchannel); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Failed to request RX IRQ")); ++ ++ return dockchannel; ++} ++EXPORT_SYMBOL(dockchannel_init); ++ ++ ++/* Dockchannel IRQchip */ ++ ++static void dockchannel_irq(struct irq_desc *desc) ++{ ++ unsigned int irq = irq_desc_get_irq(desc); ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ struct dockchannel_common *dcc = irq_get_handler_data(irq); ++ unsigned long flags = readl_relaxed(dcc->irq_base + IRQ_FLAG); ++ int bit; ++ ++ chained_irq_enter(chip, desc); ++ ++ for_each_set_bit(bit, &flags, DOCKCHANNEL_MAX_IRQ) ++ generic_handle_domain_irq(dcc->domain, bit); ++ ++ chained_irq_exit(chip, desc); ++} ++ ++static void dockchannel_irq_ack(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ ++ writel_relaxed(BIT(hwirq), dcc->irq_base + IRQ_FLAG); ++} ++ ++static void dockchannel_irq_mask(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ u32 val = readl_relaxed(dcc->irq_base + IRQ_MASK); ++ ++ writel_relaxed(val & ~BIT(hwirq), dcc->irq_base + IRQ_MASK); ++} ++ ++static void dockchannel_irq_unmask(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ u32 val = readl_relaxed(dcc->irq_base + IRQ_MASK); ++ ++ writel_relaxed(val | BIT(hwirq), dcc->irq_base + IRQ_MASK); ++} ++ ++static const struct irq_chip dockchannel_irqchip = { ++ .name = "dockchannel-irqc", ++ .irq_ack = dockchannel_irq_ack, ++ .irq_mask = dockchannel_irq_mask, ++ .irq_unmask = dockchannel_irq_unmask, ++}; ++ ++static int dockchannel_irq_domain_map(struct irq_domain *d, unsigned int virq, ++ irq_hw_number_t hw) ++{ ++ irq_set_chip_data(virq, d->host_data); ++ irq_set_chip_and_handler(virq, &dockchannel_irqchip, handle_level_irq); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops dockchannel_irq_domain_ops = { ++ .xlate = irq_domain_xlate_twocell, ++ .map = dockchannel_irq_domain_map, ++}; ++ ++static int dockchannel_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel_common *dcc; ++ struct device_node *child; ++ ++ dcc = devm_kzalloc(dev, sizeof(*dcc), GFP_KERNEL); ++ if (!dcc) ++ return -ENOMEM; ++ ++ dcc->dev = dev; ++ platform_set_drvdata(pdev, dcc); ++ ++ dcc->irq_base = devm_platform_ioremap_resource_byname(pdev, "irq"); ++ if (IS_ERR(dcc->irq_base)) ++ return PTR_ERR(dcc->irq_base); ++ ++ writel_relaxed(0, dcc->irq_base + IRQ_MASK); ++ writel_relaxed(~0, dcc->irq_base + IRQ_FLAG); ++ ++ dcc->domain = irq_domain_add_linear(dev->of_node, DOCKCHANNEL_MAX_IRQ, ++ &dockchannel_irq_domain_ops, dcc); ++ if (!dcc->domain) ++ return -ENOMEM; ++ ++ dcc->irq = platform_get_irq(pdev, 0); ++ if (dcc->irq <= 0) ++ return dev_err_probe(dev, dcc->irq, "Failed to get IRQ"); ++ ++ irq_set_handler_data(dcc->irq, dcc); ++ irq_set_chained_handler(dcc->irq, dockchannel_irq); ++ ++ for_each_child_of_node(dev->of_node, child) ++ of_platform_device_create(child, NULL, dev); ++ ++ return 0; ++} ++ ++static void dockchannel_remove(struct platform_device *pdev) ++{ ++ struct dockchannel_common *dcc = platform_get_drvdata(pdev); ++ int hwirq; ++ ++ device_for_each_child(&pdev->dev, NULL, of_platform_device_destroy); ++ ++ irq_set_chained_handler_and_data(dcc->irq, NULL, NULL); ++ ++ for (hwirq = 0; hwirq < DOCKCHANNEL_MAX_IRQ; hwirq++) ++ irq_dispose_mapping(irq_find_mapping(dcc->domain, hwirq)); ++ ++ irq_domain_remove(dcc->domain); ++ ++ writel_relaxed(0, dcc->irq_base + IRQ_MASK); ++ writel_relaxed(~0, dcc->irq_base + IRQ_FLAG); ++} ++ ++static const struct of_device_id dockchannel_of_match[] = { ++ { .compatible = "apple,dockchannel" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dockchannel_of_match); ++ ++static struct platform_driver dockchannel_driver = { ++ .driver = { ++ .name = "dockchannel", ++ .of_match_table = dockchannel_of_match, ++ }, ++ .probe = dockchannel_probe, ++ .remove = dockchannel_remove, ++}; ++module_platform_driver(dockchannel_driver); ++ ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_DESCRIPTION("Apple DockChannel driver"); +diff --git a/include/linux/soc/apple/dockchannel.h b/include/linux/soc/apple/dockchannel.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/linux/soc/apple/dockchannel.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ ++/* ++ * Apple Dockchannel devices ++ * Copyright (C) The Asahi Linux Contributors ++ */ ++#ifndef _LINUX_APPLE_DOCKCHANNEL_H_ ++#define _LINUX_APPLE_DOCKCHANNEL_H_ ++ ++#include ++#include ++#include ++ ++#if IS_ENABLED(CONFIG_APPLE_DOCKCHANNEL) ++ ++struct dockchannel; ++ ++struct dockchannel *dockchannel_init(struct platform_device *pdev); ++ ++int dockchannel_send(struct dockchannel *dockchannel, const void *buf, size_t count); ++int dockchannel_recv(struct dockchannel *dockchannel, void *buf, size_t count); ++int dockchannel_await(struct dockchannel *dockchannel, ++ void (*callback)(void *cookie, size_t avail), ++ void *cookie, size_t count); ++ ++#endif ++#endif +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:11:21 +0900 +Subject: hid: Add Apple DockChannel HID transport driver + +Apple M2 devices have an MTP coprocessor embedded in the SoC that +handles HID for the integrated touchpad/keyboard, and communicates +over the DockChannel interface. This driver implements this new +interface. + +Signed-off-by: Hector Martin +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 2 + + drivers/hid/dockchannel-hid/Kconfig | 14 + + drivers/hid/dockchannel-hid/Makefile | 6 + + drivers/hid/dockchannel-hid/dockchannel-hid.c | 1213 ++++++++++ + 5 files changed, 1237 insertions(+) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1418,4 +1418,6 @@ source "drivers/hid/surface-hid/Kconfig" + + source "drivers/hid/spi-hid/Kconfig" + ++source "drivers/hid/dockchannel-hid/Kconfig" ++ + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -174,3 +174,5 @@ obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + + obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ ++ ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ +diff --git a/drivers/hid/dockchannel-hid/Kconfig b/drivers/hid/dockchannel-hid/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/Kconfig +@@ -0,0 +1,14 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++menu "DockChannel HID support" ++ depends on APPLE_DOCKCHANNEL ++ ++config HID_DOCKCHANNEL ++ tristate "HID over DockChannel transport layer for Apple Silicon SoCs" ++ default ARCH_APPLE ++ depends on APPLE_DOCKCHANNEL && INPUT && OF && HID ++ help ++ Say Y here if you use an M2 or later Apple Silicon based laptop. ++ The keyboard and touchpad are HID based devices connected via the ++ proprietary DockChannel interface. ++ ++endmenu +diff --git a/drivers/hid/dockchannel-hid/Makefile b/drivers/hid/dockchannel-hid/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/Makefile +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++# ++# Makefile for DockChannel HID transport drivers ++# ++ ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid.o +diff --git a/drivers/hid/dockchannel-hid/dockchannel-hid.c b/drivers/hid/dockchannel-hid/dockchannel-hid.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/dockchannel-hid.c +@@ -0,0 +1,1213 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 OR MIT ++ * ++ * Apple DockChannel HID transport driver ++ * ++ * Copyright The Asahi Linux Contributors ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../hid-ids.h" ++ ++#define COMMAND_TIMEOUT_MS 1000 ++#define START_TIMEOUT_MS 2000 ++ ++#define MAX_INTERFACES 16 ++ ++/* Data + checksum */ ++#define MAX_PKT_SIZE (0xffff + 4) ++ ++#define DCHID_CHANNEL_CMD 0x11 ++#define DCHID_CHANNEL_REPORT 0x12 ++ ++struct dchid_hdr { ++ u8 hdr_len; ++ u8 channel; ++ u16 length; ++ u8 seq; ++ u8 iface; ++ u16 pad; ++} __packed; ++ ++#define IFACE_COMM 0 ++ ++#define FLAGS_GROUP GENMASK(7, 6) ++#define FLAGS_REQ GENMASK(5, 0) ++ ++#define REQ_SET_REPORT 0 ++#define REQ_GET_REPORT 1 ++ ++struct dchid_subhdr { ++ u8 flags; ++ u8 unk; ++ u16 length; ++ u32 retcode; ++} __packed; ++ ++#define EVENT_GPIO_CMD 0xa0 ++#define EVENT_INIT 0xf0 ++#define EVENT_READY 0xf1 ++ ++struct dchid_init_hdr { ++ u8 type; ++ u8 unk1; ++ u8 unk2; ++ u8 iface; ++ char name[16]; ++ u8 more_packets; ++ u8 unkpad; ++} __packed; ++ ++#define INIT_HID_DESCRIPTOR 0 ++#define INIT_GPIO_REQUEST 1 ++#define INIT_TERMINATOR 2 ++#define INIT_PRODUCT_NAME 7 ++ ++#define CMD_RESET_INTERFACE 0x40 ++#define CMD_SEND_FIRMWARE 0x95 ++#define CMD_ENABLE_INTERFACE 0xb4 ++#define CMD_ACK_GPIO_CMD 0xa1 ++ ++struct dchid_init_block_hdr { ++ u16 type; ++ u16 length; ++} __packed; ++ ++#define MAX_GPIO_NAME 32 ++ ++struct dchid_gpio_request { ++ u16 unk; ++ u16 id; ++ char name[MAX_GPIO_NAME]; ++} __packed; ++ ++struct dchid_gpio_cmd { ++ u8 type; ++ u8 iface; ++ u8 gpio; ++ u8 unk; ++ u8 cmd; ++} __packed; ++ ++struct dchid_gpio_ack { ++ u8 type; ++ u32 retcode; ++ u8 cmd[]; ++} __packed; ++ ++#define STM_REPORT_ID 0x10 ++#define STM_REPORT_SERIAL 0x11 ++#define STM_REPORT_KEYBTYPE 0x14 ++ ++struct dchid_stm_id { ++ u8 unk; ++ u16 vendor_id; ++ u16 product_id; ++ u16 version_number; ++ u8 unk2; ++ u8 unk3; ++ u8 keyboard_type; ++ u8 serial_length; ++ /* Serial follows, but we grab it with a different report. */ ++} __packed; ++ ++#define FW_MAGIC 0x46444948 ++#define FW_VER 1 ++ ++struct fw_header { ++ u32 magic; ++ u32 version; ++ u32 hdr_length; ++ u32 data_length; ++ u32 iface_offset; ++} __packed; ++ ++struct dchid_work { ++ struct work_struct work; ++ struct dchid_iface *iface; ++ ++ struct dchid_hdr hdr; ++ u8 data[]; ++}; ++ ++struct dchid_iface { ++ struct dockchannel_hid *dchid; ++ struct hid_device *hid; ++ struct workqueue_struct *wq; ++ ++ bool creating; ++ struct work_struct create_work; ++ ++ int index; ++ const char *name; ++ const struct device_node *of_node; ++ ++ uint8_t tx_seq; ++ bool deferred; ++ bool starting; ++ bool open; ++ struct completion ready; ++ ++ void *hid_desc; ++ size_t hid_desc_len; ++ ++ struct gpio_desc *gpio; ++ char gpio_name[MAX_GPIO_NAME]; ++ int gpio_id; ++ ++ struct mutex out_mutex; ++ u32 out_flags; ++ int out_report; ++ u32 retcode; ++ void *resp_buf; ++ size_t resp_size; ++ struct completion out_complete; ++ ++ u32 keyboard_layout_id; ++}; ++ ++struct dockchannel_hid { ++ struct device *dev; ++ struct dockchannel *dc; ++ struct device_link *helper_link; ++ ++ bool id_ready; ++ struct dchid_stm_id device_id; ++ char serial[64]; ++ ++ struct dchid_iface *comm; ++ struct dchid_iface *ifaces[MAX_INTERFACES]; ++ ++ u8 pkt_buf[MAX_PKT_SIZE]; ++ ++ /* Workqueue to asynchronously create HID devices */ ++ struct workqueue_struct *new_iface_wq; ++}; ++ ++static ssize_t apple_layout_id_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct hid_device *hdev = to_hid_device(dev); ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ return scnprintf(buf, PAGE_SIZE, "%d\n", iface->keyboard_layout_id); ++} ++ ++static DEVICE_ATTR_RO(apple_layout_id); ++ ++static struct dchid_iface * ++dchid_get_interface(struct dockchannel_hid *dchid, int index, const char *name) ++{ ++ struct dchid_iface *iface; ++ ++ if (index >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Interface index %d out of range\n", index); ++ return NULL; ++ } ++ ++ if (dchid->ifaces[index]) ++ return dchid->ifaces[index]; ++ ++ iface = devm_kzalloc(dchid->dev, sizeof(struct dchid_iface), GFP_KERNEL); ++ if (!iface) ++ return NULL; ++ ++ iface->index = index; ++ iface->name = devm_kstrdup(dchid->dev, name, GFP_KERNEL); ++ iface->dchid = dchid; ++ iface->out_report= -1; ++ init_completion(&iface->out_complete); ++ init_completion(&iface->ready); ++ mutex_init(&iface->out_mutex); ++ iface->wq = alloc_ordered_workqueue("dchid-%s", WQ_MEM_RECLAIM, iface->name); ++ if (!iface->wq) ++ return NULL; ++ ++ /* Comm is not a HID subdevice */ ++ if (!strcmp(name, "comm")) { ++ dchid->ifaces[index] = iface; ++ return iface; ++ } ++ ++ iface->of_node = of_get_child_by_name(dchid->dev->of_node, name); ++ if (!iface->of_node) { ++ dev_warn(dchid->dev, "No OF node for subdevice %s, ignoring.", name); ++ return NULL; ++ } ++ ++ dchid->ifaces[index] = iface; ++ return iface; ++} ++ ++static u32 dchid_checksum(void *p, size_t length) ++{ ++ u32 sum = 0; ++ ++ while (length >= 4) { ++ sum += get_unaligned_le32(p); ++ p += 4; ++ length -= 4; ++ } ++ ++ WARN_ON_ONCE(length); ++ return sum; ++} ++ ++static int dchid_send(struct dchid_iface *iface, u32 flags, void *msg, size_t size) ++{ ++ u32 checksum = 0xffffffff; ++ size_t wsize = round_down(size, 4); ++ size_t tsize = size - wsize; ++ int ret; ++ struct { ++ struct dchid_hdr hdr; ++ struct dchid_subhdr sub; ++ } __packed h; ++ ++ memset(&h, 0, sizeof(h)); ++ h.hdr.hdr_len = sizeof(h.hdr); ++ h.hdr.channel = DCHID_CHANNEL_CMD; ++ h.hdr.length = round_up(size, 4) + sizeof(h.sub); ++ h.hdr.seq = iface->tx_seq; ++ h.hdr.iface = iface->index; ++ h.sub.flags = flags; ++ h.sub.length = size; ++ ++ ret = dockchannel_send(iface->dchid->dc, &h, sizeof(h)); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(&h, sizeof(h)); ++ ++ ret = dockchannel_send(iface->dchid->dc, msg, wsize); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(msg, wsize); ++ ++ if (tsize) { ++ u8 tail[4] = {0, 0, 0, 0}; ++ ++ memcpy(tail, msg + wsize, tsize); ++ ret = dockchannel_send(iface->dchid->dc, tail, sizeof(tail)); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(tail, sizeof(tail)); ++ } ++ ++ ret = dockchannel_send(iface->dchid->dc, &checksum, sizeof(checksum)); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int dchid_cmd(struct dchid_iface *iface, u32 type, u32 req, ++ void *data, size_t size, void *resp_buf, size_t resp_size) ++{ ++ int ret; ++ int report_id = *(u8*)data; ++ ++ mutex_lock(&iface->out_mutex); ++ ++ WARN_ON(iface->out_report != -1); ++ iface->out_report = report_id; ++ iface->out_flags = FIELD_PREP(FLAGS_GROUP, type) | FIELD_PREP(FLAGS_REQ, req); ++ iface->resp_buf = resp_buf; ++ iface->resp_size = resp_size; ++ reinit_completion(&iface->out_complete); ++ ++ ret = dchid_send(iface, iface->out_flags, data, size); ++ if (ret < 0) ++ goto done; ++ ++ if (!wait_for_completion_timeout(&iface->out_complete, msecs_to_jiffies(COMMAND_TIMEOUT_MS))) { ++ dev_err(iface->dchid->dev, "output report 0x%x to iface %d (%s) timed out\n", ++ report_id, iface->index, iface->name); ++ ret = -ETIMEDOUT; ++ goto done; ++ } ++ ++ ret = iface->resp_size; ++ if (iface->retcode) { ++ dev_err(iface->dchid->dev, ++ "output report 0x%x to iface %d (%s) failed with err 0x%x\n", ++ report_id, iface->index, iface->name, iface->retcode); ++ ret = -EIO; ++ } ++ ++done: ++ iface->tx_seq++; ++ iface->out_report = -1; ++ iface->out_flags = 0; ++ iface->resp_buf = NULL; ++ iface->resp_size = 0; ++ mutex_unlock(&iface->out_mutex); ++ return ret; ++} ++ ++static int dchid_comm_cmd(struct dockchannel_hid *dchid, void *cmd, size_t size) ++{ ++ return dchid_cmd(dchid->comm, HID_FEATURE_REPORT, REQ_SET_REPORT, cmd, size, NULL, 0); ++} ++ ++static int dchid_enable_interface(struct dchid_iface *iface) ++{ ++ u8 msg[] = { CMD_ENABLE_INTERFACE, iface->index }; ++ ++ return dchid_comm_cmd(iface->dchid, msg, sizeof(msg)); ++} ++ ++static int dchid_reset_interface(struct dchid_iface *iface, int state) ++{ ++ u8 msg[] = { CMD_RESET_INTERFACE, 1, iface->index, state }; ++ ++ return dchid_comm_cmd(iface->dchid, msg, sizeof(msg)); ++} ++ ++static int dchid_send_firmware(struct dchid_iface *iface, void *firmware, size_t size) ++{ ++ struct { ++ u8 cmd; ++ u8 unk1; ++ u8 unk2; ++ u8 iface; ++ u64 addr; ++ u32 size; ++ } __packed msg = { ++ .cmd = CMD_SEND_FIRMWARE, ++ .unk1 = 2, ++ .unk2 = 0, ++ .iface = iface->index, ++ .size = size, ++ }; ++ dma_addr_t addr; ++ void *buf = dmam_alloc_coherent(iface->dchid->dev, size, &addr, GFP_KERNEL); ++ ++ if (IS_ERR_OR_NULL(buf)) ++ return buf ? PTR_ERR(buf) : -ENOMEM; ++ ++ msg.addr = addr; ++ memcpy(buf, firmware, size); ++ wmb(); ++ ++ return dchid_comm_cmd(iface->dchid, &msg, sizeof(msg)); ++} ++ ++static int dchid_get_firmware(struct dchid_iface *iface, void **firmware, size_t *size) ++{ ++ int ret; ++ const char *fw_name; ++ const struct firmware *fw; ++ struct fw_header *hdr; ++ u8 *fw_data; ++ ++ ret = of_property_read_string(iface->of_node, "firmware-name", &fw_name); ++ if (ret) { ++ /* Firmware is only for some devices */ ++ *firmware = NULL; ++ *size = 0; ++ return 0; ++ } ++ ++ ret = request_firmware(&fw, fw_name, iface->dchid->dev); ++ if (ret) ++ return ret; ++ ++ hdr = (struct fw_header *)fw->data; ++ ++ if (hdr->magic != FW_MAGIC || hdr->version != FW_VER || ++ hdr->hdr_length < sizeof(*hdr) || hdr->hdr_length > fw->size || ++ (hdr->hdr_length + (size_t)hdr->data_length) > fw->size || ++ hdr->iface_offset >= hdr->data_length) { ++ dev_warn(iface->dchid->dev, "%s: invalid firmware header\n", ++ fw_name); ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ fw_data = devm_kmemdup(iface->dchid->dev, fw->data + hdr->hdr_length, ++ hdr->data_length, GFP_KERNEL); ++ if (!fw_data) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ if (hdr->iface_offset) ++ fw_data[hdr->iface_offset] = iface->index; ++ ++ *firmware = fw_data; ++ *size = hdr->data_length; ++ ++done: ++ release_firmware(fw); ++ return ret; ++} ++ ++static int dchid_request_gpio(struct dchid_iface *iface) ++{ ++ char prop_name[MAX_GPIO_NAME + 16]; ++ ++ if (iface->gpio) ++ return 0; ++ ++ dev_info(iface->dchid->dev, "Requesting GPIO %s#%d: %s\n", ++ iface->name, iface->gpio_id, iface->gpio_name); ++ ++ snprintf(prop_name, sizeof(prop_name), "apple,%s", iface->gpio_name); ++ ++ iface->gpio = devm_gpiod_get_index(iface->dchid->dev, prop_name, 0, GPIOD_OUT_LOW); ++ ++ if (IS_ERR_OR_NULL(iface->gpio)) { ++ dev_err(iface->dchid->dev, "Failed to request GPIO %s-gpios\n", prop_name); ++ iface->gpio = NULL; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int dchid_start_interface(struct dchid_iface *iface) ++{ ++ void *fw; ++ size_t size; ++ int ret; ++ ++ if (iface->starting) { ++ dev_warn(iface->dchid->dev, "Interface %s is already starting", iface->name); ++ return -EINPROGRESS; ++ } ++ ++ dev_info(iface->dchid->dev, "Starting interface %s\n", iface->name); ++ ++ iface->starting = true; ++ ++ /* Look to see if we need firmware */ ++ ret = dchid_get_firmware(iface, &fw, &size); ++ if (ret < 0) ++ goto err; ++ ++ /* If we need a GPIO, make sure we have it. */ ++ if (iface->gpio_id) { ++ ret = dchid_request_gpio(iface); ++ if (ret < 0) ++ goto err; ++ } ++ ++ /* Only multi-touch has firmware */ ++ if (fw && size) { ++ ++ /* Send firmware to the device */ ++ dev_info(iface->dchid->dev, "Sending firmware for %s\n", iface->name); ++ ret = dchid_send_firmware(iface, fw, size); ++ if (ret < 0) { ++ dev_err(iface->dchid->dev, "Failed to send %s firmwareS", iface->name); ++ goto err; ++ } ++ ++ /* After loading firmware, multi-touch needs a reset */ ++ dev_info(iface->dchid->dev, "Resetting %s\n", iface->name); ++ dchid_reset_interface(iface, 0); ++ dchid_reset_interface(iface, 2); ++ } ++ ++ return 0; ++ ++err: ++ iface->starting = false; ++ return ret; ++} ++ ++static int dchid_start(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ if (iface->keyboard_layout_id) { ++ int ret = device_create_file(&hdev->dev, &dev_attr_apple_layout_id); ++ if (ret) { ++ dev_warn(iface->dchid->dev, "Failed to create apple_layout_id: %d", ret); ++ iface->keyboard_layout_id = 0; ++ } ++ } ++ ++ return 0; ++}; ++ ++static void dchid_stop(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ if (iface->keyboard_layout_id) ++ device_remove_file(&hdev->dev, &dev_attr_apple_layout_id); ++} ++ ++static int dchid_open(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ int ret; ++ ++ if (!completion_done(&iface->ready)) { ++ ret = dchid_start_interface(iface); ++ if (ret < 0) ++ return ret; ++ ++ if (!wait_for_completion_timeout(&iface->ready, msecs_to_jiffies(START_TIMEOUT_MS))) { ++ dev_err(iface->dchid->dev, "iface %s start timed out\n", iface->name); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ iface->open = true; ++ return 0; ++} ++ ++static void dchid_close(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ iface->open = false; ++} ++ ++static int dchid_parse(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ return hid_parse_report(hdev, iface->hid_desc, iface->hid_desc_len); ++} ++ ++/* Note: buf excludes report number! For ease of fetching strings/etc. */ ++static int dchid_get_report_cmd(struct dchid_iface *iface, u8 reportnum, void *buf, size_t len) ++{ ++ int ret = dchid_cmd(iface, HID_FEATURE_REPORT, REQ_GET_REPORT, &reportnum, 1, buf, len); ++ ++ return ret <= 0 ? ret : ret - 1; ++} ++ ++/* Note: buf includes report number! */ ++static int dchid_set_report(struct dchid_iface *iface, void *buf, size_t len) ++{ ++ return dchid_cmd(iface, HID_OUTPUT_REPORT, REQ_SET_REPORT, buf, len, NULL, 0); ++} ++ ++static int dchid_raw_request(struct hid_device *hdev, ++ unsigned char reportnum, __u8 *buf, size_t len, ++ unsigned char rtype, int reqtype) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ switch (reqtype) { ++ case HID_REQ_GET_REPORT: ++ buf[0] = reportnum; ++ return dchid_cmd(iface, rtype, REQ_GET_REPORT, &reportnum, 1, buf + 1, len - 1); ++ case HID_REQ_SET_REPORT: ++ return dchid_set_report(iface, buf, len); ++ default: ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static struct hid_ll_driver dchid_ll = { ++ .start = &dchid_start, ++ .stop = &dchid_stop, ++ .open = &dchid_open, ++ .close = &dchid_close, ++ .parse = &dchid_parse, ++ .raw_request = &dchid_raw_request, ++}; ++ ++static void dchid_create_interface_work(struct work_struct *ws) ++{ ++ struct dchid_iface *iface = container_of(ws, struct dchid_iface, create_work); ++ struct dockchannel_hid *dchid = iface->dchid; ++ struct hid_device *hid; ++ int ret; ++ ++ if (iface->hid) { ++ dev_warn(dchid->dev, "Interface %s already created!\n", ++ iface->name); ++ return; ++ } ++ ++ dev_info(dchid->dev, "New interface %s\n", iface->name); ++ ++ /* Start the interface. This is not the entire init process, as firmware is loaded later on device open. */ ++ ret = dchid_enable_interface(iface); ++ if (ret < 0) { ++ dev_warn(dchid->dev, "Failed to enable %s: %d\n", iface->name, ret); ++ return; ++ } ++ ++ iface->deferred = false; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return; ++ ++ snprintf(hid->name, sizeof(hid->name), "Apple MTP %s", iface->name); ++ snprintf(hid->phys, sizeof(hid->phys), "%s.%d (%s)", ++ dev_name(dchid->dev), iface->index, iface->name); ++ strscpy(hid->uniq, dchid->serial, sizeof(hid->uniq)); ++ ++ hid->ll_driver = &dchid_ll; ++ hid->bus = BUS_HOST; ++ hid->vendor = dchid->device_id.vendor_id; ++ hid->product = dchid->device_id.product_id; ++ hid->version = dchid->device_id.version_number; ++ hid->type = HID_TYPE_OTHER; ++ if (!strcmp(iface->name, "multi-touch")) { ++ hid->type = HID_TYPE_SPI_MOUSE; ++ } else if (!strcmp(iface->name, "keyboard")) { ++ u32 country_code = 0; ++ ++ hid->type = HID_TYPE_SPI_KEYBOARD; ++ ++ /* ++ * We have to get the country code from the device tree, since the ++ * device provides no reliable way to get this info. ++ */ ++ if (!of_property_read_u32(iface->of_node, "hid-country-code", &country_code)) ++ hid->country = country_code; ++ ++ of_property_read_u32(iface->of_node, "apple,keyboard-layout-id", ++ &iface->keyboard_layout_id); ++ } ++ ++ hid->dev.parent = iface->dchid->dev; ++ hid->driver_data = iface; ++ ++ iface->hid = hid; ++ ++ ret = hid_add_device(hid); ++ if (ret < 0) { ++ iface->hid = NULL; ++ hid_destroy_device(hid); ++ dev_warn(iface->dchid->dev, "Failed to register hid device %s", iface->name); ++ } ++} ++ ++static int dchid_create_interface(struct dchid_iface *iface) ++{ ++ if (iface->creating) ++ return -EBUSY; ++ ++ iface->creating = true; ++ INIT_WORK(&iface->create_work, dchid_create_interface_work); ++ return queue_work(iface->dchid->new_iface_wq, &iface->create_work); ++} ++ ++static void dchid_handle_descriptor(struct dchid_iface *iface, void *hid_desc, size_t desc_len) ++{ ++ if (iface->hid) { ++ dev_warn(iface->dchid->dev, "Tried to initialize already started interface %s!\n", ++ iface->name); ++ return; ++ } ++ ++ iface->hid_desc = devm_kmemdup(iface->dchid->dev, hid_desc, desc_len, GFP_KERNEL); ++ if (!iface->hid_desc) ++ return; ++ ++ iface->hid_desc_len = desc_len; ++} ++ ++static void dchid_handle_ready(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_iface *iface; ++ u8 *pkt = data; ++ u8 index; ++ int i, ret; ++ ++ if (length < 2) { ++ dev_err(dchid->dev, "Bad length for ready message: %zu\n", length); ++ return; ++ } ++ ++ index = pkt[1]; ++ ++ if (index >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Got ready notification for bad iface %d\n", index); ++ return; ++ } ++ ++ iface = dchid->ifaces[index]; ++ if (!iface) { ++ dev_err(dchid->dev, "Got ready notification for unknown iface %d\n", index); ++ return; ++ } ++ ++ dev_info(dchid->dev, "Interface %s is now ready\n", iface->name); ++ complete_all(&iface->ready); ++ ++ /* When STM is ready, grab global device info */ ++ if (!strcmp(iface->name, "stm")) { ++ ret = dchid_get_report_cmd(iface, STM_REPORT_ID, &dchid->device_id, ++ sizeof(dchid->device_id)); ++ if (ret < sizeof(dchid->device_id)) { ++ dev_warn(iface->dchid->dev, "Failed to get device ID from STM!\n"); ++ /* Fake it and keep going. Things might still work... */ ++ memset(&dchid->device_id, 0, sizeof(dchid->device_id)); ++ dchid->device_id.vendor_id = HOST_VENDOR_ID_APPLE; ++ } ++ ret = dchid_get_report_cmd(iface, STM_REPORT_SERIAL, dchid->serial, ++ sizeof(dchid->serial) - 1); ++ if (ret < 0) { ++ dev_warn(iface->dchid->dev, "Failed to get serial from STM!\n"); ++ dchid->serial[0] = 0; ++ } ++ ++ dchid->id_ready = true; ++ for (i = 0; i < MAX_INTERFACES; i++) { ++ if (!dchid->ifaces[i] || !dchid->ifaces[i]->deferred) ++ continue; ++ dchid_create_interface(dchid->ifaces[i]); ++ } ++ } ++} ++ ++static void dchid_handle_init(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_init_hdr *hdr = data; ++ struct dchid_iface *iface; ++ struct dchid_init_block_hdr *blk; ++ ++ if (length < sizeof(*hdr)) ++ return; ++ ++ iface = dchid_get_interface(dchid, hdr->iface, hdr->name); ++ if (!iface) ++ return; ++ ++ data += sizeof(*hdr); ++ length -= sizeof(*hdr); ++ ++ while (length >= sizeof(*blk)) { ++ blk = data; ++ data += sizeof(*blk); ++ length -= sizeof(*blk); ++ ++ if (blk->length > length) ++ break; ++ ++ switch (blk->type) { ++ case INIT_HID_DESCRIPTOR: ++ dchid_handle_descriptor(iface, data, blk->length); ++ break; ++ ++ case INIT_GPIO_REQUEST: { ++ struct dchid_gpio_request *req = data; ++ ++ if (sizeof(*req) > length) ++ break; ++ ++ if (iface->gpio_id) { ++ dev_err(dchid->dev, ++ "Cannot request more than one GPIO per interface!\n"); ++ break; ++ } ++ ++ strscpy(iface->gpio_name, req->name, MAX_GPIO_NAME); ++ iface->gpio_id = req->id; ++ break; ++ } ++ ++ case INIT_TERMINATOR: ++ break; ++ ++ case INIT_PRODUCT_NAME: { ++ char *product = data; ++ ++ if (product[blk->length - 1] != 0) { ++ dev_warn(dchid->dev, "Unterminated product name for %s\n", ++ iface->name); ++ } else { ++ dev_info(dchid->dev, "Product name for %s: %s\n", ++ iface->name, product); ++ } ++ break; ++ } ++ ++ default: ++ dev_warn(dchid->dev, "Unknown init packet %d for %s\n", ++ blk->type, iface->name); ++ break; ++ } ++ ++ data += blk->length; ++ length -= blk->length; ++ ++ if (blk->type == INIT_TERMINATOR) ++ break; ++ } ++ ++ if (hdr->more_packets) ++ return; ++ ++ /* We need to enable STM first, since it'll give us the device IDs */ ++ if (iface->dchid->id_ready || !strcmp(iface->name, "stm")) { ++ dchid_create_interface(iface); ++ } else { ++ iface->deferred = true; ++ } ++} ++ ++static void dchid_handle_gpio(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_gpio_cmd *cmd = data; ++ struct dchid_iface *iface; ++ u32 retcode = 0xe000f00d; /* Give it a random Apple-style error code */ ++ struct dchid_gpio_ack *ack; ++ ++ if (length < sizeof(*cmd)) ++ return; ++ ++ if (cmd->iface >= MAX_INTERFACES || !(iface = dchid->ifaces[cmd->iface])) { ++ dev_err(dchid->dev, "Got GPIO command for bad inteface %d\n", cmd->iface); ++ goto err; ++ } ++ ++ if (dchid_request_gpio(iface) < 0) ++ goto err; ++ ++ if (!iface->gpio || cmd->gpio != iface->gpio_id) { ++ dev_err(dchid->dev, "Got GPIO command for bad GPIO %s#%d\n", ++ iface->name, cmd->gpio); ++ goto err; ++ } ++ ++ dev_info(dchid->dev, "GPIO command: %s#%d: %d\n", iface->name, cmd->gpio, cmd->cmd); ++ ++ switch (cmd->cmd) { ++ case 3: ++ /* Pulse. */ ++ gpiod_set_value_cansleep(iface->gpio, 1); ++ msleep(10); /* Random guess... */ ++ gpiod_set_value_cansleep(iface->gpio, 0); ++ retcode = 0; ++ break; ++ default: ++ dev_err(dchid->dev, "Unknown GPIO command %d\n", cmd->cmd ); ++ break; ++ } ++ ++err: ++ /* Ack it */ ++ ack = kzalloc(sizeof(*ack) + length, GFP_KERNEL); ++ if (!ack) ++ return; ++ ++ ack->type = CMD_ACK_GPIO_CMD; ++ ack->retcode = retcode; ++ memcpy(ack->cmd, data, length); ++ ++ if (dchid_comm_cmd(dchid, ack, sizeof(*ack) + length) < 0) ++ dev_err(dchid->dev, "Failed to ACK GPIO command\n"); ++ ++ kfree(ack); ++} ++ ++static void dchid_handle_event(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ u8 *p = data; ++ switch (*p) { ++ case EVENT_INIT: ++ dchid_handle_init(dchid, data, length); ++ break; ++ case EVENT_READY: ++ dchid_handle_ready(dchid, data, length); ++ break; ++ case EVENT_GPIO_CMD: ++ dchid_handle_gpio(dchid, data, length); ++ break; ++ } ++} ++ ++static void dchid_handle_report(struct dchid_iface *iface, void *data, size_t length) ++{ ++ struct dockchannel_hid *dchid = iface->dchid; ++ ++ if (!iface->hid) { ++ dev_warn(dchid->dev, "Report received but %s is not initialized!\n", iface->name); ++ return; ++ } ++ ++ if (!iface->open) ++ return; ++ ++ hid_input_report(iface->hid, HID_INPUT_REPORT, data, length, 1); ++} ++ ++static void dchid_packet_work(struct work_struct *ws) ++{ ++ struct dchid_work *work = container_of(ws, struct dchid_work, work); ++ struct dchid_subhdr *shdr = (void *)work->data; ++ struct dockchannel_hid *dchid = work->iface->dchid; ++ int type = FIELD_GET(FLAGS_GROUP, shdr->flags); ++ u8 *payload = work->data + sizeof(*shdr); ++ ++ if (shdr->length + sizeof(*shdr) > work->hdr.length) { ++ dev_err(dchid->dev, "Bad sub header length (%d > %zu)\n", ++ shdr->length, work->hdr.length - sizeof(*shdr)); ++ return; ++ } ++ ++ switch (type) { ++ case HID_INPUT_REPORT: ++ if (work->hdr.iface == IFACE_COMM) ++ dchid_handle_event(dchid, payload, shdr->length); ++ else ++ dchid_handle_report(work->iface, payload, shdr->length); ++ break; ++ default: ++ dev_err(dchid->dev, "Received unknown packet type %d\n", type); ++ break; ++ } ++ ++ kfree(work); ++} ++ ++static void dchid_handle_ack(struct dchid_iface *iface, struct dchid_hdr *hdr, void *data) ++{ ++ struct dchid_subhdr *shdr = (void *)data; ++ u8 *payload = data + sizeof(*shdr); ++ ++ if (shdr->length + sizeof(*shdr) > hdr->length) { ++ dev_err(iface->dchid->dev, "Bad sub header length (%d > %ld)\n", ++ shdr->length, hdr->length - sizeof(*shdr)); ++ return; ++ } ++ if (shdr->flags != iface->out_flags) { ++ dev_err(iface->dchid->dev, ++ "Received unexpected flags 0x%x on ACK channel (expFected 0x%x)\n", ++ shdr->flags, iface->out_flags); ++ return; ++ } ++ ++ if (shdr->length < 1) { ++ dev_err(iface->dchid->dev, "Received length 0 output report ack\n"); ++ return; ++ } ++ if (iface->tx_seq != hdr->seq) { ++ dev_err(iface->dchid->dev, "Received ACK with bad seq (expected %d, got %d)\n", ++ iface->tx_seq, hdr->seq); ++ return; ++ } ++ if (iface->out_report != payload[0]) { ++ dev_err(iface->dchid->dev, "Received ACK with bad report (expected %d, got %d\n", ++ iface->out_report, payload[0]); ++ return; ++ } ++ ++ if (iface->resp_buf && iface->resp_size) ++ memcpy(iface->resp_buf, payload + 1, min((size_t)shdr->length - 1, iface->resp_size)); ++ ++ iface->resp_size = shdr->length; ++ iface->out_report = -1; ++ iface->retcode = shdr->retcode; ++ complete(&iface->out_complete); ++} ++ ++static void dchid_handle_packet(void *cookie, size_t avail) ++{ ++ struct dockchannel_hid *dchid = cookie; ++ struct dchid_hdr hdr; ++ struct dchid_work *work; ++ struct dchid_iface *iface; ++ u32 checksum; ++ ++ if (dockchannel_recv(dchid->dc, &hdr, sizeof(hdr)) != sizeof(hdr)) { ++ dev_err(dchid->dev, "Read failed (header)\n"); ++ return; ++ } ++ ++ if (hdr.hdr_len != sizeof(hdr)) { ++ dev_err(dchid->dev, "Bad header length %d\n", hdr.hdr_len); ++ goto done; ++ } ++ ++ if (dockchannel_recv(dchid->dc, dchid->pkt_buf, hdr.length + 4) != (hdr.length + 4)) { ++ dev_err(dchid->dev, "Read failed (body)\n"); ++ goto done; ++ } ++ ++ checksum = dchid_checksum(&hdr, sizeof(hdr)); ++ checksum += dchid_checksum(dchid->pkt_buf, hdr.length + 4); ++ ++ if (checksum != 0xffffffff) { ++ dev_err(dchid->dev, "Checksum mismatch (iface %d): 0x%08x != 0xffffffff\n", ++ hdr.iface, checksum); ++ goto done; ++ } ++ ++ ++ if (hdr.iface >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Bad iface %d\n", hdr.iface); ++ } ++ ++ iface = dchid->ifaces[hdr.iface]; ++ ++ if (!iface) { ++ dev_err(dchid->dev, "Received packet for uninitialized iface %d\n", hdr.iface); ++ goto done; ++ } ++ ++ switch (hdr.channel) { ++ case DCHID_CHANNEL_CMD: ++ dchid_handle_ack(iface, &hdr, dchid->pkt_buf); ++ goto done; ++ case DCHID_CHANNEL_REPORT: ++ break; ++ default: ++ dev_warn(dchid->dev, "Unknown channel 0x%x, treating as report...\n", ++ hdr.channel); ++ break; ++ } ++ ++ work = kzalloc(sizeof(*work) + hdr.length, GFP_KERNEL); ++ if (!work) ++ return; ++ ++ work->hdr = hdr; ++ work->iface = iface; ++ memcpy(work->data, dchid->pkt_buf, hdr.length); ++ INIT_WORK(&work->work, dchid_packet_work); ++ ++ queue_work(iface->wq, &work->work); ++ ++done: ++ dockchannel_await(dchid->dc, dchid_handle_packet, dchid, sizeof(struct dchid_hdr)); ++} ++ ++static int dockchannel_hid_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel_hid *dchid; ++ struct device_node *child, *helper; ++ struct platform_device *helper_pdev; ++ struct property *prop; ++ int ret; ++ ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); ++ if (ret) ++ return ret; ++ ++ dchid = devm_kzalloc(dev, sizeof(*dchid), GFP_KERNEL); ++ if (!dchid) { ++ return -ENOMEM; ++ } ++ ++ dchid->dev = dev; ++ ++ /* ++ * First make sure all the GPIOs are available, in cased we need to defer. ++ * This is necessary because MTP will request them by name later, and by then ++ * it's too late to defer the probe. ++ */ ++ ++ for_each_child_of_node(dev->of_node, child) { ++ for_each_property_of_node(child, prop) { ++ size_t len = strlen(prop->name); ++ struct gpio_desc *gpio; ++ ++ if (len < 12 || strncmp("apple,", prop->name, 6) || ++ strcmp("-gpios", prop->name + len - 6)) ++ continue; ++ ++ gpio = fwnode_gpiod_get_index(&child->fwnode, prop->name, 0, GPIOD_ASIS, ++ prop->name); ++ if (IS_ERR_OR_NULL(gpio)) { ++ if (PTR_ERR(gpio) == -EPROBE_DEFER) { ++ of_node_put(child); ++ return -EPROBE_DEFER; ++ } ++ } else { ++ gpiod_put(gpio); ++ } ++ } ++ } ++ ++ /* ++ * Make sure we also have the MTP coprocessor available, and ++ * defer probe if the helper hasn't probed yet. ++ */ ++ helper = of_parse_phandle(dev->of_node, "apple,helper-cpu", 0); ++ if (!helper) { ++ dev_err(dev, "Missing apple,helper-cpu property"); ++ return -EINVAL; ++ } ++ ++ helper_pdev = of_find_device_by_node(helper); ++ of_node_put(helper); ++ if (!helper_pdev) { ++ dev_err(dev, "Failed to find helper device"); ++ return -EINVAL; ++ } ++ ++ dchid->helper_link = device_link_add(dev, &helper_pdev->dev, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ put_device(&helper_pdev->dev); ++ if (!dchid->helper_link) { ++ dev_err(dev, "Failed to link to helper device"); ++ return -EINVAL; ++ } ++ ++ if (dchid->helper_link->supplier->links.status != DL_DEV_DRIVER_BOUND) ++ return -EPROBE_DEFER; ++ ++ /* Now it is safe to begin initializing */ ++ dchid->dc = dockchannel_init(pdev); ++ if (IS_ERR_OR_NULL(dchid->dc)) { ++ return PTR_ERR(dchid->dc); ++ } ++ dchid->new_iface_wq = alloc_workqueue("dchid-new", WQ_MEM_RECLAIM, 0); ++ if (!dchid->new_iface_wq) ++ return -ENOMEM; ++ ++ dchid->comm = dchid_get_interface(dchid, IFACE_COMM, "comm"); ++ if (!dchid->comm) { ++ dev_err(dchid->dev, "Failed to initialize comm interface"); ++ return -EIO; ++ } ++ ++ dev_info(dchid->dev, "Initialized, awaiting packets\n"); ++ dockchannel_await(dchid->dc, dchid_handle_packet, dchid, sizeof(struct dchid_hdr)); ++ ++ return 0; ++} ++ ++static void dockchannel_hid_remove(struct platform_device *pdev) ++{ ++ BUG_ON(1); ++} ++ ++static const struct of_device_id dockchannel_hid_of_match[] = { ++ { .compatible = "apple,dockchannel-hid" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dockchannel_hid_of_match); ++MODULE_FIRMWARE("apple/tpmtfw-*.bin"); ++ ++static struct platform_driver dockchannel_hid_driver = { ++ .driver = { ++ .name = "dockchannel-hid", ++ .of_match_table = dockchannel_hid_of_match, ++ }, ++ .probe = dockchannel_hid_probe, ++ .remove = dockchannel_hid_remove, ++}; ++module_platform_driver(dockchannel_hid_driver); ++ ++MODULE_DESCRIPTION("Apple DockChannel HID transport driver"); ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 3 Jul 2022 23:33:37 +0900 +Subject: soc: apple: Add RTKit helper driver + +This driver can be used for coprocessors that do some background task or +communicate out-of-band, and do not do any mailbox I/O beyond the +standard RTKit initialization. + +Signed-off-by: Hector Martin +--- + drivers/soc/apple/Kconfig | 14 + + drivers/soc/apple/Makefile | 3 + + drivers/soc/apple/rtkit-helper.c | 151 ++++++++++ + 3 files changed, 168 insertions(+) + +diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Kconfig ++++ b/drivers/soc/apple/Kconfig +@@ -40,6 +40,20 @@ config APPLE_RTKIT + + Say 'y' here if you have an Apple SoC. + ++config APPLE_RTKIT_HELPER ++ tristate "Apple Generic RTKit helper co-processor" ++ depends on APPLE_RTKIT ++ depends on ARCH_APPLE || COMPILE_TEST ++ default ARCH_APPLE ++ help ++ Apple SoCs such as the M1 come with various co-processors running ++ their proprietary RTKit operating system. This option enables support ++ for a generic co-processor that does not implement any additional ++ in-band communications. It can be used for testing purposes, or for ++ coprocessors such as MTP that communicate over a different interface. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_SART + tristate "Apple SART DMA address filter" + depends on ARCH_APPLE || COMPILE_TEST +diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Makefile ++++ b/drivers/soc/apple/Makefile +@@ -9,5 +9,8 @@ apple-mailbox-y = mailbox.o + obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o + apple-rtkit-y = rtkit.o rtkit-crashlog.o + ++obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o ++apple-rtkit-helper-y = rtkit-helper.o ++ + obj-$(CONFIG_APPLE_SART) += apple-sart.o + apple-sart-y = sart.o +diff --git a/drivers/soc/apple/rtkit-helper.c b/drivers/soc/apple/rtkit-helper.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/soc/apple/rtkit-helper.c +@@ -0,0 +1,151 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Apple Generic RTKit helper coprocessor ++ * Copyright The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define APPLE_ASC_CPU_CONTROL 0x44 ++#define APPLE_ASC_CPU_CONTROL_RUN BIT(4) ++ ++struct apple_rtkit_helper { ++ struct device *dev; ++ struct apple_rtkit *rtk; ++ ++ void __iomem *asc_base; ++ ++ struct resource *sram; ++ void __iomem *sram_base; ++}; ++ ++static int apple_rtkit_helper_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr) ++{ ++ struct apple_rtkit_helper *helper = cookie; ++ struct resource res = { ++ .start = bfr->iova, ++ .end = bfr->iova + bfr->size - 1, ++ .name = "rtkit_map", ++ }; ++ ++ if (!bfr->iova) { ++ bfr->buffer = dma_alloc_coherent(helper->dev, bfr->size, ++ &bfr->iova, GFP_KERNEL); ++ if (!bfr->buffer) ++ return -ENOMEM; ++ return 0; ++ } ++ ++ if (!helper->sram) { ++ dev_err(helper->dev, ++ "RTKit buffer request with no SRAM region: %pR", &res); ++ return -EFAULT; ++ } ++ ++ res.flags = helper->sram->flags; ++ ++ if (res.end < res.start || !resource_contains(helper->sram, &res)) { ++ dev_err(helper->dev, ++ "RTKit buffer request outside SRAM region: %pR", &res); ++ return -EFAULT; ++ } ++ ++ bfr->iomem = helper->sram_base + (res.start - helper->sram->start); ++ bfr->is_mapped = true; ++ ++ return 0; ++} ++ ++static void apple_rtkit_helper_shmem_destroy(void *cookie, struct apple_rtkit_shmem *bfr) ++{ ++ // no-op ++} ++ ++static const struct apple_rtkit_ops apple_rtkit_helper_ops = { ++ .shmem_setup = apple_rtkit_helper_shmem_setup, ++ .shmem_destroy = apple_rtkit_helper_shmem_destroy, ++}; ++ ++static int apple_rtkit_helper_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct apple_rtkit_helper *helper; ++ int ret; ++ ++ /* 44 bits for addresses in standard RTKit requests */ ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); ++ if (ret) ++ return ret; ++ ++ helper = devm_kzalloc(dev, sizeof(*helper), GFP_KERNEL); ++ if (!helper) ++ return -ENOMEM; ++ ++ helper->dev = dev; ++ platform_set_drvdata(pdev, helper); ++ ++ helper->asc_base = devm_platform_ioremap_resource_byname(pdev, "asc"); ++ if (IS_ERR(helper->asc_base)) ++ return PTR_ERR(helper->asc_base); ++ ++ helper->sram = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); ++ if (helper->sram) { ++ helper->sram_base = devm_ioremap_resource(dev, helper->sram); ++ if (IS_ERR(helper->sram_base)) ++ return dev_err_probe(dev, PTR_ERR(helper->sram_base), ++ "Failed to map SRAM region"); ++ } ++ ++ helper->rtk = ++ devm_apple_rtkit_init(dev, helper, NULL, 0, &apple_rtkit_helper_ops); ++ if (IS_ERR(helper->rtk)) ++ return dev_err_probe(dev, PTR_ERR(helper->rtk), ++ "Failed to intialize RTKit"); ++ ++ writel_relaxed(APPLE_ASC_CPU_CONTROL_RUN, ++ helper->asc_base + APPLE_ASC_CPU_CONTROL); ++ ++ /* Works for both wake and boot */ ++ ret = apple_rtkit_wake(helper->rtk); ++ if (ret != 0) ++ return dev_err_probe(dev, ret, "Failed to wake up coprocessor"); ++ ++ return 0; ++} ++ ++static void apple_rtkit_helper_remove(struct platform_device *pdev) ++{ ++ struct apple_rtkit_helper *helper = platform_get_drvdata(pdev); ++ ++ if (apple_rtkit_is_running(helper->rtk)) ++ apple_rtkit_quiesce(helper->rtk); ++ ++ writel_relaxed(0, helper->asc_base + APPLE_ASC_CPU_CONTROL); ++} ++ ++static const struct of_device_id apple_rtkit_helper_of_match[] = { ++ { .compatible = "apple,rtk-helper-asc4" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, apple_rtkit_helper_of_match); ++ ++static struct platform_driver apple_rtkit_helper_driver = { ++ .driver = { ++ .name = "rtkit-helper", ++ .of_match_table = apple_rtkit_helper_of_match, ++ }, ++ .probe = apple_rtkit_helper_probe, ++ .remove = apple_rtkit_helper_remove, ++}; ++module_platform_driver(apple_rtkit_helper_driver); ++ ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_DESCRIPTION("Apple RTKit helper driver"); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 11 Dec 2022 20:08:45 +0100 +Subject: HID: transport: spi: Check status message after transmits + +Probably pointless but might be helpful to debug issues. +Gets rid of 'spi_hid_apple_status_ok' is unused compiler warning. + +Signed-off-by: Janne Grunau +--- + drivers/hid/spi-hid/spi-hid-apple-core.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-core.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -248,7 +248,17 @@ static int spihid_apple_request(struct spihid_apple *spihid, u8 target, u8 unk0, + pkt->crc16 = cpu_to_le16(crc16(0, spihid->tx_buf, + offsetof(struct spihid_transfer_packet, crc16))); + ++ memset(spihid->status_buf, 0, sizeof(spi_hid_apple_status_ok)); ++ + err = spi_sync(spihid->spidev, &spihid->tx_msg); ++ ++ if (memcmp(spihid->status_buf, spi_hid_apple_status_ok, ++ sizeof(spi_hid_apple_status_ok))) { ++ u8 *b = spihid->status_buf; ++ dev_warn_ratelimited(&spihid->spidev->dev, "status message " ++ "mismatch: %02x %02x %02x %02x\n", ++ b[0], b[1], b[2], b[3]); ++ } + mutex_unlock(&spihid->tx_lock); + if (err < 0) + return err; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 11 Dec 2022 22:56:16 +0100 +Subject: HID: magicmouse: Add .reset_resume for SPI trackpads + +The trackpad has to request multi touch reports during resume. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 14 ++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -1317,6 +1317,16 @@ static const struct hid_device_id magic_mice[] = { + }; + MODULE_DEVICE_TABLE(hid, magic_mice); + ++#ifdef CONFIG_PM ++static int magicmouse_reset_resume(struct hid_device *hdev) ++{ ++ if (hdev->bus == BUS_SPI) ++ return magicmouse_enable_multitouch(hdev); ++ ++ return 0; ++} ++#endif ++ + static struct hid_driver magicmouse_driver = { + .name = "magicmouse", + .id_table = magic_mice, +@@ -1327,6 +1337,10 @@ static struct hid_driver magicmouse_driver = { + .event = magicmouse_event, + .input_mapping = magicmouse_input_mapping, + .input_configured = magicmouse_input_configured, ++#ifdef CONFIG_PM ++ .reset_resume = magicmouse_reset_resume, ++#endif ++ + }; + module_hid_driver(magicmouse_driver); + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 11 Dec 2022 23:24:41 +0100 +Subject: HID: transport: spi: Add suspend support + +Working suspend and resume. The keyboard can not yet used as wakeup +source. Most likely caused by missing irq_set_wake support in the +gpio/pinctrl driver. + +Signed-off-by: Janne Grunau +--- + drivers/hid/spi-hid/spi-hid-apple-core.c | 89 ++++++++++ + drivers/hid/spi-hid/spi-hid-apple-of.c | 19 +- + drivers/hid/spi-hid/spi-hid-apple.h | 4 + + 3 files changed, 110 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-core.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -115,6 +115,10 @@ struct spihid_apple { + + /* state tracking flags */ + bool status_booted; ++ ++#ifdef IRQ_WAKE_SUPPORT ++ bool irq_wake_enabled; ++#endif + }; + + /** +@@ -1038,6 +1042,91 @@ void spihid_apple_core_shutdown(struct spi_device *spi) + } + EXPORT_SYMBOL_GPL(spihid_apple_core_shutdown); + ++#ifdef CONFIG_PM_SLEEP ++static int spihid_apple_core_suspend(struct device *dev) ++{ ++ int ret; ++#ifdef IRQ_WAKE_SUPPORT ++ int wake_status; ++#endif ++ struct spihid_apple *spihid = spi_get_drvdata(to_spi_device(dev)); ++ ++ if (spihid->tp.hid) { ++ ret = hid_driver_suspend(spihid->tp.hid, PMSG_SUSPEND); ++ if (ret < 0) ++ return ret; ++ } ++ ++ if (spihid->kbd.hid) { ++ ret = hid_driver_suspend(spihid->kbd.hid, PMSG_SUSPEND); ++ if (ret < 0) { ++ if (spihid->tp.hid) ++ hid_driver_resume(spihid->tp.hid); ++ return ret; ++ } ++ } ++ ++ /* Save some power */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++#ifdef IRQ_WAKE_SUPPORT ++ if (device_may_wakeup(dev)) { ++ wake_status = spihid->ops->enable_irq_wake(spihid->ops); ++ if (!wake_status) ++ spihid->irq_wake_enabled = true; ++ else ++ dev_warn(dev, "Failed to enable irq wake: %d\n", ++ wake_status); ++ } else { ++ spihid->ops->power_off(spihid->ops); ++ } ++#else ++ spihid->ops->power_off(spihid->ops); ++#endif ++ ++ return 0; ++} ++ ++static int spihid_apple_core_resume(struct device *dev) ++{ ++ int ret_tp = 0, ret_kbd = 0; ++ struct spihid_apple *spihid = spi_get_drvdata(to_spi_device(dev)); ++#ifdef IRQ_WAKE_SUPPORT ++ int wake_status; ++ ++ if (!device_may_wakeup(dev)) { ++ spihid->ops->power_on(spihid->ops); ++ } else if (spihid->irq_wake_enabled) { ++ wake_status = spihid->ops->disable_irq_wake(spihid->ops); ++ if (!wake_status) ++ spihid->irq_wake_enabled = false; ++ else ++ dev_warn(dev, "Failed to disable irq wake: %d\n", ++ wake_status); ++ } ++#endif ++ ++ spihid->ops->enable_irq(spihid->ops); ++ spihid->ops->power_on(spihid->ops); ++ ++ if (spihid->tp.hid) ++ ret_tp = hid_driver_reset_resume(spihid->tp.hid); ++ if (spihid->kbd.hid) ++ ret_kbd = hid_driver_reset_resume(spihid->kbd.hid); ++ ++ if (ret_tp < 0) ++ return ret_tp; ++ ++ return ret_kbd; ++} ++#endif ++ ++const struct dev_pm_ops spihid_apple_core_pm = { ++ SET_SYSTEM_SLEEP_PM_OPS(spihid_apple_core_suspend, ++ spihid_apple_core_resume) ++}; ++EXPORT_SYMBOL_GPL(spihid_apple_core_pm); ++ + MODULE_DESCRIPTION("Apple SPI HID transport driver"); + MODULE_AUTHOR("Janne Grunau "); + MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/spi-hid/spi-hid-apple-of.c b/drivers/hid/spi-hid/spi-hid-apple-of.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-of.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-of.c +@@ -65,6 +65,20 @@ static int spihid_apple_of_disable_irq(struct spihid_apple_ops *ops) + return 0; + } + ++static int spihid_apple_of_enable_irq_wake(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ return enable_irq_wake(sh_of->irq); ++} ++ ++static int spihid_apple_of_disable_irq_wake(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ return disable_irq_wake(sh_of->irq); ++} ++ + static int spihid_apple_of_probe(struct spi_device *spi) + { + struct device *dev = &spi->dev; +@@ -79,6 +93,8 @@ static int spihid_apple_of_probe(struct spi_device *spi) + spihid_of->ops.power_off = spihid_apple_of_power_off; + spihid_of->ops.enable_irq = spihid_apple_of_enable_irq; + spihid_of->ops.disable_irq = spihid_apple_of_disable_irq; ++ spihid_of->ops.enable_irq_wake = spihid_apple_of_enable_irq_wake; ++ spihid_of->ops.disable_irq_wake = spihid_apple_of_disable_irq_wake; + + spihid_of->enable_gpio = devm_gpiod_get_index(dev, "spien", 0, 0); + if (IS_ERR(spihid_of->enable_gpio)) { +@@ -120,8 +136,7 @@ MODULE_DEVICE_TABLE(spi, spihid_apple_of_id); + static struct spi_driver spihid_apple_of_driver = { + .driver = { + .name = "spi-hid-apple-of", +- //.pm = &spi_hid_apple_of_pm, +- .owner = THIS_MODULE, ++ .pm = &spihid_apple_core_pm, + .of_match_table = of_match_ptr(spihid_apple_of_match), + }, + +diff --git a/drivers/hid/spi-hid/spi-hid-apple.h b/drivers/hid/spi-hid/spi-hid-apple.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple.h ++++ b/drivers/hid/spi-hid/spi-hid-apple.h +@@ -20,6 +20,8 @@ struct spihid_apple_ops { + int (*power_off)(struct spihid_apple_ops *ops); + int (*enable_irq)(struct spihid_apple_ops *ops); + int (*disable_irq)(struct spihid_apple_ops *ops); ++ int (*enable_irq_wake)(struct spihid_apple_ops *ops); ++ int (*disable_irq_wake)(struct spihid_apple_ops *ops); + }; + + irqreturn_t spihid_apple_core_irq(int irq, void *data); +@@ -28,4 +30,6 @@ int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops + void spihid_apple_core_remove(struct spi_device *spi); + void spihid_apple_core_shutdown(struct spi_device *spi); + ++extern const struct dev_pm_ops spihid_apple_core_pm; ++ + #endif /* SPI_HID_APPLE_H */ +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Mon, 10 Apr 2023 22:44:44 +0900 +Subject: HID: Bump maximum report size to 16384 + +This maximum is arbitrary. Recent Apple devices have some vendor-defined +reports with 16384 here which fail to parse without this, so let's bump +it to that. + +This value is used as follows: + +report->size += parser->global.report_size * parser->global.report_count; + +[...] + +/* Total size check: Allow for possible report index byte */ +if (report->size > (max_buffer_size - 1) << 3) { + hid_err(parser->device, "report is too long\n"); + return -1; +} + +All of these fields are unsigned integers, and report_count is bounded +by HID_MAX_USAGES (12288). Therefore, as long as the respective maximums +do not overflow an unsigned integer (let's say a signed integer just in +case), we're safe. This holds for 16384. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -468,7 +468,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) + + case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: + parser->global.report_size = item_udata(item); +- if (parser->global.report_size > 256) { ++ /* Arbitrary maximum. Some Apple devices have 16384 here. ++ * This * HID_MAX_USAGES must fit in a signed integer. ++ */ ++ if (parser->global.report_size > 16384) { + hid_err(parser->device, "invalid report_size %d\n", + parser->global.report_size); + return -1; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 30 Apr 2023 23:48:45 +0900 +Subject: HID: magicmouse: Handle touch controller resets on SPI devices + +On at least some SPI devices (e.g. recent Apple Silicon machines), the +Broadcom touch controller is prone to crashing. When this happens, the +STM eventually notices and resets it. It then notifies the driver via +HID report 0x60, and the driver needs to re-enable MT mode to make +things work again. + +This poses an additional issue: the hidinput core will close the +low-level transport while the device is closed, which can cause us to +miss a reset notification. To fix this, override the input open/close +callbacks and send the MT enable every time the HID device is opened, +instead of only once on probe. This should increase general robustness, +even if the reset mechanism doesn't work for some reason, so it's worth +doing it for USB devices too. MTP devices are exempt since they do not +require the MT enable at all. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 205 ++++++---- + 1 file changed, 134 insertions(+), 71 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -60,6 +60,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define MOUSE2_REPORT_ID 0x12 + #define DOUBLE_REPORT_ID 0xf7 + #define SPI_REPORT_ID 0x02 ++#define SPI_RESET_REPORT_ID 0x60 + #define MTP_REPORT_ID 0x75 + #define USB_BATTERY_TIMEOUT_MS 60000 + +@@ -175,6 +176,98 @@ struct magicmouse_sc { + struct magicmouse_input_ops input_ops; + }; + ++static int magicmouse_enable_multitouch(struct hid_device *hdev) ++{ ++ const u8 *feature; ++ const u8 feature_mt[] = { 0xD7, 0x01 }; ++ const u8 feature_mt_mouse2[] = { 0xF1, 0x02, 0x01 }; ++ const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 }; ++ const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 }; ++ u8 *buf; ++ int ret; ++ int feature_size; ++ ++ if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || ++ hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) { ++ if (hdev->vendor == BT_VENDOR_ID_APPLE) { ++ feature_size = sizeof(feature_mt_trackpad2_bt); ++ feature = feature_mt_trackpad2_bt; ++ } else { /* USB_VENDOR_ID_APPLE */ ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; ++ } ++ } else if (hdev->vendor == SPI_VENDOR_ID_APPLE) { ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; ++ } else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { ++ feature_size = sizeof(feature_mt_mouse2); ++ feature = feature_mt_mouse2; ++ } else { ++ feature_size = sizeof(feature_mt); ++ feature = feature_mt; ++ } ++ ++ buf = kmemdup(feature, feature_size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size, ++ HID_FEATURE_REPORT, HID_REQ_SET_REPORT); ++ kfree(buf); ++ return ret; ++} ++ ++static void magicmouse_enable_mt_work(struct work_struct *work) ++{ ++ struct magicmouse_sc *msc = ++ container_of(work, struct magicmouse_sc, work.work); ++ int ret; ++ ++ ret = magicmouse_enable_multitouch(msc->hdev); ++ if (ret < 0) ++ hid_err(msc->hdev, "unable to request touch data (%d)\n", ret); ++} ++ ++static int magicmouse_open(struct input_dev *dev) ++{ ++ struct hid_device *hdev = input_get_drvdata(dev); ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ int ret; ++ ++ ret = hid_hw_open(hdev); ++ if (ret) ++ return ret; ++ ++ /* ++ * Some devices repond with 'invalid report id' when feature ++ * report switching it into multitouch mode is sent to it. ++ * ++ * This results in -EIO from the _raw low-level transport callback, ++ * but there seems to be no other way of switching the mode. ++ * Thus the super-ugly hacky success check below. ++ */ ++ ret = magicmouse_enable_multitouch(hdev); ++ if (ret == -EIO && hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ return 0; ++ } ++ if (ret < 0) ++ hid_err(hdev, "unable to request touch data (%d)\n", ret); ++ ++ /* ++ * MT enable is usually not required after the first time, so don't ++ * consider it fatal. ++ */ ++ return 0; ++} ++ ++static void magicmouse_close(struct input_dev *dev) ++{ ++ struct hid_device *hdev = input_get_drvdata(dev); ++ ++ hid_hw_close(hdev); ++} ++ + static int magicmouse_firm_touch(struct magicmouse_sc *msc) + { + int touch = -1; +@@ -705,12 +798,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev, + static int magicmouse_raw_event_spi(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + const size_t hdr_sz = sizeof(struct tp_mouse_report); + +- if (size < hdr_sz) ++ if (!size) + return 0; + +- if (data[0] != TRACKPAD2_USB_REPORT_ID) ++ if (data[0] == SPI_RESET_REPORT_ID) { ++ hid_info(hdev, "Touch controller was reset, re-enabling touch mode\n"); ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(10)); ++ return 1; ++ } ++ ++ if (data[0] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz) + return 0; + + return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); +@@ -897,10 +997,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + */ + __clear_bit(EV_REP, input->evbit); + ++ /* ++ * This isn't strictly speaking needed for USB, but enabling MT on ++ * device open is probably more robust than only doing it once on probe ++ * even if USB devices are not known to suffer from the SPI reset issue. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; + return 0; + } + +-static int magicmouse_setup_input_spi(struct input_dev *input, ++static int magicmouse_setup_input_mtp(struct input_dev *input, + struct hid_device *hdev) + { + int error; +@@ -973,6 +1080,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input, + return 0; + } + ++static int magicmouse_setup_input_spi(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int ret = magicmouse_setup_input_mtp(input, hdev); ++ if (ret) ++ return ret; ++ ++ /* ++ * Override the default input->open function to send the MT ++ * enable every time the device is opened. This ensures it works ++ * even if we missed a reset event due to the device being closed. ++ * input->close is overridden for symmetry. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; ++ ++ return 0; ++} ++ + static int magicmouse_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +@@ -1011,58 +1137,6 @@ static int magicmouse_input_configured(struct hid_device *hdev, + return 0; + } + +-static int magicmouse_enable_multitouch(struct hid_device *hdev) +-{ +- const u8 *feature; +- const u8 feature_mt[] = { 0xD7, 0x01 }; +- const u8 feature_mt_mouse2[] = { 0xF1, 0x02, 0x01 }; +- const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 }; +- const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 }; +- u8 *buf; +- int ret; +- int feature_size; +- +- if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || +- hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) { +- if (hdev->vendor == BT_VENDOR_ID_APPLE) { +- feature_size = sizeof(feature_mt_trackpad2_bt); +- feature = feature_mt_trackpad2_bt; +- } else { /* USB_VENDOR_ID_APPLE */ +- feature_size = sizeof(feature_mt_trackpad2_usb); +- feature = feature_mt_trackpad2_usb; +- } +- } else if (hdev->vendor == SPI_VENDOR_ID_APPLE) { +- feature_size = sizeof(feature_mt_trackpad2_usb); +- feature = feature_mt_trackpad2_usb; +- } else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { +- feature_size = sizeof(feature_mt_mouse2); +- feature = feature_mt_mouse2; +- } else { +- feature_size = sizeof(feature_mt); +- feature = feature_mt; +- } +- +- buf = kmemdup(feature, feature_size, GFP_KERNEL); +- if (!buf) +- return -ENOMEM; +- +- ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size, +- HID_FEATURE_REPORT, HID_REQ_SET_REPORT); +- kfree(buf); +- return ret; +-} +- +-static void magicmouse_enable_mt_work(struct work_struct *work) +-{ +- struct magicmouse_sc *msc = +- container_of(work, struct magicmouse_sc, work.work); +- int ret; +- +- ret = magicmouse_enable_multitouch(msc->hdev); +- if (ret < 0) +- hid_err(msc->hdev, "unable to request touch data (%d)\n", ret); +-} +- + static bool is_usb_magicmouse2(__u32 vendor, __u32 product) + { + if (vendor != USB_VENDOR_ID_APPLE) +@@ -1137,7 +1211,7 @@ static int magicmouse_probe(struct hid_device *hdev, + // conflicts with the report ID. + if (id->bus == BUS_HOST) { + msc->input_ops.raw_event = magicmouse_raw_event_mtp; +- msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ msc->input_ops.setup_input = magicmouse_setup_input_mtp; + } else if (id->bus == BUS_SPI) { + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; +@@ -1221,21 +1295,10 @@ static int magicmouse_probe(struct hid_device *hdev, + if (id->bus == BUS_HOST) + return 0; + +- /* +- * Some devices repond with 'invalid report id' when feature +- * report switching it into multitouch mode is sent to it. +- * +- * This results in -EIO from the _raw low-level transport callback, +- * but there seems to be no other way of switching the mode. +- * Thus the super-ugly hacky success check below. +- */ +- ret = magicmouse_enable_multitouch(hdev); +- if (ret != -EIO && ret < 0) { +- hid_err(hdev, "unable to request touch data (%d)\n", ret); +- goto err_stop_hw; +- } +- if (ret == -EIO && id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { +- schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ /* SPI devices need to watch for reset events to re-send the MT enable */ ++ if (id->bus == BUS_SPI) { ++ report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_RESET_REPORT_ID, 0); ++ report->size = 2; + } + + return 0; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 3 Dec 2023 23:10:21 +0900 +Subject: HID: transport: spi: Implement GET FEATURE + +This is used for fetching trackpad dimensions. + +Signed-off-by: Hector Martin +--- + drivers/hid/spi-hid/spi-hid-apple-core.c | 51 +++++++++- + 1 file changed, 48 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-core.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -65,6 +65,8 @@ struct spihid_interface { + u32 max_input_report_len; + u32 max_output_report_len; + u8 name[32]; ++ u8 reply_buf[SPIHID_DESC_MAX]; ++ u32 reply_len; + bool ready; + }; + +@@ -327,6 +329,7 @@ static int apple_ll_raw_request(struct hid_device *hdev, + { + struct spihid_interface *idev = hdev->driver_data; + struct spihid_apple *spihid = spihid_get_data(idev); ++ int ret; + + dev_dbg(&spihid->spidev->dev, + "apple_ll_raw_request: device:%u reportnum:%hhu rtype:%hhu", +@@ -334,7 +337,25 @@ static int apple_ll_raw_request(struct hid_device *hdev, + + switch (reqtype) { + case HID_REQ_GET_REPORT: +- return -EINVAL; // spihid_get_raw_report(); ++ if (rtype != HID_FEATURE_REPORT) ++ return -EINVAL; ++ ++ idev->reply_len = 0; ++ ret = spihid_apple_request(spihid, idev->id, 0x32, reportnum, 0x00, len, NULL, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = wait_event_interruptible_timeout(spihid->wait, idev->reply_len, ++ SPIHID_DEF_WAIT); ++ if (ret == 0) ++ ret = -ETIMEDOUT; ++ if (ret < 0) { ++ dev_err(&spihid->spidev->dev, "waiting for get report failed: %d", ret); ++ return ret; ++ } ++ memcpy(buf, idev->reply_buf, max_t(size_t, len, idev->reply_len)); ++ return idev->reply_len; ++ + case HID_REQ_SET_REPORT: + if (buf[0] != reportnum) + return -EINVAL; +@@ -606,7 +627,27 @@ static bool spihid_process_iface_hid_report_desc(struct spihid_apple *spihid, + return true; + } + +-static bool spihid_process_response(struct spihid_apple *spihid, ++static bool spihid_process_iface_get_report(struct spihid_apple *spihid, ++ u32 device, u8 report, ++ u8 *payload, size_t len) ++{ ++ struct spihid_interface *iface = spihid_get_iface(spihid, device); ++ ++ if (!iface) ++ return false; ++ ++ if (len > sizeof(iface->reply_buf) || len < 1) ++ return false; ++ ++ memcpy(iface->reply_buf, payload, len); ++ iface->reply_len = len; ++ ++ wake_up_interruptible(&spihid->wait); ++ ++ return true; ++} ++ ++static bool spihid_process_response(struct spihid_apple *spihid, u32 device, + struct spihid_msg_hdr *hdr, u8 *payload, + size_t len) + { +@@ -626,6 +667,10 @@ static bool spihid_process_response(struct spihid_apple *spihid, + } + } + ++ if (hdr->unknown0 == 0x32) { ++ return spihid_process_iface_get_report(spihid, device, hdr->unknown1, payload, len); ++ } ++ + return false; + } + +@@ -656,7 +701,7 @@ static void spihid_process_message(struct spihid_apple *spihid, u8 *data, + payload, payload_len); + break; + case SPIHID_WRITE_PACKET: +- handled = spihid_process_response(spihid, hdr, payload, ++ handled = spihid_process_response(spihid, device, hdr, payload, + payload_len); + break; + default: +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 3 Dec 2023 21:08:17 +0900 +Subject: HID: magicmouse: Query device dimensions via HID report + +For SPI/MTP trackpads, query the dimensions via HID report instead of +hardcoding values. + +TODO: Does this work for the USB/BT devices? Maybe we can get rid of the +hardcoded sizes everywhere? + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 102 ++++++++-- + 1 file changed, 81 insertions(+), 21 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -62,6 +62,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define SPI_REPORT_ID 0x02 + #define SPI_RESET_REPORT_ID 0x60 + #define MTP_REPORT_ID 0x75 ++#define SENSOR_DIMENSIONS_REPORT_ID 0xd9 + #define USB_BATTERY_TIMEOUT_MS 60000 + + #define MAX_CONTACTS 16 +@@ -116,6 +117,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++/* These are fallback values, since the real values will be queried from the device. */ + #define J314_TP_DIMENSION_X (float)13000 + #define J314_TP_MIN_X -5900 + #define J314_TP_MAX_X 6500 +@@ -139,6 +141,7 @@ struct magicmouse_input_ops { + * struct magicmouse_sc - Tracks Magic Mouse-specific data. + * @input: Input device through which we report events. + * @quirks: Currently unused. ++ * @query_dimensions: Whether to query and update dimensions on first open + * @ntouches: Number of touches in most recent touch report. + * @scroll_accel: Number of consecutive scroll motions. + * @scroll_jiffies: Time of last scroll motion. +@@ -153,6 +156,7 @@ struct magicmouse_input_ops { + struct magicmouse_sc { + struct input_dev *input; + unsigned long quirks; ++ bool query_dimensions; + + int ntouches; + int scroll_accel; +@@ -176,6 +180,11 @@ struct magicmouse_sc { + struct magicmouse_input_ops input_ops; + }; + ++static inline int le16_to_int(__le16 x) ++{ ++ return (signed short)le16_to_cpu(x); ++} ++ + static int magicmouse_enable_multitouch(struct hid_device *hdev) + { + const u8 *feature; +@@ -245,19 +254,71 @@ static int magicmouse_open(struct input_dev *dev) + * This results in -EIO from the _raw low-level transport callback, + * but there seems to be no other way of switching the mode. + * Thus the super-ugly hacky success check below. ++ * ++ * MTP devices do not need this. + */ +- ret = magicmouse_enable_multitouch(hdev); +- if (ret == -EIO && hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { +- schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); +- return 0; ++ if (hdev->bus != BUS_HOST) { ++ ret = magicmouse_enable_multitouch(hdev); ++ if (ret == -EIO && hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ return 0; ++ } ++ if (ret < 0) ++ hid_err(hdev, "unable to request touch data (%d)\n", ret); + } +- if (ret < 0) +- hid_err(hdev, "unable to request touch data (%d)\n", ret); +- + /* + * MT enable is usually not required after the first time, so don't + * consider it fatal. + */ ++ ++ /* ++ * For Apple Silicon trackpads, we want to query the dimensions on ++ * device open. This is because doing so requires the firmware, but ++ * we don't want to force a firmware load until the device is opened ++ * for the first time. So do that here and update the input properties ++ * just in time before userspace queries them. ++ */ ++ if (msc->query_dimensions) { ++ struct input_dev *input = msc->input; ++ u8 buf[32]; ++ struct { ++ __le32 width; ++ __le32 height; ++ __le16 min_x; ++ __le16 min_y; ++ __le16 max_x; ++ __le16 max_y; ++ } dim; ++ uint32_t x_span, y_span; ++ ++ ret = hid_hw_raw_request(hdev, SENSOR_DIMENSIONS_REPORT_ID, buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_GET_REPORT); ++ if (ret < (int)(1 + sizeof(dim))) { ++ hid_err(hdev, "unable to request dimensions (%d)\n", ret); ++ return ret; ++ } ++ ++ memcpy(&dim, buf + 1, sizeof(dim)); ++ ++ /* finger position */ ++ input_set_abs_params(input, ABS_MT_POSITION_X, ++ le16_to_int(dim.min_x), le16_to_int(dim.max_x), 0, 0); ++ /* Y axis is inverted */ ++ input_set_abs_params(input, ABS_MT_POSITION_Y, ++ -le16_to_int(dim.max_y), -le16_to_int(dim.min_y), 0, 0); ++ x_span = le16_to_int(dim.max_x) - le16_to_int(dim.min_x); ++ y_span = le16_to_int(dim.max_y) - le16_to_int(dim.min_y); ++ ++ /* X/Y resolution */ ++ input_abs_set_res(input, ABS_MT_POSITION_X, 100 * x_span / le32_to_cpu(dim.width) ); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, 100 * y_span / le32_to_cpu(dim.height) ); ++ ++ /* copy info, as input_mt_init_slots() does */ ++ dev->absinfo[ABS_X] = dev->absinfo[ABS_MT_POSITION_X]; ++ dev->absinfo[ABS_Y] = dev->absinfo[ABS_MT_POSITION_Y]; ++ ++ msc->query_dimensions = false; ++ } ++ + return 0; + } + +@@ -707,11 +768,6 @@ struct tp_mouse_report { + u8 padding[4]; + }; + +-static inline int le16_to_int(__le16 x) +-{ +- return (signed short)le16_to_cpu(x); +-} +- + static void report_finger_data(struct input_dev *input, int slot, + const struct input_mt_pos *pos, + const struct tp_finger *f) +@@ -1012,6 +1068,7 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + { + int error; + int mt_flags = 0; ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + __clear_bit(BTN_0, input->keybit); +@@ -1077,6 +1134,18 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + if (error) + return error; + ++ /* ++ * Override the default input->open function to send the MT ++ * enable every time the device is opened. This ensures it works ++ * even if we missed a reset event due to the device being closed. ++ * input->close is overridden for symmetry. ++ * ++ * This also takes care of the dimensions query. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; ++ msc->query_dimensions = true; ++ + return 0; + } + +@@ -1087,15 +1156,6 @@ static int magicmouse_setup_input_spi(struct input_dev *input, + if (ret) + return ret; + +- /* +- * Override the default input->open function to send the MT +- * enable every time the device is opened. This ensures it works +- * even if we missed a reset event due to the device being closed. +- * input->close is overridden for symmetry. +- */ +- input->open = magicmouse_open; +- input->close = magicmouse_close; +- + return 0; + } + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 3 Oct 2024 19:30:23 +0200 +Subject: HID: transport: spi: apple: Increase receive buffer size + +The SPI receive buffer is passed directly to hid_input_report() if it +contains a complete report. It is then passed to hid_report_raw_event() +which computes the expected report size and memsets the "missing +trailing data up to HID_MAX_BUFFER_SIZE (16K) or +hid_ll_driver.max_buffer_size (if set) to zero. + +Signed-off-by: Janne Grunau +--- + drivers/hid/spi-hid/spi-hid-apple-core.c | 11 ++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-core.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -395,6 +395,7 @@ static struct hid_ll_driver apple_hid_ll = { + .parse = &apple_ll_parse, + .raw_request = &apple_ll_raw_request, + .output_report = &apple_ll_output_report, ++ .max_buffer_size = SPIHID_MAX_INPUT_REPORT_SIZE, + }; + + static struct spihid_interface *spihid_get_iface(struct spihid_apple *spihid, +@@ -971,9 +972,15 @@ int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops + // init spi + spi_set_drvdata(spi, spihid); + +- /* allocate SPI buffers */ ++ /* ++ * allocate SPI buffers ++ * Overallocate the receice buffer since it passed directly into ++ * hid_input_report / hid_report_raw_event. The later expects the buffer ++ * to be HID_MAX_BUFFER_SIZE (16k) or hid_ll_driver.max_buffer_size if ++ * set. ++ */ + spihid->rx_buf = devm_kmalloc( +- &spi->dev, sizeof(struct spihid_transfer_packet), GFP_KERNEL); ++ &spi->dev, SPIHID_MAX_INPUT_REPORT_SIZE, GFP_KERNEL); + spihid->tx_buf = devm_kmalloc( + &spi->dev, sizeof(struct spihid_transfer_packet), GFP_KERNEL); + spihid->status_buf = devm_kmalloc( +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Tue, 21 Jan 2025 21:04:33 +0100 +Subject: HID: transport: spi: apple: Use distinctive names input devices + +Kwin uses the tripple Vendor ID, Product ID, Name to identify input +devices. If the same name ("Apple Internal Keyboard / Trackpad") is used +for both keyboard and trackpad actions like disabling the touchpad have +confusing effects. On the next login the keyboard will be disabled as +well since it shares all identifiers. + +Signed-off-by: Janne Grunau +--- + drivers/hid/spi-hid/spi-hid-apple-core.c | 12 +++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/spi-hid/spi-hid-apple-core.c ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -903,6 +903,7 @@ static int spihid_register_hid_device(struct spihid_apple *spihid, + struct spihid_interface *iface, u8 device) + { + int ret; ++ char *suffix; + struct hid_device *hid; + + iface->id = device; +@@ -911,7 +912,16 @@ static int spihid_register_hid_device(struct spihid_apple *spihid, + if (IS_ERR(hid)) + return PTR_ERR(hid); + +- strscpy(hid->name, spihid->product, sizeof(hid->name)); ++ /* ++ * Use 'Apple SPI Keyboard' and 'Apple SPI Trackpad' as input device ++ * names. The device names need to be distinct since at least Kwin uses ++ * the tripple Vendor ID, Product ID, Name to identify devices. ++ */ ++ snprintf(hid->name, sizeof(hid->name), "Apple SPI %s", iface->name); ++ // strip ' / Boot' suffix from the name ++ suffix = strstr(hid->name, " / Boot"); ++ if (suffix) ++ suffix[0] = '\0'; + snprintf(hid->phys, sizeof(hid->phys), "%s (%hhx)", + dev_name(&spihid->spidev->dev), device); + strscpy(hid->uniq, spihid->serial, sizeof(hid->uniq)); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4002-HID-quirks-remove-T2-devices-from-hid_mouse_ignore_l.patch b/patch/kernel/archive/uefi-x86-6.12/4002-HID-quirks-remove-T2-devices-from-hid_mouse_ignore_l.patch new file mode 100644 index 000000000..47e4e143c --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4002-HID-quirks-remove-T2-devices-from-hid_mouse_ignore_l.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Mon, 10 Mar 2025 22:53:28 +0530 +Subject: HID: quirks: remove T2 devices from hid_mouse_ignore_list + +In order to use hid-magicmouse for T2 trackpads, we need to +remove them from hid_mouse_ignore_list + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-quirks.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -968,14 +968,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch b/patch/kernel/archive/uefi-x86-6.12/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch new file mode 100644 index 000000000..3fa1a4eab --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Mon, 10 Mar 2025 23:03:29 +0530 +Subject: HID: apple: ignore the trackpad on T2 Macs + +In order to manage the trackpad on T2 Macs by hid-magicmouse driver +we need to ensure that it is not bound by the hid-apple driver. Use +the existing APPLE_IGNORE_MOUSE quirk for the same. + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-apple.c | 23 ++++++---- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -971,6 +971,9 @@ static int apple_probe(struct hid_device *hdev, + hdev->type != HID_TYPE_SPI_KEYBOARD) + return -ENODEV; + ++ if (quirks & APPLE_IGNORE_MOUSE && hdev->type == HID_TYPE_USBMOUSE) ++ return -ENODEV; ++ + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); + if (asc == NULL) { + hid_err(hdev, "can't alloc apple descriptor\n"); +@@ -1193,21 +1196,25 @@ static const struct hid_device_id apple_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), +- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), +- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), +- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), +- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch b/patch/kernel/archive/uefi-x86-6.12/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch new file mode 100644 index 000000000..34b81ac9b --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch @@ -0,0 +1,497 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Tue, 11 Mar 2025 18:44:06 +0530 +Subject: HID: magicmouse: Add support for trackpads found on T2 Macs + +This patch adds support for trackpads found on Macs with the T2 +Security Chip. The touch report format differs from other trackpads. +It is the same format as type 4 in bcm5974.c + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-magicmouse.c | 371 ++++++++-- + 1 file changed, 313 insertions(+), 58 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -117,6 +117,94 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++#define J140K_TP_DIMENSION_X (float)12100 ++#define J140K_TP_MIN_X -5318 ++#define J140K_TP_MAX_X 5787 ++#define J140K_TP_RES_X \ ++ ((J140K_TP_MAX_X - J140K_TP_MIN_X) / (J140K_TP_DIMENSION_X / 100)) ++#define J140K_TP_DIMENSION_Y (float)8200 ++#define J140K_TP_MIN_Y -157 ++#define J140K_TP_MAX_Y 7102 ++#define J140K_TP_RES_Y \ ++ ((J140K_TP_MAX_Y - J140K_TP_MIN_Y) / (J140K_TP_DIMENSION_Y / 100)) ++ ++#define J132_TP_DIMENSION_X (float)13500 ++#define J132_TP_MIN_X -6243 ++#define J132_TP_MAX_X 6749 ++#define J132_TP_RES_X \ ++ ((J132_TP_MAX_X - J132_TP_MIN_X) / (J132_TP_DIMENSION_X / 100)) ++#define J132_TP_DIMENSION_Y (float)8400 ++#define J132_TP_MIN_Y -170 ++#define J132_TP_MAX_Y 7685 ++#define J132_TP_RES_Y \ ++ ((J132_TP_MAX_Y - J132_TP_MIN_Y) / (J132_TP_DIMENSION_Y / 100)) ++ ++#define J680_TP_DIMENSION_X (float)16000 ++#define J680_TP_MIN_X -7456 ++#define J680_TP_MAX_X 7976 ++#define J680_TP_RES_X \ ++ ((J680_TP_MAX_X - J680_TP_MIN_X) / (J680_TP_DIMENSION_X / 100)) ++#define J680_TP_DIMENSION_Y (float)10000 ++#define J680_TP_MIN_Y -163 ++#define J680_TP_MAX_Y 9283 ++#define J680_TP_RES_Y \ ++ ((J680_TP_MAX_Y - J680_TP_MIN_Y) / (J680_TP_DIMENSION_Y / 100)) ++ ++#define J213_TP_DIMENSION_X (float)13500 ++#define J213_TP_MIN_X -6243 ++#define J213_TP_MAX_X 6749 ++#define J213_TP_RES_X \ ++ ((J213_TP_MAX_X - J213_TP_MIN_X) / (J213_TP_DIMENSION_X / 100)) ++#define J213_TP_DIMENSION_Y (float)8400 ++#define J213_TP_MIN_Y -170 ++#define J213_TP_MAX_Y 7685 ++#define J213_TP_RES_Y \ ++ ((J213_TP_MAX_Y - J213_TP_MIN_Y) / (J213_TP_DIMENSION_Y / 100)) ++ ++#define J214K_TP_DIMENSION_X (float)13200 ++#define J214K_TP_MIN_X -6046 ++#define J214K_TP_MAX_X 6536 ++#define J214K_TP_RES_X \ ++ ((J214K_TP_MAX_X - J214K_TP_MIN_X) / (J214K_TP_DIMENSION_X / 100)) ++#define J214K_TP_DIMENSION_Y (float)8200 ++#define J214K_TP_MIN_Y -164 ++#define J214K_TP_MAX_Y 7439 ++#define J214K_TP_RES_Y \ ++ ((J214K_TP_MAX_Y - J214K_TP_MIN_Y) / (J214K_TP_DIMENSION_Y / 100)) ++ ++#define J223_TP_DIMENSION_X (float)13200 ++#define J223_TP_MIN_X -6046 ++#define J223_TP_MAX_X 6536 ++#define J223_TP_RES_X \ ++ ((J223_TP_MAX_X - J223_TP_MIN_X) / (J223_TP_DIMENSION_X / 100)) ++#define J223_TP_DIMENSION_Y (float)8200 ++#define J223_TP_MIN_Y -164 ++#define J223_TP_MAX_Y 7439 ++#define J223_TP_RES_Y \ ++ ((J223_TP_MAX_Y - J223_TP_MIN_Y) / (J223_TP_DIMENSION_Y / 100)) ++ ++#define J230K_TP_DIMENSION_X (float)12100 ++#define J230K_TP_MIN_X -5318 ++#define J230K_TP_MAX_X 5787 ++#define J230K_TP_RES_X \ ++ ((J230K_TP_MAX_X - J230K_TP_MIN_X) / (J230K_TP_DIMENSION_X / 100)) ++#define J230K_TP_DIMENSION_Y (float)8200 ++#define J230K_TP_MIN_Y -157 ++#define J230K_TP_MAX_Y 7102 ++#define J230K_TP_RES_Y \ ++ ((J230K_TP_MAX_Y - J230K_TP_MIN_Y) / (J230K_TP_DIMENSION_Y / 100)) ++ ++#define J152F_TP_DIMENSION_X (float)16000 ++#define J152F_TP_MIN_X -7456 ++#define J152F_TP_MAX_X 7976 ++#define J152F_TP_RES_X \ ++ ((J152F_TP_MAX_X - J152F_TP_MIN_X) / (J152F_TP_DIMENSION_X / 100)) ++#define J152F_TP_DIMENSION_Y (float)10000 ++#define J152F_TP_MIN_Y -163 ++#define J152F_TP_MAX_Y 9283 ++#define J152F_TP_RES_Y \ ++ ((J152F_TP_MAX_Y - J152F_TP_MIN_Y) / (J152F_TP_DIMENSION_Y / 100)) ++ + /* These are fallback values, since the real values will be queried from the device. */ + #define J314_TP_DIMENSION_X (float)13000 + #define J314_TP_MIN_X -5900 +@@ -129,7 +217,11 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define J314_TP_RES_Y \ + ((J314_TP_MAX_Y - J314_TP_MIN_Y) / (J314_TP_DIMENSION_Y / 100)) + +-#define J314_TP_MAX_FINGER_ORIENTATION 16384 ++#define T2_TOUCHPAD_ENTRY(model) \ ++ { USB_DEVICE_ID_APPLE_WELLSPRINGT2_##model, model##_TP_MIN_X, model##_TP_MIN_Y, \ ++model##_TP_MAX_X, model##_TP_MAX_Y, model##_TP_RES_X, model##_TP_RES_Y } ++ ++#define INTERNAL_TP_MAX_FINGER_ORIENTATION 16384 + + struct magicmouse_input_ops { + int (*raw_event)(struct hid_device *hdev, +@@ -196,24 +288,45 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + int ret; + int feature_size; + +- if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || +- hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) { +- if (hdev->vendor == BT_VENDOR_ID_APPLE) { +- feature_size = sizeof(feature_mt_trackpad2_bt); +- feature = feature_mt_trackpad2_bt; +- } else { /* USB_VENDOR_ID_APPLE */ ++ switch (hdev->bus) { ++ case BUS_SPI: ++ case BUS_HOST: ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; ++ break; ++ default: ++ switch (hdev->product) { ++ case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2: ++ case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC: ++ switch (hdev->vendor) { ++ case BT_VENDOR_ID_APPLE: ++ feature_size = sizeof(feature_mt_trackpad2_bt); ++ feature = feature_mt_trackpad2_bt; ++ break; ++ default: /* USB_VENDOR_ID_APPLE */ ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; ++ } ++ break; ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: + feature_size = sizeof(feature_mt_trackpad2_usb); + feature = feature_mt_trackpad2_usb; ++ break; ++ case USB_DEVICE_ID_APPLE_MAGICMOUSE2: ++ feature_size = sizeof(feature_mt_mouse2); ++ feature = feature_mt_mouse2; ++ break; ++ default: ++ feature_size = sizeof(feature_mt); ++ feature = feature_mt; + } +- } else if (hdev->vendor == SPI_VENDOR_ID_APPLE) { +- feature_size = sizeof(feature_mt_trackpad2_usb); +- feature = feature_mt_trackpad2_usb; +- } else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) { +- feature_size = sizeof(feature_mt_mouse2); +- feature = feature_mt_mouse2; +- } else { +- feature_size = sizeof(feature_mt); +- feature = feature_mt; + } + + buf = kmemdup(feature, feature_size, GFP_KERNEL); +@@ -784,7 +897,7 @@ static void report_finger_data(struct input_dev *input, int slot, + input_report_abs(input, ABS_MT_WIDTH_MINOR, + le16_to_int(f->tool_minor) << 1); + input_report_abs(input, ABS_MT_ORIENTATION, +- J314_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); ++ INTERNAL_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); + input_report_abs(input, ABS_MT_PRESSURE, le16_to_int(f->pressure)); + input_report_abs(input, ABS_MT_POSITION_X, pos->x); + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); +@@ -872,6 +985,20 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); + } + ++static int magicmouse_raw_event_t2(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ const size_t hdr_sz = sizeof(struct tp_mouse_report); ++ ++ if (!size) ++ return 0; ++ ++ if (data[0] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz) ++ return 0; ++ ++ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -1063,8 +1190,31 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + return 0; + } + +-static int magicmouse_setup_input_mtp(struct input_dev *input, +- struct hid_device *hdev) ++struct magicmouse_t2_properties { ++ u32 id; ++ int min_x; ++ int min_y; ++ int max_x; ++ int max_y; ++ int res_x; ++ int res_y; ++}; ++ ++static const struct magicmouse_t2_properties magicmouse_t2_configs[] = { ++ T2_TOUCHPAD_ENTRY(J140K), ++ T2_TOUCHPAD_ENTRY(J132), ++ T2_TOUCHPAD_ENTRY(J680), ++ T2_TOUCHPAD_ENTRY(J213), ++ T2_TOUCHPAD_ENTRY(J214K), ++ T2_TOUCHPAD_ENTRY(J223), ++ T2_TOUCHPAD_ENTRY(J230K), ++ T2_TOUCHPAD_ENTRY(J152F), ++}; ++ ++static int magicmouse_setup_input_int_tpd(struct input_dev *input, ++ struct hid_device *hdev, int min_x, int min_y, ++ int max_x, int max_y, int res_x, int res_y, ++ bool query_dimensions) + { + int error; + int mt_flags = 0; +@@ -1105,19 +1255,17 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + input_abs_set_res(input, ABS_MT_PRESSURE, 1); + + /* finger orientation */ +- input_set_abs_params(input, ABS_MT_ORIENTATION, -J314_TP_MAX_FINGER_ORIENTATION, +- J314_TP_MAX_FINGER_ORIENTATION, 0, 0); ++ input_set_abs_params(input, ABS_MT_ORIENTATION, -INTERNAL_TP_MAX_FINGER_ORIENTATION, ++ INTERNAL_TP_MAX_FINGER_ORIENTATION, 0, 0); + + /* finger position */ +- input_set_abs_params(input, ABS_MT_POSITION_X, J314_TP_MIN_X, J314_TP_MAX_X, +- 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_X, min_x, max_x, 0, 0); + /* Y axis is inverted */ +- input_set_abs_params(input, ABS_MT_POSITION_Y, -J314_TP_MAX_Y, -J314_TP_MIN_Y, +- 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_Y, -max_y, -min_y, 0, 0); + + /* X/Y resolution */ +- input_abs_set_res(input, ABS_MT_POSITION_X, J314_TP_RES_X); +- input_abs_set_res(input, ABS_MT_POSITION_Y, J314_TP_RES_Y); ++ input_abs_set_res(input, ABS_MT_POSITION_X, res_x); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); + + input_set_events_per_packet(input, 60); + +@@ -1144,7 +1292,20 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + */ + input->open = magicmouse_open; + input->close = magicmouse_close; +- msc->query_dimensions = true; ++ msc->query_dimensions = query_dimensions; ++ ++ return 0; ++} ++ ++static int magicmouse_setup_input_mtp(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X, ++ J314_TP_MIN_Y, J314_TP_MAX_X, ++ J314_TP_MAX_Y, J314_TP_RES_X, ++ J314_TP_RES_Y, true); ++ if (ret) ++ return ret; + + return 0; + } +@@ -1152,7 +1313,34 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + static int magicmouse_setup_input_spi(struct input_dev *input, + struct hid_device *hdev) + { +- int ret = magicmouse_setup_input_mtp(input, hdev); ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X, ++ J314_TP_MIN_Y, J314_TP_MAX_X, ++ J314_TP_MAX_Y, J314_TP_RES_X, ++ J314_TP_RES_Y, true); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int magicmouse_setup_input_t2(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int min_x, min_y, max_x, max_y, res_x, res_y; ++ ++ for (size_t i = 0; i < ARRAY_SIZE(magicmouse_t2_configs); i++) { ++ if (magicmouse_t2_configs[i].id == hdev->product) { ++ min_x = magicmouse_t2_configs[i].min_x; ++ min_y = magicmouse_t2_configs[i].min_y; ++ max_x = magicmouse_t2_configs[i].max_x; ++ max_y = magicmouse_t2_configs[i].max_y; ++ res_x = magicmouse_t2_configs[i].res_x; ++ res_y = magicmouse_t2_configs[i].res_y; ++ } ++ } ++ ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, min_x, min_y, ++ max_x, max_y, res_x, res_y, false); + if (ret) + return ret; + +@@ -1258,8 +1446,22 @@ static int magicmouse_probe(struct hid_device *hdev, + int ret; + + if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && +- hdev->type != HID_TYPE_SPI_MOUSE) +- return -ENODEV; ++ hdev->type != HID_TYPE_SPI_MOUSE) ++ return -ENODEV; ++ ++ switch (id->product) { ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ if (hdev->type != HID_TYPE_USBMOUSE) ++ return -ENODEV; ++ break; ++ } + + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { +@@ -1269,16 +1471,32 @@ static int magicmouse_probe(struct hid_device *hdev, + + // internal trackpad use a data format use input ops to avoid + // conflicts with the report ID. +- if (id->bus == BUS_HOST) { ++ switch (id->bus) { ++ case BUS_HOST: + msc->input_ops.raw_event = magicmouse_raw_event_mtp; + msc->input_ops.setup_input = magicmouse_setup_input_mtp; +- } else if (id->bus == BUS_SPI) { ++ break; ++ case BUS_SPI: + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; +- +- } else { +- msc->input_ops.raw_event = magicmouse_raw_event_usb; +- msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ break; ++ default: ++ switch (id->product) { ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ msc->input_ops.raw_event = magicmouse_raw_event_t2; ++ msc->input_ops.setup_input = magicmouse_setup_input_t2; ++ break; ++ default: ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ } + } + + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; +@@ -1319,29 +1537,50 @@ static int magicmouse_probe(struct hid_device *hdev, + goto err_stop_hw; + } + +- if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- MOUSE_REPORT_ID, 0); +- else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- MOUSE2_REPORT_ID, 0); +- else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || +- id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) { +- if (id->vendor == BT_VENDOR_ID_APPLE) +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- TRACKPAD2_BT_REPORT_ID, 0); +- else /* USB_VENDOR_ID_APPLE */ +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- TRACKPAD2_USB_REPORT_ID, 0); +- } else if (id->bus == BUS_SPI) { ++ switch (id->bus) { ++ case BUS_SPI: + report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0); +- } else if (id->bus == BUS_HOST) { ++ break; ++ case BUS_HOST: + report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0); +- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- TRACKPAD_REPORT_ID, 0); +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- DOUBLE_REPORT_ID, 0); ++ break; ++ default: ++ switch (id->product) { ++ case USB_DEVICE_ID_APPLE_MAGICMOUSE: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE_REPORT_ID, 0); ++ break; ++ case USB_DEVICE_ID_APPLE_MAGICMOUSE2: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE2_REPORT_ID, 0); ++ break; ++ case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2: ++ case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC: ++ switch (id->vendor) { ++ case BT_VENDOR_ID_APPLE: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD2_BT_REPORT_ID, 0); ++ break; ++ default: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD2_USB_REPORT_ID, 0); ++ } ++ break; ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD2_USB_REPORT_ID, 0); ++ break; ++ default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD_REPORT_ID, 0); ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ DOUBLE_REPORT_ID, 0); ++ } + } + + if (!report) { +@@ -1432,6 +1671,22 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), .driver_data = 0 }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = 0 }, + { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4005-HID-apple-Add-necessary-IDs-and-support-for-replacem.patch b/patch/kernel/archive/uefi-x86-6.12/4005-HID-apple-Add-necessary-IDs-and-support-for-replacem.patch new file mode 100644 index 000000000..50dcac92e --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4005-HID-apple-Add-necessary-IDs-and-support-for-replacem.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Tue, 18 Mar 2025 21:25:05 +0530 +Subject: HID: apple: Add necessary IDs and support for replacement trackpad on + MacBookPro15,1 + +Some third party trackpad replacements like that of HAWSON may have a +different PID than the stock trackpad. This commit adds one such trackpad +to hid-apple. + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-apple.c | 4 +++ + drivers/hid/hid-ids.h | 17 +++++----- + drivers/hid/hid-quirks.c | 1 + + 3 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -530,6 +530,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + table = apple2021_fn_keys; + else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 || + hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 || ++ hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT || + hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) + table = macbookpro_no_esc_fn_keys; + else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K || +@@ -1204,6 +1205,9 @@ static const struct hid_device_id apple_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_IGNORE_MOUSE }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_IGNORE_MOUSE }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -174,14 +174,15 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 +-#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT 0x0278 ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -316,6 +316,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) }, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/4006-HID-magicmouse-Add-MacBookPro15-1-replacement-trackp.patch b/patch/kernel/archive/uefi-x86-6.12/4006-HID-magicmouse-Add-MacBookPro15-1-replacement-trackp.patch new file mode 100644 index 000000000..5464a232b --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/4006-HID-magicmouse-Add-MacBookPro15-1-replacement-trackp.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Tue, 18 Mar 2025 21:27:25 +0530 +Subject: HID: magicmouse: Add MacBookPro15,1 replacement trackpad support + +This commit adds support for third party replacement trackpad for +MacBookPro15,1 with a different PID in hid-magicmouse. + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-magicmouse.c | 18 ++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -150,6 +150,17 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define J680_TP_RES_Y \ + ((J680_TP_MAX_Y - J680_TP_MIN_Y) / (J680_TP_DIMENSION_Y / 100)) + ++#define J680_ALT_TP_DIMENSION_X (float)16000 ++#define J680_ALT_TP_MIN_X -7456 ++#define J680_ALT_TP_MAX_X 7976 ++#define J680_ALT_TP_RES_X \ ++ ((J680_ALT_TP_MAX_X - J680_ALT_TP_MIN_X) / (J680_ALT_TP_DIMENSION_X / 100)) ++#define J680_ALT_TP_DIMENSION_Y (float)10000 ++#define J680_ALT_TP_MIN_Y -163 ++#define J680_ALT_TP_MAX_Y 9283 ++#define J680_ALT_TP_RES_Y \ ++ ((J680_ALT_TP_MAX_Y - J680_ALT_TP_MIN_Y) / (J680_ALT_TP_DIMENSION_Y / 100)) ++ + #define J213_TP_DIMENSION_X (float)13500 + #define J213_TP_MIN_X -6243 + #define J213_TP_MAX_X 6749 +@@ -311,6 +322,7 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: +@@ -1204,6 +1216,7 @@ static const struct magicmouse_t2_properties magicmouse_t2_configs[] = { + T2_TOUCHPAD_ENTRY(J140K), + T2_TOUCHPAD_ENTRY(J132), + T2_TOUCHPAD_ENTRY(J680), ++ T2_TOUCHPAD_ENTRY(J680_ALT), + T2_TOUCHPAD_ENTRY(J213), + T2_TOUCHPAD_ENTRY(J214K), + T2_TOUCHPAD_ENTRY(J223), +@@ -1453,6 +1466,7 @@ static int magicmouse_probe(struct hid_device *hdev, + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: +@@ -1485,6 +1499,7 @@ static int magicmouse_probe(struct hid_device *hdev, + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: +@@ -1567,6 +1582,7 @@ static int magicmouse_probe(struct hid_device *hdev, + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: +@@ -1677,6 +1693,8 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch b/patch/kernel/archive/uefi-x86-6.12/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch new file mode 100644 index 000000000..fb96a66f0 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ashish Arora +Date: Sat, 8 Jan 2022 21:43:18 +1100 +Subject: drm/i915: Discard large BIOS framebuffers causing display corruption + +On certain 4k panels, the BIOS framebuffer is larger than what panel +requires causing display corruption. Introduce a check for the same. + +Signed-off-by: Ashish Arora +--- + drivers/gpu/drm/i915/display/intel_fbdev.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_fbdev.c ++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c +@@ -199,10 +199,10 @@ static int intelfb_create(struct drm_fb_helper *helper, + ifbdev->fb = NULL; + + if (fb && +- (sizes->fb_width > fb->base.width || +- sizes->fb_height > fb->base.height)) { ++ (sizes->fb_width != fb->base.width || ++ sizes->fb_height != fb->base.height)) { + drm_dbg_kms(&dev_priv->drm, +- "BIOS fb too small (%dx%d), we require (%dx%d)," ++ "BIOS fb not valid (%dx%d), we require (%dx%d)," + " releasing it\n", + fb->base.width, fb->base.height, + sizes->fb_width, sizes->fb_height); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/8001-Add-APFS-driver.patch b/patch/kernel/archive/uefi-x86-6.12/8001-Add-APFS-driver.patch new file mode 100644 index 000000000..2606b65c9 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/8001-Add-APFS-driver.patch @@ -0,0 +1,27188 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "github-actions[bot]" + <41898282+github-actions[bot]@users.noreply.github.com> +Date: Tue, 28 Oct 2025 18:52:50 +0000 +Subject: Add APFS driver + +--- + fs/apfs/Makefile | 28 + + fs/apfs/apfs.h | 1316 ++++ + fs/apfs/apfs_raw.h | 1570 +++++ + fs/apfs/btree.c | 1174 ++++ + fs/apfs/compress.c | 478 ++ + fs/apfs/dir.c | 1504 +++++ + fs/apfs/extents.c | 2374 +++++++ + fs/apfs/file.c | 224 + + fs/apfs/inode.c | 2594 ++++++++ + fs/apfs/key.c | 337 + + fs/apfs/libzbitmap.c | 442 ++ + fs/apfs/libzbitmap.h | 31 + + fs/apfs/lzfse/lzfse.h | 67 + + fs/apfs/lzfse/lzfse_decode.c | 80 + + fs/apfs/lzfse/lzfse_decode_base.c | 743 +++ + fs/apfs/lzfse/lzfse_fse.c | 126 + + fs/apfs/lzfse/lzfse_fse.h | 573 ++ + fs/apfs/lzfse/lzfse_internal.h | 482 ++ + fs/apfs/lzfse/lzvn_decode_base.c | 487 ++ + fs/apfs/lzfse/lzvn_decode_base.h | 73 + + fs/apfs/message.c | 29 + + fs/apfs/namei.c | 146 + + fs/apfs/node.c | 2069 ++++++ + fs/apfs/object.c | 315 + + fs/apfs/snapshot.c | 687 ++ + fs/apfs/spaceman.c | 1479 +++++ + fs/apfs/super.c | 2127 +++++++ + fs/apfs/symlink.c | 80 + + fs/apfs/transaction.c | 1034 +++ + fs/apfs/unicode.c | 3156 ++++++++++ + fs/apfs/unicode.h | 27 + + fs/apfs/version.h | 1 + + fs/apfs/xattr.c | 914 +++ + fs/apfs/xfield.c | 171 + + 34 files changed, 26938 insertions(+) + +diff --git a/fs/apfs/Makefile b/fs/apfs/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/Makefile +@@ -0,0 +1,28 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Makefile for the out-of-tree Linux APFS module. ++# ++ ++KERNELRELEASE ?= $(shell uname -r) ++KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build ++PWD := $(shell pwd) ++ ++obj-m = apfs.o ++apfs-y := btree.o compress.o dir.o extents.o file.o inode.o key.o libzbitmap.o \ ++ lzfse/lzfse_decode.o lzfse/lzfse_decode_base.o lzfse/lzfse_fse.o \ ++ lzfse/lzvn_decode_base.o message.o namei.o node.o object.o snapshot.o \ ++ spaceman.o super.o symlink.o transaction.o unicode.o xattr.o xfield.o ++ ++# If you want mounts to be writable by default, run the build as: ++# make CONFIG=-DCONFIG_APFS_RW_ALWAYS ++# This is risky and not generally recommended. ++ccflags-y += $(CONFIG) ++ ++default: ++ ./genver.sh ++ make -C $(KERNEL_DIR) M=$(PWD) ++install: ++ make -C $(KERNEL_DIR) M=$(PWD) modules_install ++clean: ++ rm -f version.h ++ make -C $(KERNEL_DIR) M=$(PWD) clean +diff --git a/fs/apfs/apfs.h b/fs/apfs/apfs.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/apfs.h +@@ -0,0 +1,1316 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#ifndef _APFS_H ++#define _APFS_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Redhat kernels regularly break the api, so they need their own version ++ * checks. Make sure they always fail for non-rhel kernels. ++ * ++ * By the way, if rhel keeps picking up breaking patches for old majors after ++ * a new one is out, this check could break down and things could get more ++ * complicated. I don't think they do that though... ++ */ ++#ifdef RHEL_RELEASE ++#define RHEL_VERSION_GE(a, b) (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(a, b)) ++#else ++#define RHEL_VERSION_GE(a, b) 0 ++#endif ++ ++#include "apfs_raw.h" ++ ++#define EFSBADCRC EBADMSG /* Bad CRC detected */ ++#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) /* SB_RDONLY came in 4.14 */ ++#define SB_RDONLY MS_RDONLY ++#define SB_SILENT MS_SILENT ++#define SB_NOSEC MS_NOSEC ++#define SB_ACTIVE MS_ACTIVE ++static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags & SB_RDONLY; } ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0) ++#define lockdep_assert_held_write(l) ((void)(l)) ++#endif ++ ++/* Compatibility wrapper around submit_bh() */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || RHEL_VERSION_GE(9, 2) ++#define apfs_submit_bh(op, op_flags, bh) submit_bh(op | op_flags, bh) ++#else ++#define apfs_submit_bh(op, op_flags, bh) submit_bh(op, op_flags, bh) ++#endif ++ ++/* ++ * Parameter for the snapshot creation ioctl ++ */ ++struct apfs_ioctl_snap_name { ++ char name[APFS_SNAP_MAX_NAMELEN + 1]; ++}; ++ ++#define APFS_IOC_SET_DFLT_PFK _IOW('@', 0x80, struct apfs_wrapped_crypto_state) ++#define APFS_IOC_SET_DIR_CLASS _IOW('@', 0x81, u32) ++#define APFS_IOC_SET_PFK _IOW('@', 0x82, struct apfs_wrapped_crypto_state) ++#define APFS_IOC_GET_CLASS _IOR('@', 0x83, u32) ++#define APFS_IOC_GET_PFK _IOR('@', 0x84, struct apfs_wrapped_crypto_state) ++#define APFS_IOC_TAKE_SNAPSHOT _IOW('@', 0x85, struct apfs_ioctl_snap_name) ++ ++/* ++ * In-memory representation of an APFS object ++ */ ++struct apfs_object { ++ struct super_block *sb; ++ u64 block_nr; ++ u64 oid; ++ ++ /* ++ * Buffer head containing the one block of the object, may be NULL if ++ * the object is only in memory. TODO: support objects with more than ++ * one block. ++ */ ++ struct buffer_head *o_bh; ++ char *data; /* The raw object */ ++ bool ephemeral; /* Is this an ephemeral object? */ ++}; ++ ++/* Constants used in managing the size of a node's table of contents */ ++#define APFS_BTREE_TOC_ENTRY_INCREMENT 8 ++#define APFS_BTREE_TOC_ENTRY_MAX_UNUSED (2 * BTREE_TOC_ENTRY_INCREMENT) ++ ++/* ++ * In-memory representation of an APFS node ++ */ ++struct apfs_node { ++ u32 tree_type; /* Tree type (subtype of the node object) */ ++ u16 flags; /* Node flags */ ++ u32 records; /* Number of records in the node */ ++ ++ int key; /* Offset of the key area in the block */ ++ int free; /* Offset of the free area in the block */ ++ int val; /* Offset of the value area in the block */ ++ ++ int key_free_list_len; /* Length of the fragmented free key space */ ++ int val_free_list_len; /* Length of the fragmented free value space */ ++ ++ struct apfs_object object; /* Object holding the node */ ++}; ++ ++/** ++ * apfs_node_is_leaf - Check if a b-tree node is a leaf ++ * @node: the node to check ++ */ ++static inline bool apfs_node_is_leaf(struct apfs_node *node) ++{ ++ return (node->flags & APFS_BTNODE_LEAF) != 0; ++} ++ ++/** ++ * apfs_node_is_root - Check if a b-tree node is the root ++ * @node: the node to check ++ */ ++static inline bool apfs_node_is_root(struct apfs_node *node) ++{ ++ return (node->flags & APFS_BTNODE_ROOT) != 0; ++} ++ ++/** ++ * apfs_node_has_fixed_kv_size - Check if a b-tree node has fixed key/value ++ * sizes ++ * @node: the node to check ++ */ ++static inline bool apfs_node_has_fixed_kv_size(struct apfs_node *node) ++{ ++ return (node->flags & APFS_BTNODE_FIXED_KV_SIZE) != 0; ++} ++ ++struct apfs_ip_bitmap_block_info { ++ bool dirty; /* Do we need to commit this block to disk? */ ++ void *block; /* In-memory address of the bitmap block */ ++}; ++ ++/* ++ * Space manager data in memory. ++ */ ++struct apfs_spaceman { ++ struct apfs_spaceman_phys *sm_raw; /* On-disk spaceman structure */ ++ struct apfs_nxsb_info *sm_nxi; /* Container superblock */ ++ u32 sm_size; /* Size of @sm_raw in bytes */ ++ ++ u32 sm_blocks_per_chunk; /* Blocks covered by a bitmap block */ ++ u32 sm_chunks_per_cib; /* Chunk count in a chunk-info block */ ++ u64 sm_block_count; /* Block count for the container */ ++ u64 sm_chunk_count; /* Number of bitmap blocks */ ++ u32 sm_cib_count; /* Number of chunk-info blocks */ ++ u64 sm_free_count; /* Number of free blocks */ ++ u32 sm_addr_offset; /* Offset of cib addresses in @sm_raw */ ++ u64 sm_main_fq_nodes; /* Number of nodes in the main fq */ ++ ++ /* ++ * A range of freed blocks not yet put in the free queue. Extend this as ++ * much as possible before creating an actual record. ++ */ ++ u64 sm_free_cache_base; ++ u64 sm_free_cache_blkcnt; ++ ++ /* Shift to match an ip block with its bitmap in the array */ ++ int sm_ip_bmaps_shift; ++ /* Mask to find an ip block's offset inside its ip bitmap */ ++ u32 sm_ip_bmaps_mask; ++ /* Number of ip bitmaps */ ++ u32 sm_ip_bmaps_count; ++ /* List of ip bitmaps, in order */ ++ struct apfs_ip_bitmap_block_info sm_ip_bmaps[]; ++}; ++ ++#define APFS_TRANS_MAIN_QUEUE_MAX 10000 ++#define APFS_TRANS_BUFFERS_MAX 65536 ++#define APFS_TRANS_STARTS_MAX 65536 ++ ++/* Possible states for the container transaction structure */ ++#define APFS_NX_TRANS_FORCE_COMMIT 1 /* Commit guaranteed */ ++#define APFS_NX_TRANS_DEFER_COMMIT 2 /* Commit banned right now */ ++#define APFS_NX_TRANS_COMMITTING 4 /* Commit ongoing */ ++#define APFS_NX_TRANS_INCOMPLETE_BLOCK 8 /* A data block is not written in full */ ++ ++/* ++ * ENOSPC checks before transactions are more or less coarse depending on this. ++ */ ++enum apfs_trans_kind { ++ APFS_TRANS_REG, /* Most transactions */ ++ APFS_TRANS_DEL, /* Transactions that usually free space */ ++ APFS_TRANS_SYNC, /* Sync (or unmount) transaction */ ++}; ++ ++/* The space requirements for each kind of transaction, in blocks */ ++#define APFS_REG_ROOM 128 ++#define APFS_DEL_ROOM 20 ++#define APFS_SYNC_ROOM 6 ++ ++/* ++ * Structure that keeps track of a container transaction. ++ */ ++struct apfs_nx_transaction { ++ unsigned int t_state; ++ ++ struct delayed_work t_work; /* Work task for transaction commits */ ++ struct super_block *t_work_sb; /* sb that last queued a commit */ ++ ++ struct list_head t_inodes; /* List of inodes in the transaction */ ++ struct list_head t_buffers; /* List of buffers in the transaction */ ++ size_t t_buffers_count; /* Count of items on the list */ ++ int t_starts_count; /* Count of starts for transaction */ ++}; ++ ++/* State bits for buffer heads in a transaction */ ++#define BH_TRANS BH_PrivateStart /* Attached to a transaction */ ++#define BH_CSUM (BH_PrivateStart + 1) /* Requires checksum update */ ++BUFFER_FNS(TRANS, trans); ++BUFFER_FNS(CSUM, csum); ++ ++/* ++ * Additional information for a buffer in a transaction. ++ */ ++struct apfs_bh_info { ++ struct buffer_head *bh; /* The buffer head */ ++ struct list_head list; /* List of buffers in the transaction */ ++}; ++ ++/* ++ * List entry for an in-memory ephemeral object ++ */ ++struct apfs_ephemeral_object_info { ++ u64 oid; /* Ephemeral object id */ ++ u32 size; /* Size of the object in bytes */ ++ void *object; /* In-memory address of the object */ ++}; ++ ++/* ++ * We allocate a fixed space for the list of ephemeral objects. I don't ++ * actually know how big this should be allowed to get, but all the objects ++ * must be written down with each transaction commit, so probably not too big. ++ */ ++#define APFS_EPHEMERAL_LIST_SIZE 32768 ++#define APFS_EPHEMERAL_LIST_LIMIT (APFS_EPHEMERAL_LIST_SIZE / sizeof(struct apfs_ephemeral_object_info)) ++ ++/* Mount option flags for a container */ ++#define APFS_CHECK_NODES 1 ++#define APFS_READWRITE 2 ++/* ++ * Mount options for a container are decided on its first mount. This flag lets ++ * future mounts know that has happened already. ++ */ ++#define APFS_FLAGS_SET 4 ++ ++/* ++ * Wrapper around block devices for portability. ++ */ ++struct apfs_blkdev_info { ++ struct block_device *blki_bdev; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) || RHEL_VERSION_GE(9, 5) ++ struct file *blki_bdev_file; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++ struct bdev_handle *blki_bdev_handle; ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) && !RHEL_VERSION_GE(9, 4) ++ fmode_t blki_mode; ++#endif ++ ++ /* ++ * For tier 2, we need to remember the mount path for show_options(). ++ * We don't need this for the main device of course, but better to ++ * keep things consistent. ++ */ ++ char *blki_path; ++}; ++ ++/* ++ * Container superblock data in memory ++ */ ++struct apfs_nxsb_info { ++ /* Block device info for the container */ ++ struct apfs_blkdev_info *nx_blkdev_info; ++ struct apfs_blkdev_info *nx_tier2_info; ++ u64 nx_tier2_bno; /* Offset for tier 2 block numbers */ ++ ++ struct apfs_nx_superblock *nx_raw; /* On-disk main sb */ ++ u64 nx_bno; /* Current block number for the checkpoint superblock */ ++ u64 nx_xid; /* Latest transaction id */ ++ ++ /* List of ephemeral objects in memory (except the superblock) */ ++ struct apfs_ephemeral_object_info *nx_eph_list; ++ int nx_eph_count; ++ ++ struct list_head vol_list; /* List of mounted volumes in container */ ++ ++ unsigned int nx_flags; /* Mount options shared by all volumes */ ++ unsigned int nx_refcnt; /* Number of mounted volumes in container */ ++ ++ /* TODO: handle block sizes above the maximum of PAGE_SIZE? */ ++ unsigned long nx_blocksize; ++ unsigned char nx_blocksize_bits; ++ ++ struct apfs_spaceman *nx_spaceman; ++ struct apfs_nx_transaction nx_transaction; ++ int nx_trans_buffers_max; ++ ++ /* For now, a single semaphore for every operation */ ++ struct rw_semaphore nx_big_sem; ++ ++ /* List of currently mounted containers */ ++ struct list_head nx_list; ++}; ++ ++extern struct mutex nxs_mutex; ++ ++/* ++ * Omap mapping in memory. ++ * TODO: could this and apfs_omap_rec be the same struct? ++ */ ++struct apfs_omap_map { ++ u64 xid; ++ u64 bno; ++ u32 flags; ++}; ++ ++/* ++ * Omap record data in memory ++ */ ++struct apfs_omap_rec { ++ u64 oid; ++ u64 bno; ++}; ++ ++#define APFS_OMAP_CACHE_SLOTS 128 ++#define APFS_OMAP_CACHE_SLOT_MASK (APFS_OMAP_CACHE_SLOTS - 1) ++ ++/** ++ * Cache of omap records ++ */ ++struct apfs_omap_cache { ++ struct apfs_omap_rec recs[APFS_OMAP_CACHE_SLOTS]; ++ bool disabled; ++ spinlock_t lock; ++}; ++ ++/* ++ * Omap structure shared by all snapshots for the same volume. ++ */ ++struct apfs_omap { ++ struct apfs_node *omap_root; ++ struct apfs_omap_cache omap_cache; ++ ++ /* Transaction id for most recent snapshot */ ++ u64 omap_latest_snap; ++ ++ /* Number of snapshots sharing this omap */ ++ unsigned int omap_refcnt; ++}; ++ ++/* ++ * Volume superblock data in memory ++ */ ++struct apfs_sb_info { ++ struct apfs_nxsb_info *s_nxi; /* In-memory container sb for volume */ ++ struct list_head list; /* List of mounted volumes in container */ ++ struct apfs_superblock *s_vsb_raw; /* On-disk volume sb */ ++ ++ dev_t s_anon_dev; /* Anonymous device for this volume-snapshot */ ++ ++ char *s_tier2_path; /* Path to the tier 2 device */ ++ ++ char *s_snap_name; /* Label for the mounted snapshot */ ++ u64 s_snap_xid; /* Transaction id for mounted snapshot */ ++ ++ struct apfs_node *s_cat_root; /* Root of the catalog tree */ ++ struct apfs_omap *s_omap; /* The object map */ ++ ++ struct apfs_object s_vobject; /* Volume superblock object */ ++ ++ /* Mount options */ ++ unsigned int s_vol_nr; /* Index of the volume in the sb list */ ++ kuid_t s_uid; /* uid to override on-disk uid */ ++ kgid_t s_gid; /* gid to override on-disk gid */ ++ ++ struct apfs_crypto_state_val *s_dflt_pfk; /* default per-file key */ ++ ++ struct inode *s_private_dir; /* Inode for the private directory */ ++ struct work_struct s_orphan_cleanup_work; ++ atomic_t s_orphan_cleanup_err; /* Error from last orphan cleanup */ ++}; ++ ++static inline struct apfs_sb_info *APFS_SB(struct super_block *sb) ++{ ++ return sb->s_fs_info; ++} ++ ++static inline bool apfs_is_sealed(struct super_block *sb) ++{ ++ u64 flags = le64_to_cpu(APFS_SB(sb)->s_vsb_raw->apfs_incompatible_features); ++ ++ return flags & APFS_INCOMPAT_SEALED_VOLUME; ++} ++ ++/** ++ * apfs_vol_is_encrypted - Check if a volume is encrypting files ++ * @sb: superblock ++ */ ++static inline bool apfs_vol_is_encrypted(struct super_block *sb) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ ++ return (vsb_raw->apfs_fs_flags & cpu_to_le64(APFS_FS_UNENCRYPTED)) == 0; ++} ++ ++/** ++ * APFS_NXI - Get the shared container info for a volume's superblock ++ * @sb: superblock structure ++ */ ++static inline struct apfs_nxsb_info *APFS_NXI(struct super_block *sb) ++{ ++ return APFS_SB(sb)->s_nxi; ++} ++ ++/** ++ * APFS_SM - Get the shared spaceman struct for a volume's superblock ++ * @sb: superblock structure ++ */ ++static inline struct apfs_spaceman *APFS_SM(struct super_block *sb) ++{ ++ return APFS_NXI(sb)->nx_spaceman; ++} ++ ++static inline bool apfs_is_case_insensitive(struct super_block *sb) ++{ ++ return (APFS_SB(sb)->s_vsb_raw->apfs_incompatible_features & ++ cpu_to_le64(APFS_INCOMPAT_CASE_INSENSITIVE)) != 0; ++} ++ ++static inline bool apfs_is_normalization_insensitive(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ u64 flags = le64_to_cpu(sbi->s_vsb_raw->apfs_incompatible_features); ++ ++ if (apfs_is_case_insensitive(sb)) ++ return true; ++ if (flags & APFS_INCOMPAT_NORMALIZATION_INSENSITIVE) ++ return true; ++ return false; ++} ++ ++/** ++ * apfs_max_maps_per_block - Find the maximum map count for a mapping block ++ * @sb: superblock structure ++ */ ++static inline int apfs_max_maps_per_block(struct super_block *sb) ++{ ++ unsigned long maps_size; ++ ++ maps_size = (sb->s_blocksize - sizeof(struct apfs_checkpoint_map_phys)); ++ return maps_size / sizeof(struct apfs_checkpoint_mapping); ++} ++ ++/* ++ * In-memory representation of a key, as relevant for a b-tree query. ++ */ ++struct apfs_key { ++ u64 id; ++ u64 number; /* Extent offset, name hash or transaction id */ ++ const char *name; /* On-disk name string */ ++ u8 type; /* Record type (0 for the omap) */ ++}; ++ ++/** ++ * apfs_init_free_queue_key - Initialize an in-memory key for a free queue query ++ * @xid: transaction id ++ * @paddr: block number ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_free_queue_key(u64 xid, u64 paddr, ++ struct apfs_key *key) ++{ ++ key->id = xid; ++ key->type = 0; ++ key->number = paddr; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_omap_key - Initialize an in-memory key for an omap query ++ * @oid: object id ++ * @xid: latest transaction id ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_omap_key(u64 oid, u64 xid, struct apfs_key *key) ++{ ++ key->id = oid; ++ key->type = 0; ++ key->number = xid; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_extent_key - Initialize an in-memory key for an extentref query ++ * @bno: physical block number for the start of the extent ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_extent_key(u64 bno, struct apfs_key *key) ++{ ++ key->id = bno; ++ key->type = APFS_TYPE_EXTENT; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_inode_key - Initialize an in-memory key for an inode query ++ * @ino: inode number ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_inode_key(u64 ino, struct apfs_key *key) ++{ ++ key->id = ino; ++ key->type = APFS_TYPE_INODE; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_file_extent_key - Initialize an in-memory key for an extent query ++ * @id: extent id ++ * @offset: logical address (0 for a multiple query) ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_file_extent_key(u64 id, u64 offset, ++ struct apfs_key *key) ++{ ++ key->id = id; ++ key->type = APFS_TYPE_FILE_EXTENT; ++ key->number = offset; ++ key->name = NULL; ++} ++ ++static inline void apfs_init_fext_key(u64 id, u64 offset, struct apfs_key *key) ++{ ++ key->id = id; ++ key->type = 0; ++ key->number = offset; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_dstream_id_key - Initialize an in-memory key for a dstream query ++ * @id: data stream id ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_dstream_id_key(u64 id, struct apfs_key *key) ++{ ++ key->id = id; ++ key->type = APFS_TYPE_DSTREAM_ID; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_crypto_state_key - Initialize an in-memory key for a crypto query ++ * @id: crypto state id ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_crypto_state_key(u64 id, struct apfs_key *key) ++{ ++ key->id = id; ++ key->type = APFS_TYPE_CRYPTO_STATE; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_sibling_link_key - Initialize an in-memory key for a sibling query ++ * @ino: inode number ++ * @id: sibling id ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_sibling_link_key(u64 ino, u64 id, ++ struct apfs_key *key) ++{ ++ key->id = ino; ++ key->type = APFS_TYPE_SIBLING_LINK; ++ key->number = id; /* Only guessing (TODO) */ ++ key->name = NULL; ++} ++ ++/** ++ * apfs_init_sibling_map_key - Initialize in-memory key for a sibling map query ++ * @id: sibling id ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_sibling_map_key(u64 id, struct apfs_key *key) ++{ ++ key->id = id; ++ key->type = APFS_TYPE_SIBLING_MAP; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++extern void apfs_init_drec_key(struct super_block *sb, u64 ino, const char *name, ++ unsigned int name_len, struct apfs_key *key); ++ ++/** ++ * apfs_init_xattr_key - Initialize an in-memory key for a xattr query ++ * @ino: inode number of the parent file ++ * @name: xattr name (NULL for a multiple query) ++ * @key: apfs_key structure to initialize ++ */ ++static inline void apfs_init_xattr_key(u64 ino, const char *name, ++ struct apfs_key *key) ++{ ++ key->id = ino; ++ key->type = APFS_TYPE_XATTR; ++ key->number = 0; ++ key->name = name; ++} ++ ++static inline void apfs_init_snap_metadata_key(u64 xid, struct apfs_key *key) ++{ ++ key->id = xid; ++ key->type = APFS_TYPE_SNAP_METADATA; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++static inline void apfs_init_snap_name_key(const char *name, struct apfs_key *key) ++{ ++ key->id = APFS_SNAP_NAME_OBJ_ID; ++ key->type = APFS_TYPE_SNAP_NAME; ++ key->number = 0; ++ key->name = name; ++} ++ ++static inline void apfs_init_omap_snap_key(u64 xid, struct apfs_key *key) ++{ ++ key->id = xid; ++ key->type = 0; ++ key->number = 0; ++ key->name = NULL; ++} ++ ++/** ++ * apfs_key_set_hdr - Set the header for a raw catalog key ++ * @type: record type ++ * @id: record id ++ * @key: the key to initialize ++ */ ++static inline void apfs_key_set_hdr(u64 type, u64 id, void *key) ++{ ++ struct apfs_key_header *hdr = key; ++ ++ hdr->obj_id_and_type = cpu_to_le64(id | type << APFS_OBJ_TYPE_SHIFT); ++} ++ ++/** ++ * apfs_cat_type - Read the record type of a catalog key ++ * @key: the raw catalog key ++ */ ++static inline int apfs_cat_type(struct apfs_key_header *key) ++{ ++ return (le64_to_cpu(key->obj_id_and_type) & APFS_OBJ_TYPE_MASK) >> APFS_OBJ_TYPE_SHIFT; ++} ++ ++/** ++ * apfs_cat_cnid - Read the cnid value on a catalog key ++ * @key: the raw catalog key ++ * ++ * TODO: rename this function, since it's not just for the catalog anymore ++ */ ++static inline u64 apfs_cat_cnid(struct apfs_key_header *key) ++{ ++ return le64_to_cpu(key->obj_id_and_type) & APFS_OBJ_ID_MASK; ++} ++ ++/* Flags for the query structure */ ++#define APFS_QUERY_TREE_MASK 000177 /* Which b-tree we query */ ++#define APFS_QUERY_OMAP 000001 /* This is a b-tree object map query */ ++#define APFS_QUERY_CAT 000002 /* This is a catalog tree query */ ++#define APFS_QUERY_FREE_QUEUE 000004 /* This is a free queue query */ ++#define APFS_QUERY_EXTENTREF 000010 /* This is an extent reference query */ ++#define APFS_QUERY_FEXT 000020 /* This is a fext tree query */ ++#define APFS_QUERY_SNAP_META 000040 /* This is a snapshot meta query */ ++#define APFS_QUERY_OMAP_SNAP 000100 /* This is an omap snapshots query */ ++#define APFS_QUERY_NEXT 000200 /* Find next of multiple matches */ ++#define APFS_QUERY_EXACT 000400 /* Search for an exact match */ ++#define APFS_QUERY_DONE 001000 /* The search at this level is over */ ++#define APFS_QUERY_ANY_NAME 002000 /* Multiple search for any name */ ++#define APFS_QUERY_ANY_NUMBER 004000 /* Multiple search for any number */ ++#define APFS_QUERY_MULTIPLE (APFS_QUERY_ANY_NAME | APFS_QUERY_ANY_NUMBER) ++#define APFS_QUERY_PREV 010000 /* Find previous record */ ++ ++/* ++ * Structure used to retrieve data from an APFS B-Tree. ++ */ ++struct apfs_query { ++ struct apfs_node *node; /* Node being searched */ ++ struct apfs_key key; /* What the query is looking for */ ++ ++ struct apfs_query *parent; /* Query for parent node */ ++ unsigned int flags; ++ ++ /* Set by the query on success */ ++ int index; /* Index of the entry in the node */ ++ int key_off; /* Offset of the key in the node */ ++ int key_len; /* Length of the key */ ++ int off; /* Offset of the value in the node */ ++ int len; /* Length of the value */ ++ ++ int depth; /* Put a limit on recursion */ ++}; ++ ++/** ++ * apfs_query_storage - Get the storage type for a query's btree ++ * @query: the query structure ++ */ ++static inline u32 apfs_query_storage(struct apfs_query *query) ++{ ++ if (query->flags & APFS_QUERY_OMAP) ++ return APFS_OBJ_PHYSICAL; ++ if (query->flags & APFS_QUERY_CAT) ++ return APFS_OBJ_VIRTUAL; ++ if (query->flags & APFS_QUERY_FEXT) ++ return APFS_OBJ_PHYSICAL; ++ if (query->flags & APFS_QUERY_FREE_QUEUE) ++ return APFS_OBJ_EPHEMERAL; ++ if (query->flags & APFS_QUERY_EXTENTREF) ++ return APFS_OBJ_PHYSICAL; ++ if (query->flags & APFS_QUERY_SNAP_META) ++ return APFS_OBJ_PHYSICAL; ++ if (query->flags & APFS_QUERY_OMAP_SNAP) ++ return APFS_OBJ_PHYSICAL; ++ ++ /* Absurd, but don't panic: let the callers fail and report it */ ++ return -1; ++} ++ ++/* ++ * Extent record data in memory ++ */ ++struct apfs_file_extent { ++ u64 logical_addr; ++ u64 phys_block_num; ++ u64 len; ++ u64 crypto_id; ++}; ++ ++/* ++ * Physical extent record data in memory ++ */ ++struct apfs_phys_extent { ++ u64 bno; ++ u64 blkcount; ++ u64 len; /* In bytes */ ++ u32 refcnt; ++ u8 kind; ++}; ++ ++/* ++ * Data stream info in memory ++ */ ++struct apfs_dstream_info { ++ struct super_block *ds_sb; /* Filesystem superblock */ ++ struct inode *ds_inode; /* NULL for xattr dstreams */ ++ u64 ds_id; /* ID of the extent records */ ++ u64 ds_size; /* Length of the stream */ ++ u64 ds_sparse_bytes;/* Hole byte count in stream */ ++ struct apfs_file_extent ds_cached_ext; /* Latest extent record */ ++ bool ds_ext_dirty; /* Is ds_cached_ext dirty? */ ++ spinlock_t ds_ext_lock; /* Protects ds_cached_ext */ ++ bool ds_shared; /* Has multiple references? */ ++}; ++ ++/** ++ * apfs_alloced_size - Return the alloced size for a data stream ++ * @dstream: data stream info ++ * ++ * TODO: is this always correct? Or could the extents have an unused tail? ++ */ ++static inline u64 apfs_alloced_size(struct apfs_dstream_info *dstream) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ u64 blks = (dstream->ds_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; ++ ++ return blks << sb->s_blocksize_bits; ++} ++ ++/* ++ * APFS inode data in memory ++ */ ++struct apfs_inode_info { ++ u64 i_ino64; /* 32-bit-safe inode number */ ++ u64 i_parent_id; /* ID of primary parent */ ++ struct timespec64 i_crtime; /* Time of creation */ ++ u32 i_nchildren; /* Child count for directory */ ++ uid_t i_saved_uid; /* User ID on disk */ ++ gid_t i_saved_gid; /* Group ID on disk */ ++ u32 i_key_class; /* Security class for directory */ ++ u64 i_int_flags; /* Internal flags */ ++ u32 i_bsd_flags; /* BSD flags */ ++ struct list_head i_list; /* List of inodes in transaction */ ++ ++ bool i_has_dstream; /* Is there a dstream record? */ ++ struct apfs_dstream_info i_dstream; /* Dstream data, if any */ ++ ++ bool i_cleaned; /* Orphan data already deleted */ ++ ++ struct inode vfs_inode; ++}; ++ ++static inline struct apfs_inode_info *APFS_I(const struct inode *inode) ++{ ++ return container_of(inode, struct apfs_inode_info, vfs_inode); ++} ++ ++/** ++ * apfs_ino - Get the 64-bit id of an inode ++ * @inode: the vfs inode ++ * ++ * Returns all 64 bits of @inode's id, even on 32-bit architectures. ++ */ ++static inline u64 apfs_ino(const struct inode *inode) ++{ ++ return APFS_I(inode)->i_ino64; ++} ++ ++/** ++ * apfs_set_ino - Set a 64-bit id on an inode ++ * @inode: the vfs inode ++ * @id: id to set ++ * ++ * Sets both the vfs inode number and the actual 32-bit-safe id. ++ */ ++static inline void apfs_set_ino(struct inode *inode, u64 id) ++{ ++ inode->i_ino = id; /* Higher bits may be lost, but it doesn't matter */ ++ APFS_I(inode)->i_ino64 = id; ++} ++ ++/* Make the compiler complain if we ever access i_ino directly by mistake */ ++#define i_ino DONT_USE_I_INO ++ ++/* ++ * Directory entry record in memory ++ */ ++struct apfs_drec { ++ u8 *name; ++ u64 ino; ++ u64 sibling_id; /* The sibling id; 0 if none */ ++ int name_len; ++ unsigned int type; ++}; ++ ++/* ++ * Xattr record data in memory ++ */ ++struct apfs_xattr { ++ u8 *name; ++ u8 *xdata; ++ int name_len; ++ int xdata_len; ++ bool has_dstream; ++}; ++ ++struct apfs_compressed_data { ++ bool has_dstream; ++ u64 size; ++ union { ++ struct apfs_dstream_info *dstream; ++ void *data; ++ }; ++}; ++ ++/* ++ * Report function name and line number for the message types that are likely ++ * to signal a bug, to make things easier for reporters. Don't do this for the ++ * common messages, there is no point and it makes the console look too busy. ++ */ ++#define apfs_emerg(sb, fmt, ...) apfs_msg(sb, KERN_EMERG, __func__, __LINE__, fmt, ##__VA_ARGS__) ++#define apfs_alert(sb, fmt, ...) apfs_msg(sb, KERN_ALERT, __func__, __LINE__, fmt, ##__VA_ARGS__) ++#define apfs_crit(sb, fmt, ...) apfs_msg(sb, KERN_CRIT, __func__, __LINE__, fmt, ##__VA_ARGS__) ++#define apfs_err(sb, fmt, ...) apfs_msg(sb, KERN_ERR, __func__, __LINE__, fmt, ##__VA_ARGS__) ++#define apfs_warn(sb, fmt, ...) apfs_msg(sb, KERN_WARNING, NULL, 0, fmt, ##__VA_ARGS__) ++#define apfs_notice(sb, fmt, ...) apfs_msg(sb, KERN_NOTICE, NULL, 0, fmt, ##__VA_ARGS__) ++#define apfs_info(sb, fmt, ...) apfs_msg(sb, KERN_INFO, NULL, 0, fmt, ##__VA_ARGS__) ++ ++#ifdef CONFIG_APFS_DEBUG ++#define ASSERT(expr) WARN_ON(!(expr)) ++#define apfs_debug(sb, fmt, ...) apfs_msg(sb, KERN_DEBUG, __func__, __LINE__, fmt, ##__VA_ARGS__) ++#else ++#define ASSERT(expr) ((void)0) ++#define apfs_debug(sb, fmt, ...) no_printk(fmt, ##__VA_ARGS__) ++#endif /* CONFIG_APFS_DEBUG */ ++ ++/** ++ * apfs_assert_in_transaction - Assert that the object is in current transaction ++ * @sb: superblock structure ++ * @obj: on-disk object to check ++ */ ++#define apfs_assert_in_transaction(sb, obj) \ ++do { \ ++ (void)sb; \ ++ (void)obj; \ ++ ASSERT(le64_to_cpu((obj)->o_xid) == APFS_NXI(sb)->nx_xid); \ ++} while (0) ++ ++/* btree.c */ ++extern struct apfs_node *apfs_query_root(const struct apfs_query *query); ++extern struct apfs_query *apfs_alloc_query(struct apfs_node *node, ++ struct apfs_query *parent); ++extern void apfs_free_query(struct apfs_query *query); ++extern int apfs_btree_query(struct super_block *sb, struct apfs_query **query); ++extern int apfs_omap_lookup_block(struct super_block *sb, struct apfs_omap *omap, u64 id, u64 *block, bool write); ++extern int apfs_omap_lookup_newest_block(struct super_block *sb, struct apfs_omap *omap, u64 id, u64 *block, bool write); ++extern int apfs_create_omap_rec(struct super_block *sb, u64 oid, u64 bno); ++extern int apfs_delete_omap_rec(struct super_block *sb, u64 oid); ++extern int apfs_query_join_transaction(struct apfs_query *query); ++extern int __apfs_btree_insert(struct apfs_query *query, void *key, int key_len, void *val, int val_len); ++extern int apfs_btree_insert(struct apfs_query *query, void *key, int key_len, ++ void *val, int val_len); ++extern int apfs_btree_remove(struct apfs_query *query); ++extern void apfs_btree_change_node_count(struct apfs_query *query, int change); ++extern int apfs_btree_replace(struct apfs_query *query, void *key, int key_len, ++ void *val, int val_len); ++extern void apfs_query_direct_forward(struct apfs_query *query); ++ ++/* compress.c */ ++extern int apfs_compress_get_size(struct inode *inode, loff_t *size); ++ ++/* dir.c */ ++extern int apfs_inode_by_name(struct inode *dir, const struct qstr *child, ++ u64 *ino); ++extern int apfs_mkany(struct inode *dir, struct dentry *dentry, ++ umode_t mode, dev_t rdev, const char *symname); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++extern int apfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t rdev); ++extern int apfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); ++extern int apfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, ++ unsigned int flags); ++extern int apfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool excl); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++extern int apfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode, dev_t rdev); ++extern int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode); ++extern int apfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, ++ struct dentry *old_dentry, struct inode *new_dir, ++ struct dentry *new_dentry, unsigned int flags); ++extern int apfs_create(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 15, 0) ++extern int apfs_mknod(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, dev_t rdev); ++extern int apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode); ++extern int apfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, ++ struct dentry *old_dentry, struct inode *new_dir, ++ struct dentry *new_dentry, unsigned int flags); ++extern int apfs_create(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl); ++#else ++extern int apfs_mknod(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, dev_t rdev); ++extern struct dentry *apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode); ++extern int apfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, ++ struct dentry *old_dentry, struct inode *new_dir, ++ struct dentry *new_dentry, unsigned int flags); ++extern int apfs_create(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl); ++#endif ++ ++extern int apfs_link(struct dentry *old_dentry, struct inode *dir, ++ struct dentry *dentry); ++extern int apfs_unlink(struct inode *dir, struct dentry *dentry); ++extern int apfs_rmdir(struct inode *dir, struct dentry *dentry); ++extern int apfs_delete_orphan_link(struct inode *inode); ++extern u64 apfs_any_orphan_ino(struct super_block *sb, u64 *ino_p); ++ ++/* extents.c */ ++extern int apfs_extent_from_query(struct apfs_query *query, ++ struct apfs_file_extent *extent); ++extern int apfs_logic_to_phys_bno(struct apfs_dstream_info *dstream, sector_t dsblock, u64 *bno); ++extern int __apfs_get_block(struct apfs_dstream_info *dstream, sector_t iblock, ++ struct buffer_head *bh_result, int create); ++extern int apfs_get_block(struct inode *inode, sector_t iblock, ++ struct buffer_head *bh_result, int create); ++extern int apfs_flush_extent_cache(struct apfs_dstream_info *dstream); ++extern int apfs_dstream_get_new_bno(struct apfs_dstream_info *dstream, u64 dsblock, u64 *bno); ++extern int apfs_get_new_block(struct inode *inode, sector_t iblock, ++ struct buffer_head *bh_result, int create); ++extern int apfs_truncate(struct apfs_dstream_info *dstream, loff_t new_size); ++extern int apfs_inode_delete_front(struct inode *inode); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) ++extern loff_t apfs_remap_file_range(struct file *src_file, loff_t off, struct file *dst_file, loff_t destoff, loff_t len, unsigned int remap_flags); ++#else ++extern int apfs_clone_file_range(struct file *src_file, loff_t off, struct file *dst_file, loff_t destoff, u64 len); ++#endif ++extern int apfs_clone_extents(struct apfs_dstream_info *dstream, u64 new_id); ++extern int apfs_nonsparse_dstream_read(struct apfs_dstream_info *dstream, void *buf, size_t count, u64 offset); ++extern void apfs_nonsparse_dstream_preread(struct apfs_dstream_info *dstream); ++ ++/* file.c */ ++extern int apfs_file_mmap(struct file *file, struct vm_area_struct *vma); ++extern int apfs_fsync(struct file *file, loff_t start, loff_t end, int datasync); ++ ++/* inode.c */ ++extern struct inode *apfs_iget(struct super_block *sb, u64 cnid); ++extern int apfs_update_inode(struct inode *inode, char *new_name); ++extern void apfs_schedule_orphan_cleanup(struct super_block *sb); ++extern void apfs_orphan_cleanup_work(struct work_struct *work); ++extern void apfs_evict_inode(struct inode *inode); ++extern struct inode *apfs_new_inode(struct inode *dir, umode_t mode, ++ dev_t rdev); ++extern int apfs_create_inode_rec(struct super_block *sb, struct inode *inode, ++ struct dentry *dentry); ++extern int apfs_inode_create_exclusive_dstream(struct inode *inode); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++extern int __apfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata); ++extern int __apfs_write_end(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata); ++#else ++extern int __apfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata); ++extern int __apfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata); ++#endif ++extern int apfs_dstream_adj_refcnt(struct apfs_dstream_info *dstream, u32 delta); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++extern int apfs_setattr(struct dentry *dentry, struct iattr *iattr); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++extern int apfs_setattr(struct user_namespace *mnt_userns, ++ struct dentry *dentry, struct iattr *iattr); ++#else ++extern int apfs_setattr(struct mnt_idmap *idmap, ++ struct dentry *dentry, struct iattr *iattr); ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++extern int apfs_update_time(struct inode *inode, struct timespec64 *time, int flags); ++#else ++extern int apfs_update_time(struct inode *inode, int flags); ++#endif ++long apfs_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++long apfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) /* No statx yet... */ ++extern int apfs_getattr(struct vfsmount *mnt, struct dentry *dentry, ++ struct kstat *stat); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++extern int apfs_getattr(const struct path *path, struct kstat *stat, ++ u32 request_mask, unsigned int query_flags); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++extern int apfs_getattr(struct user_namespace *mnt_userns, ++ const struct path *path, struct kstat *stat, u32 request_mask, ++ unsigned int query_flags); ++#else ++extern int apfs_getattr(struct mnt_idmap *idmap, ++ const struct path *path, struct kstat *stat, u32 request_mask, ++ unsigned int query_flags); ++#endif ++ ++extern int apfs_crypto_adj_refcnt(struct super_block *sb, u64 crypto_id, int delta); ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++#define fileattr file_kattr ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) || RHEL_VERSION_GE(9, 6) ++extern int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa); ++extern int apfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) ++extern int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa); ++extern int apfs_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa); ++#endif ++ ++/* key.c */ ++extern int apfs_filename_cmp(struct super_block *sb, const char *name1, unsigned int len1, const char *name2, unsigned int len2); ++extern int apfs_keycmp(struct apfs_key *k1, struct apfs_key *k2); ++extern int apfs_read_cat_key(void *raw, int size, struct apfs_key *key, bool hashed); ++extern int apfs_read_fext_key(void *raw, int size, struct apfs_key *key); ++extern int apfs_read_free_queue_key(void *raw, int size, struct apfs_key *key); ++extern int apfs_read_omap_key(void *raw, int size, struct apfs_key *key); ++extern int apfs_read_extentref_key(void *raw, int size, struct apfs_key *key); ++extern int apfs_read_snap_meta_key(void *raw, int size, struct apfs_key *key); ++extern int apfs_read_omap_snap_key(void *raw, int size, struct apfs_key *key); ++ ++/* message.c */ ++extern __printf(5, 6) void apfs_msg(struct super_block *sb, const char *prefix, const char *func, int line, const char *fmt, ...); ++ ++/* node.c */ ++extern struct apfs_node *apfs_read_node(struct super_block *sb, u64 oid, ++ u32 storage, bool write); ++extern void apfs_update_node(struct apfs_node *node); ++extern int apfs_delete_node(struct apfs_node *node, int type); ++extern int apfs_node_query(struct super_block *sb, struct apfs_query *query); ++extern void apfs_node_query_first(struct apfs_query *query); ++extern int apfs_omap_map_from_query(struct apfs_query *query, struct apfs_omap_map *map); ++extern int apfs_node_split(struct apfs_query *query); ++extern int apfs_node_locate_key(struct apfs_node *node, int index, int *off); ++extern void apfs_node_free(struct apfs_node *node); ++extern void apfs_node_free_range(struct apfs_node *node, u16 off, u16 len); ++extern bool apfs_node_has_room(struct apfs_node *node, int length, bool replace); ++extern int apfs_node_replace(struct apfs_query *query, void *key, int key_len, void *val, int val_len); ++extern int apfs_node_insert(struct apfs_query *query, void *key, int key_len, void *val, int val_len); ++extern int apfs_create_single_rec_node(struct apfs_query *query, void *key, int key_len, void *val, int val_len); ++extern int apfs_make_empty_btree_root(struct super_block *sb, u32 subtype, u64 *oid); ++ ++/* object.c */ ++extern int apfs_obj_verify_csum(struct super_block *sb, struct buffer_head *bh); ++extern void apfs_obj_set_csum(struct super_block *sb, struct apfs_obj_phys *obj); ++extern int apfs_multiblock_verify_csum(char *object, u32 size); ++extern void apfs_multiblock_set_csum(char *object, u32 size); ++extern int apfs_create_cpm_block(struct super_block *sb, u64 bno, struct buffer_head **bh_p); ++extern int apfs_create_cpoint_map(struct super_block *sb, struct apfs_checkpoint_map_phys *cpm, struct apfs_obj_phys *obj, u64 bno, u32 size); ++extern struct apfs_ephemeral_object_info *apfs_ephemeral_object_lookup(struct super_block *sb, u64 oid); ++extern struct buffer_head *apfs_read_object_block(struct super_block *sb, u64 bno, bool write, bool preserve); ++extern u32 apfs_index_in_data_area(struct super_block *sb, u64 bno); ++extern u64 apfs_data_index_to_bno(struct super_block *sb, u32 index); ++ ++/* snapshot.c */ ++extern int apfs_ioc_take_snapshot(struct file *file, void __user *user_arg); ++extern int apfs_switch_to_snapshot(struct super_block *sb); ++ ++/* spaceman.c */ ++extern int apfs_read_spaceman(struct super_block *sb); ++extern int apfs_free_queue_insert_nocache(struct super_block *sb, u64 bno, u64 count); ++extern int apfs_free_queue_insert(struct super_block *sb, u64 bno, u64 count); ++extern int apfs_spaceman_allocate_block(struct super_block *sb, u64 *bno, bool backwards); ++extern int apfs_write_ip_bitmaps(struct super_block *sb); ++extern int apfs_spaceman_get_free_blkcnt(struct super_block *sb, u64 *blkcnt); ++ ++/* super.c */ ++extern int apfs_map_volume_super_bno(struct super_block *sb, u64 bno, bool check); ++extern int apfs_map_volume_super(struct super_block *sb, bool write); ++extern void apfs_unmap_volume_super(struct super_block *sb); ++extern int apfs_read_omap(struct super_block *sb, bool write); ++extern int apfs_read_catalog(struct super_block *sb, bool write); ++extern int apfs_sync_fs(struct super_block *sb, int wait); ++ ++/* transaction.c */ ++extern int apfs_cpoint_data_free(struct super_block *sb, u64 bno); ++extern void apfs_transaction_init(struct apfs_nx_transaction *trans); ++extern int apfs_transaction_start(struct super_block *sb, enum apfs_trans_kind kind); ++extern int apfs_transaction_commit(struct super_block *sb); ++extern void apfs_inode_join_transaction(struct super_block *sb, struct inode *inode); ++extern int apfs_transaction_join(struct super_block *sb, ++ struct buffer_head *bh); ++void apfs_transaction_abort(struct super_block *sb); ++extern int apfs_transaction_flush_all_inodes(struct super_block *sb); ++extern int apfs_read_ephemeral_objects(struct super_block *sb); ++ ++/* xattr.c */ ++extern int ____apfs_xattr_get(struct inode *inode, const char *name, void *buffer, ++ size_t size, bool only_whole); ++extern int __apfs_xattr_get(struct inode *inode, const char *name, void *buffer, ++ size_t size); ++extern int apfs_delete_all_xattrs(struct inode *inode); ++extern int apfs_xattr_set(struct inode *inode, const char *name, const void *value, ++ size_t size, int flags); ++extern ssize_t apfs_listxattr(struct dentry *dentry, char *buffer, size_t size); ++extern int apfs_xattr_get_compressed_data(struct inode *inode, const char *name, struct apfs_compressed_data *cdata); ++extern void apfs_release_compressed_data(struct apfs_compressed_data *cdata); ++extern int apfs_compressed_data_read(struct apfs_compressed_data *cdata, void *buf, size_t count, u64 offset); ++ ++/* xfield.c */ ++extern int apfs_find_xfield(u8 *xfields, int len, u8 xtype, char **xval); ++extern int apfs_init_xfields(u8 *buffer, int buflen); ++extern int apfs_insert_xfield(u8 *buffer, int buflen, ++ const struct apfs_x_field *xkey, ++ const void *xval); ++ ++/* ++ * Inode and file operations ++ */ ++ ++/* compress.c */ ++extern const struct address_space_operations apfs_compress_aops; ++extern const struct file_operations apfs_compress_file_operations; ++ ++/* dir.c */ ++extern const struct file_operations apfs_dir_operations; ++ ++/* file.c */ ++extern const struct file_operations apfs_file_operations; ++extern const struct inode_operations apfs_file_inode_operations; ++ ++/* namei.c */ ++extern const struct inode_operations apfs_dir_inode_operations; ++extern const struct inode_operations apfs_special_inode_operations; ++extern const struct dentry_operations apfs_dentry_operations; ++ ++/* symlink.c */ ++extern const struct inode_operations apfs_symlink_inode_operations; ++ ++/* xattr.c */ ++extern const struct xattr_handler *apfs_xattr_handlers[]; ++ ++/** ++ * apfs_assert_query_is_valid - Assert that all of a query's ancestors are set ++ * @query: the query to check ++ * ++ * A query may lose some of its ancestors during a node split, but nothing ++ * should be done to such a query until it gets refreshed. ++ */ ++static inline void apfs_assert_query_is_valid(const struct apfs_query *query) ++{ ++ ASSERT(apfs_node_is_root(apfs_query_root(query))); ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) ++#define page_has_buffers(page) folio_buffers(page_folio(page)) ++#endif ++ ++/* ++ * TODO: the following are modified variants of buffer head functions that will ++ * work with the shared block device for the container. The correct approach ++ * here would be to avoid buffer heads and use bios, but for now this will do. ++ */ ++ ++static inline void ++apfs_map_bh(struct buffer_head *bh, struct super_block *sb, sector_t block) ++{ ++ struct apfs_nxsb_info *nxi = NULL; ++ struct apfs_blkdev_info *info = NULL; ++ ++ nxi = APFS_NXI(sb); ++ info = nxi->nx_blkdev_info; ++ ++ /* ++ * Block numbers above s_tier2_bno are for the tier 2 device of a ++ * fusion drive. Don't bother returning an error code if a regular ++ * drive gets corrupted and reports a tier 2 block number: just treat ++ * it the same as any other out-of-range block. ++ */ ++ if (block >= nxi->nx_tier2_bno) { ++ if (nxi->nx_tier2_info) { ++ info = nxi->nx_tier2_info; ++ block -= nxi->nx_tier2_bno; ++ } else { ++ apfs_err(sb, "block number in tier 2 range (0x%llx)", (unsigned long long)block); ++ } ++ } ++ ++ set_buffer_mapped(bh); ++ bh->b_bdev = info->blki_bdev; ++ bh->b_blocknr = block; ++ bh->b_size = sb->s_blocksize; ++} ++ ++static inline struct buffer_head * ++apfs_sb_bread(struct super_block *sb, sector_t block) ++{ ++ struct apfs_nxsb_info *nxi = NULL; ++ struct apfs_blkdev_info *info = NULL; ++ ++ nxi = APFS_NXI(sb); ++ info = nxi->nx_blkdev_info; ++ ++ if (block >= nxi->nx_tier2_bno) { ++ if (!nxi->nx_tier2_info) { ++ /* Not really a fusion drive, so it's corrupted */ ++ apfs_err(sb, "block number in tier 2 range (0x%llx)", (unsigned long long)block); ++ return NULL; ++ } ++ info = nxi->nx_tier2_info; ++ block -= nxi->nx_tier2_bno; ++ } ++ ++ return __bread_gfp(info->blki_bdev, block, sb->s_blocksize, __GFP_MOVABLE); ++} ++ ++/* Like apfs_getblk(), but doesn't mark the buffer uptodate */ ++static inline struct buffer_head * ++__apfs_getblk(struct super_block *sb, sector_t block) ++{ ++ struct apfs_nxsb_info *nxi = NULL; ++ struct apfs_blkdev_info *info = NULL; ++ ++ nxi = APFS_NXI(sb); ++ info = nxi->nx_blkdev_info; ++ ++ if (block >= nxi->nx_tier2_bno) { ++ if (!nxi->nx_tier2_info) { ++ /* Not really a fusion drive, so it's corrupted */ ++ apfs_err(sb, "block number in tier 2 range (0x%llx)", (unsigned long long)block); ++ return NULL; ++ } ++ info = nxi->nx_tier2_info; ++ block -= nxi->nx_tier2_bno; ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ return __getblk_gfp(info->blki_bdev, block, sb->s_blocksize, __GFP_MOVABLE); ++#else ++ return bdev_getblk(info->blki_bdev, block, sb->s_blocksize, __GFP_MOVABLE); ++#endif ++} ++ ++/* Use instead of apfs_sb_bread() for blocks that will just be overwritten */ ++static inline struct buffer_head * ++apfs_getblk(struct super_block *sb, sector_t block) ++{ ++ struct buffer_head *bh = NULL; ++ ++ bh = __apfs_getblk(sb, block); ++ if (bh) ++ set_buffer_uptodate(bh); ++ return bh; ++} ++ ++#endif /* _APFS_H */ +diff --git a/fs/apfs/apfs_raw.h b/fs/apfs/apfs_raw.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/apfs_raw.h +@@ -0,0 +1,1570 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) 2019 Ernesto A. Fernández ++ * ++ * Definitions for all on-disk data structures. ++ */ ++ ++#ifndef _APFS_RAW_H ++#define _APFS_RAW_H ++ ++#include ++#include ++ ++/* Object identifiers constants */ ++#define APFS_OID_NX_SUPERBLOCK 1 ++#define APFS_OID_INVALID 0ULL ++#define APFS_OID_RESERVED_COUNT 1024 ++ ++/* Object type masks */ ++#define APFS_OBJECT_TYPE_MASK 0x0000ffff ++#define APFS_OBJECT_TYPE_FLAGS_MASK 0xffff0000 ++#define APFS_OBJ_STORAGETYPE_MASK 0xc0000000 ++#define APFS_OBJECT_TYPE_FLAGS_DEFINED_MASK 0xf8000000 ++ ++/* Object types */ ++#define APFS_OBJECT_TYPE_NX_SUPERBLOCK 0x00000001 ++#define APFS_OBJECT_TYPE_BTREE 0x00000002 ++#define APFS_OBJECT_TYPE_BTREE_NODE 0x00000003 ++#define APFS_OBJECT_TYPE_SPACEMAN 0x00000005 ++#define APFS_OBJECT_TYPE_SPACEMAN_CAB 0x00000006 ++#define APFS_OBJECT_TYPE_SPACEMAN_CIB 0x00000007 ++#define APFS_OBJECT_TYPE_SPACEMAN_BITMAP 0x00000008 ++#define APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x00000009 ++#define APFS_OBJECT_TYPE_EXTENT_LIST_TREE 0x0000000a ++#define APFS_OBJECT_TYPE_OMAP 0x0000000b ++#define APFS_OBJECT_TYPE_CHECKPOINT_MAP 0x0000000c ++#define APFS_OBJECT_TYPE_FS 0x0000000d ++#define APFS_OBJECT_TYPE_FSTREE 0x0000000e ++#define APFS_OBJECT_TYPE_BLOCKREFTREE 0x0000000f ++#define APFS_OBJECT_TYPE_SNAPMETATREE 0x00000010 ++#define APFS_OBJECT_TYPE_NX_REAPER 0x00000011 ++#define APFS_OBJECT_TYPE_NX_REAP_LIST 0x00000012 ++#define APFS_OBJECT_TYPE_OMAP_SNAPSHOT 0x00000013 ++#define APFS_OBJECT_TYPE_EFI_JUMPSTART 0x00000014 ++#define APFS_OBJECT_TYPE_FUSION_MIDDLE_TREE 0x00000015 ++#define APFS_OBJECT_TYPE_NX_FUSION_WBC 0x00000016 ++#define APFS_OBJECT_TYPE_NX_FUSION_WBC_LIST 0x00000017 ++#define APFS_OBJECT_TYPE_ER_STATE 0x00000018 ++#define APFS_OBJECT_TYPE_GBITMAP 0x00000019 ++#define APFS_OBJECT_TYPE_GBITMAP_TREE 0x0000001a ++#define APFS_OBJECT_TYPE_GBITMAP_BLOCK 0x0000001b ++#define APFS_OBJECT_TYPE_ER_RECOVERY_BLOCK 0x0000001c ++#define APFS_OBJECT_TYPE_SNAP_META_EXT 0x0000001d ++#define APFS_OBJECT_TYPE_INTEGRITY_META 0x0000001e ++#define APFS_OBJECT_TYPE_FEXT_TREE 0x0000001f ++#define APFS_OBJECT_TYPE_RESERVED_20 0x00000020 ++#define APFS_OBJECT_TYPE_INVALID 0x00000000 ++#define APFS_OBJECT_TYPE_TEST 0x000000ff ++ ++/* Object type flags */ ++#define APFS_OBJ_VIRTUAL 0x00000000 ++#define APFS_OBJ_EPHEMERAL 0x80000000 ++#define APFS_OBJ_PHYSICAL 0x40000000 ++#define APFS_OBJ_NOHEADER 0x20000000 ++#define APFS_OBJ_ENCRYPTED 0x10000000 ++#define APFS_OBJ_NONPERSISTENT 0x08000000 ++ ++#define APFS_MAX_CKSUM_SIZE 8 ++ ++/* ++ * On-disk representation of an APFS object ++ */ ++struct apfs_obj_phys { ++/*00*/ __le64 o_cksum; /* Fletcher checksum */ ++ __le64 o_oid; /* Object-id */ ++/*10*/ __le64 o_xid; /* Transaction ID */ ++ __le32 o_type; /* Object type */ ++ __le32 o_subtype; /* Object subtype */ ++} __packed; ++ ++/* Flags for the object map structure */ ++#define APFS_OMAP_MANUALLY_MANAGED 0x00000001 ++#define APFS_OMAP_ENCRYPTING 0x00000002 ++#define APFS_OMAP_DECRYPTING 0x00000004 ++#define APFS_OMAP_KEYROLLING 0x00000008 ++#define APFS_OMAP_CRYPTO_GENERATION 0x00000010 ++#define APFS_OMAP_FLAGS_VALID_MASK (APFS_OMAP_MANUALLY_MANAGED \ ++ | APFS_OMAP_ENCRYPTING \ ++ | APFS_OMAP_DECRYPTING \ ++ | APFS_OMAP_KEYROLLING \ ++ | APFS_OMAP_CRYPTO_GENERATION) ++ ++/* ++ * On-disk representation of an object map ++ */ ++struct apfs_omap_phys { ++/*00*/ struct apfs_obj_phys om_o; ++/*20*/ __le32 om_flags; ++ __le32 om_snap_count; ++ __le32 om_tree_type; ++ __le32 om_snapshot_tree_type; ++/*30*/ __le64 om_tree_oid; ++ __le64 om_snapshot_tree_oid; ++/*40*/ __le64 om_most_recent_snap; ++ __le64 om_pending_revert_min; ++ __le64 om_pending_revert_max; ++} __packed; ++ ++/* Object map value flags */ ++#define APFS_OMAP_VAL_DELETED 0x00000001 ++#define APFS_OMAP_VAL_SAVED 0x00000002 ++#define APFS_OMAP_VAL_ENCRYPTED 0x00000004 ++#define APFS_OMAP_VAL_NOHEADER 0x00000008 ++#define APFS_OMAP_VAL_CRYPTO_GENERATION 0x00000010 ++#define APFS_OMAP_VAL_FLAGS_VALID_MASK (APFS_OMAP_VAL_DELETED \ ++ | APFS_OMAP_VAL_SAVED \ ++ | APFS_OMAP_VAL_ENCRYPTED \ ++ | APFS_OMAP_VAL_NOHEADER \ ++ | APFS_OMAP_VAL_CRYPTO_GENERATION) ++ ++/* ++ * Structure of a value in an object map B-tree ++ */ ++struct apfs_omap_val { ++ __le32 ov_flags; ++ __le32 ov_size; ++ __le64 ov_paddr; ++} __packed; ++ ++/* ++ * Structure of a value in an omap's snapshot tree ++ */ ++struct apfs_omap_snapshot { ++ __le32 oms_flags; ++ __le32 oms_pad; ++ __le64 oms_oid; ++} __packed; ++ ++/* B-tree node flags */ ++#define APFS_BTNODE_ROOT 0x0001 ++#define APFS_BTNODE_LEAF 0x0002 ++#define APFS_BTNODE_FIXED_KV_SIZE 0x0004 ++#define APFS_BTNODE_CHECK_KOFF_INVAL 0x8000 ++#define APFS_BTNODE_MASK 0x0007 /* Valid on-disk flags */ ++ ++/* B-tree location constants */ ++#define APFS_BTOFF_INVALID 0xffff ++ ++/* ++ * Structure storing a location inside a B-tree node ++ */ ++struct apfs_nloc { ++ __le16 off; ++ __le16 len; ++} __packed; ++ ++/* ++ * Structure storing the location of a key/value pair within a B-tree node ++ */ ++struct apfs_kvloc { ++ struct apfs_nloc k; ++ struct apfs_nloc v; ++} __packed; ++ ++/* ++ * Structure storing the location of a key/value pair within a B-tree node ++ * having fixed-size key and value (flag APFS_BTNODE_FIXED_KV_SIZE is present) ++ */ ++struct apfs_kvoff { ++ __le16 k; ++ __le16 v; ++} __packed; ++ ++/* ++ * On-disk representation of a B-tree node ++ */ ++struct apfs_btree_node_phys { ++/*00*/ struct apfs_obj_phys btn_o; ++/*20*/ __le16 btn_flags; ++ __le16 btn_level; ++ __le32 btn_nkeys; ++/*28*/ struct apfs_nloc btn_table_space; ++ struct apfs_nloc btn_free_space; ++ struct apfs_nloc btn_key_free_list; ++ struct apfs_nloc btn_val_free_list; ++/*38*/ __le64 btn_data[]; ++} __packed; ++ ++/* B-tree info flags */ ++#define APFS_BTREE_UINT64_KEYS 0x00000001 ++#define APFS_BTREE_SEQUENTIAL_INSERT 0x00000002 ++#define APFS_BTREE_ALLOW_GHOSTS 0x00000004 ++#define APFS_BTREE_EPHEMERAL 0x00000008 ++#define APFS_BTREE_PHYSICAL 0x00000010 ++#define APFS_BTREE_NONPERSISTENT 0x00000020 ++#define APFS_BTREE_KV_NONALIGNED 0x00000040 ++#define APFS_BTREE_FLAGS_VALID_MASK (APFS_BTREE_UINT64_KEYS \ ++ | APFS_BTREE_SEQUENTIAL_INSERT \ ++ | APFS_BTREE_ALLOW_GHOSTS \ ++ | APFS_BTREE_EPHEMERAL \ ++ | APFS_BTREE_PHYSICAL \ ++ | APFS_BTREE_NONPERSISTENT \ ++ | APFS_BTREE_KV_NONALIGNED) ++ ++/* ++ * Structure used to store information about a B-tree that won't change ++ * over time ++ */ ++struct apfs_btree_info_fixed { ++ __le32 bt_flags; ++ __le32 bt_node_size; ++ __le32 bt_key_size; ++ __le32 bt_val_size; ++} __packed; ++ ++/* ++ * Structure used to store information about a B-tree (located at the end of ++ * a B-tree root node block) ++ */ ++struct apfs_btree_info { ++ struct apfs_btree_info_fixed bt_fixed; ++ __le32 bt_longest_key; /* Longest key ever stored */ ++ __le32 bt_longest_val; /* Longest value ever stored */ ++ __le64 bt_key_count; ++ __le64 bt_node_count; ++} __packed; ++ ++/* ++ * Structure of the value of a directory entry. This is the data in ++ * the catalog nodes for record type APFS_TYPE_DIR_REC. ++ */ ++struct apfs_drec_val { ++ __le64 file_id; ++ __le64 date_added; ++ __le16 flags; ++ u8 xfields[]; ++} __packed; ++ ++/* Physical extent records */ ++#define APFS_PEXT_LEN_MASK 0x0fffffffffffffffULL ++#define APFS_PEXT_KIND_MASK 0xf000000000000000ULL ++#define APFS_PEXT_KIND_SHIFT 60 ++ ++/* The kind of a physical extent record */ ++enum { ++ APFS_KIND_ANY = 0, ++ APFS_KIND_NEW = 1, ++ APFS_KIND_UPDATE = 2, ++ APFS_KIND_DEAD = 3, ++ APFS_KIND_UPDATE_REFCNT = 4, ++ ++ APFS_KIND_INVALID = 255 /* This is weird, won't fit in 4 bits */ ++}; ++ ++#define APFS_OWNING_OBJ_ID_INVALID (~0ULL) ++#define APFS_OWNING_OBJ_ID_UNKNOWN (~1ULL) ++ ++/* ++ * Structure of a physical extent record ++ */ ++struct apfs_phys_ext_val { ++ __le64 len_and_kind; ++ __le64 owning_obj_id; ++ __le32 refcnt; ++} __packed; ++ ++/* File extent records */ ++#define APFS_FILE_EXTENT_LEN_MASK 0x00ffffffffffffffULL ++#define APFS_FILE_EXTENT_FLAG_MASK 0xff00000000000000ULL ++#define APFS_FILE_EXTENT_FLAG_SHIFT 56 ++#define APFS_FILE_EXTENT_CRYPTO_FLAG 0x01 /* Made-up name */ ++#define APFS_FILE_EXTENT_PREALLOCATED 0x02 /* Made-up name */ ++#define APFS_VALID_FILE_EXTENT_FLAGS (APFS_FILE_EXTENT_CRYPTO_FLAG \ ++ | APFS_FILE_EXTENT_PREALLOCATED) ++ ++/* ++ * Put a bound on maximum file size so that a growing truncation will always ++ * produce a single hole extent, even if 64k block sizes were in use. Larger ++ * file sizes could be supported with multiple extents of course, but it takes ++ * some work and I don't see the point. ++ */ ++#define APFS_MAX_FILE_SIZE 0x00ffffffffff0000ULL ++ ++/* ++ * Structure of a file extent record ++ */ ++struct apfs_file_extent_val { ++ __le64 len_and_flags; ++ __le64 phys_block_num; ++ __le64 crypto_id; ++} __packed; ++ ++/* ++ * Structure of a data stream record ++ */ ++struct apfs_dstream_id_val { ++ __le32 refcnt; ++} __packed; ++ ++#define APFS_CP_MAX_WRAPPEDKEYSIZE 128 ++ ++/* ++ * Structure used to store the encryption state for PFKs ++ */ ++struct apfs_wrapped_crypto_state { ++ __le16 major_version; ++ __le16 minor_version; ++ __le32 cpflags; ++ __le32 persistent_class; ++ __le32 key_os_version; ++ __le16 key_revision; ++ __le16 key_len; ++ u8 persistent_key[]; ++} __packed; ++ ++/* ++ * Structure of a crypto state record ++ */ ++struct apfs_crypto_state_val { ++ __le32 refcnt; ++ struct apfs_wrapped_crypto_state state; ++} __packed; ++ ++/* Inode numbers for special inodes */ ++#define APFS_INVALID_INO_NUM 0 ++ ++#define APFS_ROOT_DIR_PARENT 1 /* Root directory parent */ ++#define APFS_ROOT_DIR_INO_NUM 2 /* Root directory */ ++#define APFS_PRIV_DIR_INO_NUM 3 /* Private directory */ ++#define APFS_SNAP_DIR_INO_NUM 6 /* Snapshots metadata */ ++#define APFS_PURGEABLE_DIR_INO_NUM 7 /* Parent of purgeable files */ ++ ++/* Smallest inode number available for user content */ ++#define APFS_MIN_USER_INO_NUM 16 ++ ++#define APFS_UNIFIED_ID_SPACE_MARK 0x0800000000000000 ++ ++/* Inode internal flags */ ++#define APFS_INODE_IS_APFS_PRIVATE 0x00000001 ++#define APFS_INODE_MAINTAIN_DIR_STATS 0x00000002 ++#define APFS_INODE_DIR_STATS_ORIGIN 0x00000004 ++#define APFS_INODE_PROT_CLASS_EXPLICIT 0x00000008 ++#define APFS_INODE_WAS_CLONED 0x00000010 ++#define APFS_INODE_FLAG_UNUSED 0x00000020 ++#define APFS_INODE_HAS_SECURITY_EA 0x00000040 ++#define APFS_INODE_BEING_TRUNCATED 0x00000080 ++#define APFS_INODE_HAS_FINDER_INFO 0x00000100 ++#define APFS_INODE_IS_SPARSE 0x00000200 ++#define APFS_INODE_WAS_EVER_CLONED 0x00000400 ++#define APFS_INODE_ACTIVE_FILE_TRIMMED 0x00000800 ++#define APFS_INODE_PINNED_TO_MAIN 0x00001000 ++#define APFS_INODE_PINNED_TO_TIER2 0x00002000 ++#define APFS_INODE_HAS_RSRC_FORK 0x00004000 ++#define APFS_INODE_NO_RSRC_FORK 0x00008000 ++#define APFS_INODE_ALLOCATION_SPILLEDOVER 0x00010000 ++#define APFS_INODE_FAST_PROMOTE 0x00020000 ++#define APFS_INODE_HAS_UNCOMPRESSED_SIZE 0x00040000 ++#define APFS_INODE_IS_PURGEABLE 0x00080000 ++#define APFS_INODE_WANTS_TO_BE_PURGEABLE 0x00100000 ++#define APFS_INODE_IS_SYNC_ROOT 0x00200000 ++#define APFS_INODE_SNAPSHOT_COW_EXEMPTION 0x00400000 ++/* This flag is not documented */ ++#define APFS_INODE_HAS_PURGEABLE_FLAGS 0x02000000 ++ ++/* Masks for internal flags */ ++#define APFS_VALID_INTERNAL_INODE_FLAGS (APFS_INODE_IS_APFS_PRIVATE \ ++ | APFS_INODE_MAINTAIN_DIR_STATS \ ++ | APFS_INODE_DIR_STATS_ORIGIN \ ++ | APFS_INODE_PROT_CLASS_EXPLICIT \ ++ | APFS_INODE_WAS_CLONED \ ++ | APFS_INODE_HAS_SECURITY_EA \ ++ | APFS_INODE_BEING_TRUNCATED \ ++ | APFS_INODE_HAS_FINDER_INFO \ ++ | APFS_INODE_IS_SPARSE \ ++ | APFS_INODE_WAS_EVER_CLONED \ ++ | APFS_INODE_ACTIVE_FILE_TRIMMED \ ++ | APFS_INODE_PINNED_TO_MAIN \ ++ | APFS_INODE_PINNED_TO_TIER2 \ ++ | APFS_INODE_HAS_RSRC_FORK \ ++ | APFS_INODE_NO_RSRC_FORK \ ++ | APFS_INODE_ALLOCATION_SPILLEDOVER \ ++ | APFS_INODE_FAST_PROMOTE \ ++ | APFS_INODE_HAS_UNCOMPRESSED_SIZE \ ++ | APFS_INODE_IS_PURGEABLE \ ++ | APFS_INODE_WANTS_TO_BE_PURGEABLE \ ++ | APFS_INODE_IS_SYNC_ROOT \ ++ | APFS_INODE_SNAPSHOT_COW_EXEMPTION \ ++ | APFS_INODE_HAS_PURGEABLE_FLAGS) ++#define APFS_INODE_INHERITED_INTERNAL_FLAGS (APFS_INODE_MAINTAIN_DIR_STATS) ++#define APFS_INDOE_CLONED_INTERNAL_FLAGS (APFS_INODE_HAS_RSRC_FORK \ ++ | APFS_INODE_NO_RSRC_FORK \ ++ | APFS_INODE_HAS_FINDER_INFO) ++#define APFS_INODE_PINNED_MASK (APFS_INODE_PINNED_TO_MAIN \ ++ | APFS_INODE_PINNED_TO_TIER2) ++ ++/* BSD flags */ ++#define APFS_INOBSD_NODUMP 0x00000001 ++#define APFS_INOBSD_IMMUTABLE 0x00000002 ++#define APFS_INOBSD_APPEND 0x00000004 ++#define APFS_INOBSD_COMPRESSED 0x00000020 ++ ++/* ++ * Structure of an inode as stored as a B-tree value ++ */ ++struct apfs_inode_val { ++/*00*/ __le64 parent_id; ++ __le64 private_id; ++/*10*/ __le64 create_time; ++ __le64 mod_time; ++ __le64 change_time; ++ __le64 access_time; ++/*30*/ __le64 internal_flags; ++ union { ++ __le32 nchildren; ++ __le32 nlink; ++ }; ++ __le32 default_protection_class; ++/*40*/ __le32 write_generation_counter; ++ __le32 bsd_flags; ++ __le32 owner; ++ __le32 group; ++/*50*/ __le16 mode; ++ __le16 pad1; ++ __le64 uncompressed_size; ++/*5C*/ u8 xfields[]; ++} __packed; ++ ++/* Extended field types for dentries */ ++#define APFS_DREC_EXT_TYPE_SIBLING_ID 1 ++ ++/* Extended field types for inodes */ ++#define APFS_INO_EXT_TYPE_SNAP_XID 1 ++#define APFS_INO_EXT_TYPE_DELTA_TREE_OID 2 ++#define APFS_INO_EXT_TYPE_DOCUMENT_ID 3 ++#define APFS_INO_EXT_TYPE_NAME 4 ++#define APFS_INO_EXT_TYPE_PREV_FSIZE 5 ++#define APFS_INO_EXT_TYPE_RESERVED_6 6 ++#define APFS_INO_EXT_TYPE_FINDER_INFO 7 ++#define APFS_INO_EXT_TYPE_DSTREAM 8 ++#define APFS_INO_EXT_TYPE_RESERVED_9 9 ++#define APFS_INO_EXT_TYPE_DIR_STATS_KEY 10 ++#define APFS_INO_EXT_TYPE_FS_UUID 11 ++#define APFS_INO_EXT_TYPE_RESERVED_12 12 ++#define APFS_INO_EXT_TYPE_SPARSE_BYTES 13 ++#define APFS_INO_EXT_TYPE_RDEV 14 ++#define APFS_INO_EXT_TYPE_PURGEABLE_FLAGS 15 ++#define APFS_INO_EXT_TYPE_ORIG_SYNC_ROOT_ID 16 ++ ++/* Extended field flags */ ++#define APFS_XF_DATA_DEPENDENT 0x01 ++#define APFS_XF_DO_NOT_COPY 0x02 ++#define APFS_XF_RESERVED_4 0x04 ++#define APFS_XF_CHILDREN_INHERIT 0x08 ++#define APFS_XF_USER_FIELD 0x10 ++#define APFS_XF_SYSTEM_FIELD 0x20 ++#define APFS_XF_RESERVED_40 0x40 ++#define APFS_XF_RESERVED_80 0x80 ++ ++/* Constants for extended fields */ ++#define APFS_MIN_DOC_ID 3 /* Smallest not reserved document id */ ++ ++/* ++ * Structure used to store the number and size of an xfield collection. The ++ * official reference seems to be wrong about @xf_used_data: it's the size of ++ * the xfield values alone, without the metadata. ++ */ ++struct apfs_xf_blob { ++ __le16 xf_num_exts; ++ __le16 xf_used_data; ++ u8 xf_data[]; ++} __packed; ++ ++/* ++ * Structure used to describe an extended field ++ */ ++struct apfs_x_field { ++ u8 x_type; ++ u8 x_flags; ++ __le16 x_size; ++} __packed; ++ ++/* ++ * Structure used to store information about a data stream ++ */ ++struct apfs_dstream { ++ __le64 size; ++ __le64 alloced_size; ++ __le64 default_crypto_id; ++ __le64 total_bytes_written; ++ __le64 total_bytes_read; ++} __packed; ++ ++/* ++ * Structure used to store directory information ++ */ ++struct apfs_dir_stats_val { ++ __le64 num_children; ++ __le64 total_size; ++ __le64 chained_key; ++ __le64 gen_count; ++} __packed; ++ ++/* ++ * Structure of the value for a sibling link record. These are used to ++ * list the hard links for a given inode. ++ */ ++struct apfs_sibling_val { ++ __le64 parent_id; ++ __le16 name_len; ++ u8 name[]; ++} __packed; ++ ++/* ++ * Structure of the value for a sibling map record. No idea what these are for. ++ */ ++struct apfs_sibling_map_val { ++ __le64 file_id; ++} __packed; ++ ++/* ++ * Structure of a key in an object map B-tree ++ */ ++struct apfs_omap_key { ++ __le64 ok_oid; ++ __le64 ok_xid; ++} __packed; ++ ++/* ++ * Structure of a key in a free-space queue b-tree ++ */ ++struct apfs_spaceman_free_queue_key { ++ __le64 sfqk_xid; ++ __le64 sfqk_paddr; ++} __packed; ++ ++/* Catalog records types */ ++enum { ++ APFS_TYPE_ANY = 0, ++ APFS_TYPE_SNAP_METADATA = 1, ++ APFS_TYPE_EXTENT = 2, ++ APFS_TYPE_INODE = 3, ++ APFS_TYPE_XATTR = 4, ++ APFS_TYPE_SIBLING_LINK = 5, ++ APFS_TYPE_DSTREAM_ID = 6, ++ APFS_TYPE_CRYPTO_STATE = 7, ++ APFS_TYPE_FILE_EXTENT = 8, ++ APFS_TYPE_DIR_REC = 9, ++ APFS_TYPE_DIR_STATS = 10, ++ APFS_TYPE_SNAP_NAME = 11, ++ APFS_TYPE_SIBLING_MAP = 12, ++ APFS_TYPE_MAX_VALID = 12, ++ APFS_TYPE_MAX = 15, ++ APFS_TYPE_INVALID = 15, ++}; ++ ++/* Bit masks for the 'obj_id_and_type' field of a key header */ ++#define APFS_OBJ_ID_MASK 0x0fffffffffffffffULL ++#define APFS_OBJ_TYPE_MASK 0xf000000000000000ULL ++#define APFS_OBJ_TYPE_SHIFT 60 ++ ++/* Key header for filesystem-object keys */ ++struct apfs_key_header { ++ __le64 obj_id_and_type; ++} __packed; ++ ++/* ++ * Structure of the key for a physical extent record ++ */ ++struct apfs_phys_ext_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* ++ * Structure of the key for an inode record ++ */ ++struct apfs_inode_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* ++ * Structure of the key for a file extent record ++ */ ++struct apfs_file_extent_key { ++ struct apfs_key_header hdr; ++ __le64 logical_addr; ++} __packed; ++ ++/* ++ * Structure of the key for a data stream record ++ */ ++struct apfs_dstream_id_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* ++ * Structure of the key for a crypto state record ++ */ ++struct apfs_crypto_state_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* Bit masks for the 'name_len_and_hash' field of a directory entry */ ++#define APFS_DREC_LEN_MASK 0x000003ff ++#define APFS_DREC_HASH_MASK 0xfffffc00 ++#define APFS_DREC_HASH_SHIFT 10 ++ ++/* We could support bigger filenames, but I don't know if Linux allows it */ ++#define APFS_NAME_LEN NAME_MAX ++ ++/* Bit masks for the 'type' field of a directory entry */ ++enum { ++ APFS_DREC_TYPE_MASK = 0x000f, ++ APFS_DREC_RESERVED_10 = 0x0010, ++ ++ /* These flags are not documented */ ++ APFS_DREC_PURGEABLE_2 = 0x0200, ++ APFS_DREC_PURGEABLE_8 = 0x0800, ++}; ++ ++#define APFS_DREC_PURGEABLE (APFS_DREC_PURGEABLE_2 | APFS_DREC_PURGEABLE_8) ++ ++/* ++ * Structure of the key for a directory entry - no hash, used on normalization ++ * sensitive volumes ++ */ ++struct apfs_drec_key { ++ struct apfs_key_header hdr; ++ __le16 name_len; ++ u8 name[]; ++} __packed; ++ ++/* ++ * Structure of the key for a directory entry, including a precomputed ++ * hash of its name ++ */ ++struct apfs_drec_hashed_key { ++ struct apfs_key_header hdr; ++ __le32 name_len_and_hash; ++ u8 name[]; ++} __packed; ++ ++/* ++ * Structure of the key for an extended attributes record ++ */ ++struct apfs_xattr_key { ++ struct apfs_key_header hdr; ++ __le16 name_len; ++ u8 name[]; ++} __packed; ++ ++/* ++ * Structure of the key for a snapshot metadata record ++ */ ++struct apfs_snap_metadata_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* The snapshot name headers always have this placeholder object id */ ++#define APFS_SNAP_NAME_OBJ_ID (~0ULL & APFS_OBJ_ID_MASK) ++ ++/* ++ * Structure of the key for a snapshot name record ++ */ ++struct apfs_snap_name_key { ++ struct apfs_key_header hdr; ++ __le16 name_len; ++ u8 name[]; ++} __packed; ++ ++/* ++ * Structure of the key for a sibling link record ++ */ ++struct apfs_sibling_link_key { ++ struct apfs_key_header hdr; ++ __le64 sibling_id; ++} __packed; ++ ++/* ++ * Structure of the key for a siblink map record ++ */ ++struct apfs_sibling_map_key { ++ struct apfs_key_header hdr; ++} __packed; ++ ++/* ++ * On-disk allocation info for a chunk of blocks ++ */ ++struct apfs_chunk_info { ++ __le64 ci_xid; ++ __le64 ci_addr; ++ __le32 ci_block_count; ++ __le32 ci_free_count; ++ __le64 ci_bitmap_addr; ++} __packed; ++ ++/* Constants for the chunk info block */ ++#define APFS_CI_COUNT_MASK 0x000FFFFF ++#define APFS_CI_COUNT_RESERVED_MASK 0xFFF00000 ++ ++/* ++ * Structure of a block with an array of chunk allocation info structures ++ */ ++struct apfs_chunk_info_block { ++ struct apfs_obj_phys cib_o; ++ __le32 cib_index; ++ __le32 cib_chunk_info_count; ++ struct apfs_chunk_info cib_chunk_info[]; ++} __packed; ++ ++/* ++ * Structure of a block with an array of addresses to chunk information blocks ++ */ ++struct apfs_cib_addr_block { ++ struct apfs_obj_phys cab_o; ++ __le32 cab_index; ++ __le32 cab_cib_count; ++ __le64 cab_cib_addr[]; ++} __packed; ++ ++/* ++ * On-disk structure for a free queue ++ */ ++struct apfs_spaceman_free_queue { ++ __le64 sfq_count; ++ __le64 sfq_tree_oid; ++ __le64 sfq_oldest_xid; ++ __le16 sfq_tree_node_limit; ++ __le16 sfq_pad16; ++ __le32 sfq_pad32; ++ __le64 sfq_reserved; ++} __packed; ++ ++/* Indexes for a free queue array */ ++enum { ++ APFS_SFQ_IP = 0, ++ APFS_SFQ_MAIN = 1, ++ APFS_SFQ_TIER2 = 2, ++ APFS_SFQ_COUNT = 3 ++}; ++ ++/* ++ * On-disk structure for device allocation information ++ */ ++struct apfs_spaceman_device { ++ __le64 sm_block_count; ++ __le64 sm_chunk_count; ++ __le32 sm_cib_count; ++ __le32 sm_cab_count; ++ __le64 sm_free_count; ++ __le32 sm_addr_offset; ++ __le32 sm_reserved; ++ __le64 sm_reserved2; ++} __packed; ++ ++/* Indexes for a device array */ ++enum { ++ APFS_SD_MAIN = 0, ++ APFS_SD_TIER2 = 1, ++ APFS_SD_COUNT = 2 ++}; ++ ++/* ++ * On-disk structure to describe allocation zone boundaries ++ */ ++struct apfs_spaceman_allocation_zone_boundaries { ++ __le64 saz_zone_start; ++ __le64 saz_zone_end; ++} __packed; ++ ++/* Allocation zone constants */ ++#define APFS_SM_ALLOCZONE_INVALID_END_BOUNDARY 0 ++#define APFS_SM_ALLOCZONE_NUM_PREVIOUS_BOUNDARIES 7 ++ ++struct apfs_spaceman_allocation_zone_info_phys { ++ struct apfs_spaceman_allocation_zone_boundaries saz_current_boundaries; ++ struct apfs_spaceman_allocation_zone_boundaries ++ saz_previous_boundaries[APFS_SM_ALLOCZONE_NUM_PREVIOUS_BOUNDARIES]; ++ ++ __le16 saz_zone_id; ++ __le16 saz_previous_boundary_index; ++ __le32 saz_reserved; ++} __packed; ++ ++/* Datazone constants */ ++#define APFS_SM_DATAZONE_ALLOCZONE_COUNT 8 ++ ++struct apfs_spaceman_datazone_info_phys { ++ struct apfs_spaceman_allocation_zone_info_phys ++ sdz_allocation_zones[APFS_SD_COUNT][APFS_SM_DATAZONE_ALLOCZONE_COUNT]; ++} __packed; ++ ++/* Internal-pool bitmap constants */ ++#define APFS_SPACEMAN_IP_BM_TX_MULTIPLIER 16 ++#define APFS_SPACEMAN_IP_BM_INDEX_INVALID 0xFFFF ++#define APFS_SPACEMAN_IP_BM_BLOCK_COUNT_MAX 0xFFFE ++ ++/* Space manager flags */ ++#define APFS_SM_FLAG_VERSIONED 0x00000001 ++#define APFS_SM_FLAGS_VALID_MASK APFS_SM_FLAG_VERSIONED ++ ++/* ++ * On-disk structure for the space manager ++ */ ++struct apfs_spaceman_phys { ++ struct apfs_obj_phys sm_o; ++ __le32 sm_block_size; ++ __le32 sm_blocks_per_chunk; ++ __le32 sm_chunks_per_cib; ++ __le32 sm_cibs_per_cab; ++ struct apfs_spaceman_device sm_dev[APFS_SD_COUNT]; ++ __le32 sm_flags; ++ __le32 sm_ip_bm_tx_multiplier; ++ __le64 sm_ip_block_count; ++ __le32 sm_ip_bm_size_in_blocks; ++ __le32 sm_ip_bm_block_count; ++ __le64 sm_ip_bm_base; ++ __le64 sm_ip_base; ++ __le64 sm_fs_reserve_block_count; ++ __le64 sm_fs_reserve_alloc_count; ++ struct apfs_spaceman_free_queue sm_fq[APFS_SFQ_COUNT]; ++ __le16 sm_ip_bm_free_head; ++ __le16 sm_ip_bm_free_tail; ++ __le32 sm_ip_bm_xid_offset; ++ __le32 sm_ip_bitmap_offset; ++ __le32 sm_ip_bm_free_next_offset; ++ __le32 sm_version; ++ __le32 sm_struct_size; ++ struct apfs_spaceman_datazone_info_phys sm_datazone; ++} __packed; ++ ++/* ++ * Structure used to store a range of physical blocks ++ */ ++struct apfs_prange { ++ __le64 pr_start_paddr; ++ __le64 pr_block_count; ++} __packed; ++ ++/* Reaper flags */ ++#define APFS_NR_BHM_FLAG 0x00000001 ++#define APFS_NR_CONTINUE 0x00000002 ++#define APFS_NR_FLAGS_VALID_MASK (APFS_NR_BHM_FLAG | APFS_NR_CONTINUE) ++ ++/* ++ * On-disk reaper structure ++ */ ++struct apfs_nx_reaper_phys { ++ struct apfs_obj_phys nr_o; ++ __le64 nr_next_reap_id; ++ __le64 nr_completed_id; ++ __le64 nr_head; ++ __le64 nr_tail; ++ __le32 nr_flags; ++ __le32 nr_rlcount; ++ __le32 nr_type; ++ __le32 nr_size; ++ __le64 nr_fs_oid; ++ __le64 nr_oid; ++ __le64 nr_xid; ++ __le32 nr_nrle_flags; ++ __le32 nr_state_buffer_size; ++ u8 nr_state_buffer[]; ++} __packed; ++ ++struct apfs_nx_reap_list_entry { ++ __le32 nrle_next; ++ __le32 nrle_flags; ++ __le32 nrle_type; ++ __le32 nrle_size; ++ __le64 nrle_fs_oid; ++ __le64 nrle_oid; ++ __le64 nrle_xid; ++} __packed; ++ ++struct apfs_nx_reap_list_phys { ++ struct apfs_obj_phys nrl_o; ++ __le64 nrl_next; ++ __le32 nrl_flags; ++ __le32 nrl_max; ++ __le32 nrl_count; ++ __le32 nrl_first; ++ __le32 nrl_last; ++ __le32 nrl_free; ++ struct apfs_nx_reap_list_entry nrl_entries[]; ++} __packed; ++ ++/* EFI constants */ ++#define APFS_NX_EFI_JUMPSTART_MAGIC 0x5244534A ++#define APFS_NX_EFI_JUMPSTART_VERSION 1 ++ ++/* ++ * Information about the embedded EFI driver ++ */ ++struct apfs_nx_efi_jumpstart { ++ struct apfs_obj_phys nej_o; ++ __le32 nej_magic; ++ __le32 nej_version; ++ __le32 nej_efi_file_len; ++ __le32 nej_num_extents; ++ __le64 nej_reserved[16]; ++ struct apfs_prange nej_rec_extents[]; ++} __packed; ++ ++/* Main container */ ++ ++/* Container constants */ ++#define APFS_NX_MAGIC 0x4253584E ++#define APFS_NX_BLOCK_NUM 0 ++#define APFS_NX_MAX_FILE_SYSTEMS 100 ++ ++#define APFS_NX_EPH_INFO_COUNT 4 ++#define APFS_NX_EPH_MIN_BLOCK_COUNT 8 ++#define APFS_NX_MAX_FILE_SYSTEM_EPH_STRUCTS 4 ++#define APFS_NX_TX_MIN_CHECKPOINT_COUNT 4 ++#define APFS_NX_EPH_INFO_VERSION_1 1 ++ ++/* Container flags */ ++#define APFS_NX_RESERVED_1 0x00000001LL ++#define APFS_NX_RESERVED_2 0x00000002LL ++#define APFS_NX_CRYPTO_SW 0x00000004LL ++#define APFS_NX_FLAGS_VALID_MASK (APFS_NX_RESERVED_1 \ ++ | APFS_NX_RESERVED_2 \ ++ | APFS_NX_CRYPTO_SW) ++ ++/* Optional container feature flags */ ++#define APFS_NX_FEATURE_DEFRAG 0x0000000000000001ULL ++#define APFS_NX_FEATURE_LCFD 0x0000000000000002ULL ++#define APFS_NX_SUPPORTED_FEATURES_MASK (APFS_NX_FEATURE_DEFRAG | \ ++ APFS_NX_FEATURE_LCFD) ++ ++/* Read-only compatible container feature flags */ ++#define APFS_NX_SUPPORTED_ROCOMPAT_MASK (0x0ULL) ++ ++/* Incompatible container feature flags */ ++#define APFS_NX_INCOMPAT_VERSION1 0x0000000000000001ULL ++#define APFS_NX_INCOMPAT_VERSION2 0x0000000000000002ULL ++#define APFS_NX_INCOMPAT_FUSION 0x0000000000000100ULL ++#define APFS_NX_SUPPORTED_INCOMPAT_MASK (APFS_NX_INCOMPAT_VERSION2 \ ++ | APFS_NX_INCOMPAT_FUSION) ++ ++/* Block and container sizes */ ++#define APFS_NX_MINIMUM_BLOCK_SIZE 4096 ++#define APFS_NX_DEFAULT_BLOCK_SIZE 4096 ++#define APFS_NX_MAXIMUM_BLOCK_SIZE 65536 ++#define APFS_NX_MINIMUM_CONTAINER_SIZE 1048576 ++ ++/* Indexes into a container superblock's array of counters */ ++enum { ++ APFS_NX_CNTR_OBJ_CKSUM_SET = 0, ++ APFS_NX_CNTR_OBJ_CKSUM_FAIL = 1, ++ ++ APFS_NX_NUM_COUNTERS = 32 ++}; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) ++#define UUID_SIZE 16 ++#endif ++ ++/* ++ * On-disk representation of the container superblock ++ */ ++struct apfs_nx_superblock { ++/*00*/ struct apfs_obj_phys nx_o; ++/*20*/ __le32 nx_magic; ++ __le32 nx_block_size; ++ __le64 nx_block_count; ++ ++/*30*/ __le64 nx_features; ++ __le64 nx_readonly_compatible_features; ++ __le64 nx_incompatible_features; ++ ++/*48*/ char nx_uuid[UUID_SIZE]; ++ ++/*58*/ __le64 nx_next_oid; ++ __le64 nx_next_xid; ++ ++/*68*/ __le32 nx_xp_desc_blocks; ++ __le32 nx_xp_data_blocks; ++/*70*/ __le64 nx_xp_desc_base; ++ __le64 nx_xp_data_base; ++ __le32 nx_xp_desc_next; ++ __le32 nx_xp_data_next; ++/*88*/ __le32 nx_xp_desc_index; ++ __le32 nx_xp_desc_len; ++ __le32 nx_xp_data_index; ++ __le32 nx_xp_data_len; ++ ++/*98*/ __le64 nx_spaceman_oid; ++ __le64 nx_omap_oid; ++ __le64 nx_reaper_oid; ++ ++/*B0*/ __le32 nx_test_type; ++ ++ __le32 nx_max_file_systems; ++/*B8*/ __le64 nx_fs_oid[APFS_NX_MAX_FILE_SYSTEMS]; ++/*3D8*/ __le64 nx_counters[APFS_NX_NUM_COUNTERS]; ++/*4D8*/ struct apfs_prange nx_blocked_out_prange; ++ __le64 nx_evict_mapping_tree_oid; ++/*4F0*/ __le64 nx_flags; ++ __le64 nx_efi_jumpstart; ++/*500*/ char nx_fusion_uuid[UUID_SIZE]; ++ struct apfs_prange nx_keylocker; ++/*520*/ __le64 nx_ephemeral_info[APFS_NX_EPH_INFO_COUNT]; ++ ++/*540*/ __le64 nx_test_oid; ++ ++ __le64 nx_fusion_mt_oid; ++/*550*/ __le64 nx_fusion_wbc_oid; ++ struct apfs_prange nx_fusion_wbc; ++ ++ __le64 nx_newest_mounted_version; ++ ++/*570*/ struct apfs_prange nx_mkb_locker; ++} __packed; ++ ++/* ++ * A mapping from an ephemeral object id to its physical address ++ */ ++struct apfs_checkpoint_mapping { ++ __le32 cpm_type; ++ __le32 cpm_subtype; ++ __le32 cpm_size; ++ __le32 cpm_pad; ++ __le64 cpm_fs_oid; ++ __le64 cpm_oid; ++ __le64 cpm_paddr; ++} __packed; ++ ++/* Checkpoint flags */ ++#define APFS_CHECKPOINT_MAP_LAST 0x00000001 ++ ++/* ++ * A checkpoint-mapping block ++ */ ++struct apfs_checkpoint_map_phys { ++ struct apfs_obj_phys cpm_o; ++ __le32 cpm_flags; ++ __le32 cpm_count; ++ struct apfs_checkpoint_mapping cpm_map[]; ++} __packed; ++ ++/* Volume */ ++ ++/* Volume constants */ ++#define APFS_MAGIC 0x42535041 ++ ++#define APFS_MAX_HIST 8 ++#define APFS_VOLNAME_LEN 256 ++ ++/* Volume flags */ ++#define APFS_FS_UNENCRYPTED 0x00000001LL ++#define APFS_FS_EFFACEABLE 0x00000002LL ++#define APFS_FS_RESERVED_4 0x00000004LL ++#define APFS_FS_ONEKEY 0x00000008LL ++#define APFS_FS_SPILLEDOVER 0x00000010LL ++#define APFS_FS_RUN_SPILLOVER_CLEANER 0x00000020LL ++#define APFS_FS_ALWAYS_CHECK_EXTENTREF 0x00000040LL ++#define APFS_FS_PREVIOUSLY_SEALED 0x00000080LL /* Made-up name */ ++#define APFS_FS_PFK 0x00000100LL /* Made-up name */ ++#define APFS_FS_UNKNOWN_200 0x00000200LL ++#define APFS_FS_FLAGS_VALID_MASK (APFS_FS_UNENCRYPTED \ ++ | APFS_FS_EFFACEABLE \ ++ | APFS_FS_RESERVED_4 \ ++ | APFS_FS_ONEKEY \ ++ | APFS_FS_SPILLEDOVER \ ++ | APFS_FS_RUN_SPILLOVER_CLEANER \ ++ | APFS_FS_ALWAYS_CHECK_EXTENTREF \ ++ | APFS_FS_PREVIOUSLY_SEALED \ ++ | APFS_FS_PFK \ ++ | APFS_FS_UNKNOWN_200) ++ ++#define APFS_FS_CRYPTOFLAGS (APFS_FS_UNENCRYPTED \ ++ | APFS_FS_EFFACEABLE \ ++ | APFS_FS_ONEKEY) ++ ++/* Volume roles */ ++#define APFS_VOLUME_ENUM_SHIFT 6 ++#define APFS_VOL_ROLE_NONE 0x0000 ++#define APFS_VOL_ROLE_SYSTEM 0x0001 ++#define APFS_VOL_ROLE_USER 0x0002 ++#define APFS_VOL_ROLE_RECOVERY 0x0004 ++#define APFS_VOL_ROLE_VM 0x0008 ++#define APFS_VOL_ROLE_PREBOOT 0x0010 ++#define APFS_VOL_ROLE_INSTALLER 0x0020 ++#define APFS_VOL_ROLE_DATA (1 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_BASEBAND (2 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_UPDATE (3 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_XART (4 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_HARDWARE (5 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_BACKUP (6 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_RESERVED_7 (7 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_RESERVED_8 (8 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_ENTERPRISE (9 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_RESERVED_10 (10 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLE_PRELOGIN (11 << APFS_VOLUME_ENUM_SHIFT) ++#define APFS_VOL_ROLES_VALID_MASK (APFS_VOL_ROLE_SYSTEM \ ++ | APFS_VOL_ROLE_USER \ ++ | APFS_VOL_ROLE_RECOVERY \ ++ | APFS_VOL_ROLE_VM \ ++ | APFS_VOL_ROLE_PREBOOT \ ++ | APFS_VOL_ROLE_INSTALLER \ ++ | APFS_VOL_ROLE_DATA \ ++ | APFS_VOL_ROLE_BASEBAND \ ++ | APFS_VOL_ROLE_UPDATE \ ++ | APFS_VOL_ROLE_XART \ ++ | APFS_VOL_ROLE_HARDWARE \ ++ | APFS_VOL_ROLE_BACKUP \ ++ | APFS_VOL_ROLE_RESERVED_7 \ ++ | APFS_VOL_ROLE_RESERVED_8 \ ++ | APFS_VOL_ROLE_ENTERPRISE \ ++ | APFS_VOL_ROLE_RESERVED_10 \ ++ | APFS_VOL_ROLE_PRELOGIN) ++ ++/* Optional volume feature flags */ ++#define APFS_FEATURE_DEFRAG_PRERELEASE 0x00000001LL ++#define APFS_FEATURE_HARDLINK_MAP_RECORDS 0x00000002LL ++#define APFS_FEATURE_DEFRAG 0x00000004LL ++#define APFS_FEATURE_STRICTATIME 0x00000008LL ++#define APFS_FEATURE_VOLGRP_SYSTEM_INO_SPACE 0x00000010LL ++ ++#define APFS_SUPPORTED_FEATURES_MASK (APFS_FEATURE_DEFRAG \ ++ | APFS_FEATURE_DEFRAG_PRERELEASE \ ++ | APFS_FEATURE_HARDLINK_MAP_RECORDS \ ++ | APFS_FEATURE_STRICTATIME \ ++ | APFS_FEATURE_VOLGRP_SYSTEM_INO_SPACE) ++ ++/* Read-only compatible volume feature flags */ ++#define APFS_SUPPORTED_ROCOMPAT_MASK (0x0ULL) ++ ++/* Incompatible volume feature flags */ ++#define APFS_INCOMPAT_CASE_INSENSITIVE 0x00000001LL ++#define APFS_INCOMPAT_DATALESS_SNAPS 0x00000002LL ++#define APFS_INCOMPAT_ENC_ROLLED 0x00000004LL ++#define APFS_INCOMPAT_NORMALIZATION_INSENSITIVE 0x00000008LL ++#define APFS_INCOMPAT_INCOMPLETE_RESTORE 0x00000010LL ++#define APFS_INCOMPAT_SEALED_VOLUME 0x00000020LL ++#define APFS_INCOMPAT_PFK 0x00000040LL /* Made-up name */ ++#define APFS_INCOMPAT_EXTENT_PREALLOC_FLAG 0x00000080LL /* Made-up name */ ++#define APFS_INCOMPAT_SECONDARY_FSROOT 0x00000100LL /* Made-up name */ ++ ++#define APFS_SUPPORTED_INCOMPAT_MASK (APFS_INCOMPAT_CASE_INSENSITIVE \ ++ | APFS_INCOMPAT_DATALESS_SNAPS \ ++ | APFS_INCOMPAT_ENC_ROLLED \ ++ | APFS_INCOMPAT_NORMALIZATION_INSENSITIVE \ ++ | APFS_INCOMPAT_INCOMPLETE_RESTORE \ ++ | APFS_INCOMPAT_SEALED_VOLUME \ ++ | APFS_INCOMPAT_PFK \ ++ | APFS_INCOMPAT_EXTENT_PREALLOC_FLAG \ ++ | APFS_INCOMPAT_SECONDARY_FSROOT) ++ ++#define APFS_MODIFIED_NAMELEN 32 ++ ++/* ++ * Structure containing information about a program that modified the volume ++ */ ++struct apfs_modified_by { ++ u8 id[APFS_MODIFIED_NAMELEN]; ++ __le64 timestamp; ++ __le64 last_xid; ++} __packed; ++ ++/* Version constants for wrapped meta crypto state */ ++#define APFS_WMCS_MAJOR_VERSION 5 ++#define APFS_WMCS_MINOR_VERSION 0 ++ ++/* Protection classes */ ++#define APFS_PROTECTION_CLASS_DIR_NONE 0 /* Inherits the directory's default */ ++#define APFS_PROTECTION_CLASS_A 1 ++#define APFS_PROTECTION_CLASS_B 2 ++#define APFS_PROTECTION_CLASS_C 3 ++#define APFS_PROTECTION_CLASS_D 4 /* No protection */ ++#define APFS_PROTECTION_CLASS_F 6 /* No protection, nonpersistent key */ ++ ++/* Encryption identifiers */ ++#define APFS_CRYPTO_SW_ID 4 ++#define APFS_CRYPTO_RESERVED_5 5 ++#define APFS_UNASSIGNED_CRYPTO_ID (~0ULL) ++ ++/* Doc id index flags. I'm making up the names for now. */ ++#define APFS_DOC_ID_HAS_PREV_TREE 0x00000001 ++#define APFS_DOC_ID_UNKNOWN_02 0x00000002 ++#define APFS_DOC_ID_UNKNOWN_04 0x00000004 ++#define APFS_DOC_ID_UNKNOWN_08 0x00000008 ++#define APFS_DOC_ID_UNKNOWN_10 0x00000010 ++#define APFS_DOC_ID_VALID_FLAGS (APFS_DOC_ID_HAS_PREV_TREE \ ++ | APFS_DOC_ID_UNKNOWN_02 \ ++ | APFS_DOC_ID_UNKNOWN_04 \ ++ | APFS_DOC_ID_UNKNOWN_08 \ ++ | APFS_DOC_ID_UNKNOWN_10) ++ ++/* ++ * Structure used to store the encryption state ++ */ ++struct apfs_wrapped_meta_crypto_state { ++ __le16 major_version; ++ __le16 minor_version; ++ __le32 cpflags; ++ __le32 persistent_class; ++ __le32 key_os_version; ++ __le16 key_revision; ++ __le16 unused; ++} __packed; ++ ++/* ++ * On-disk representation of a volume superblock ++ */ ++struct apfs_superblock { ++/*00*/ struct apfs_obj_phys apfs_o; ++ ++/*20*/ __le32 apfs_magic; ++ __le32 apfs_fs_index; ++ ++/*28*/ __le64 apfs_features; ++ __le64 apfs_readonly_compatible_features; ++ __le64 apfs_incompatible_features; ++ ++/*40*/ __le64 apfs_unmount_time; ++ ++ __le64 apfs_fs_reserve_block_count; ++ __le64 apfs_fs_quota_block_count; ++ __le64 apfs_fs_alloc_count; ++ ++/*60*/ struct apfs_wrapped_meta_crypto_state apfs_meta_crypto; ++ ++/*74*/ __le32 apfs_root_tree_type; ++ __le32 apfs_extentref_tree_type; ++ __le32 apfs_snap_meta_tree_type; ++ ++/*80*/ __le64 apfs_omap_oid; ++ __le64 apfs_root_tree_oid; ++ __le64 apfs_extentref_tree_oid; ++ __le64 apfs_snap_meta_tree_oid; ++ ++/*A0*/ __le64 apfs_revert_to_xid; ++ __le64 apfs_revert_to_sblock_oid; ++ ++/*B0*/ __le64 apfs_next_obj_id; ++ ++/*B8*/ __le64 apfs_num_files; ++ __le64 apfs_num_directories; ++ __le64 apfs_num_symlinks; ++ __le64 apfs_num_other_fsobjects; ++ __le64 apfs_num_snapshots; ++ ++/*E0*/ __le64 apfs_total_blocks_alloced; ++ __le64 apfs_total_blocks_freed; ++ ++/*F0*/ char apfs_vol_uuid[UUID_SIZE]; ++/*100*/ __le64 apfs_last_mod_time; ++ ++ __le64 apfs_fs_flags; ++ ++/*110*/ struct apfs_modified_by apfs_formatted_by; ++/*140*/ struct apfs_modified_by apfs_modified_by[APFS_MAX_HIST]; ++ ++/*2C0*/ u8 apfs_volname[APFS_VOLNAME_LEN]; ++/*3C0*/ __le32 apfs_next_doc_id; ++ ++ __le16 apfs_role; ++ __le16 reserved; ++ ++/*3C8*/ __le64 apfs_root_to_xid; ++ __le64 apfs_er_state_oid; ++ ++ __le64 apfs_cloneinfo_id_epoch; ++ __le64 apfs_cloneinfo_xid; ++ ++ __le64 apfs_snap_meta_ext_oid; ++ ++/*3F0*/ char apfs_volume_group_id[UUID_SIZE]; ++ ++/*400*/ __le64 apfs_integrity_meta_oid; ++ ++ __le64 apfs_fext_tree_oid; ++/*410*/ __le32 apfs_fext_tree_type; ++ ++ __le32 reserved_type; ++ __le64 reserved_oid; ++ ++/*420*/ __le64 apfs_doc_id_index_xid; ++ __le32 apfs_doc_id_index_flags; ++ __le32 apfs_doc_id_tree_type; ++/*430*/ __le64 apfs_doc_id_tree_oid; /* Made-up name */ ++ __le64 apfs_prev_doc_id_tree_oid; ++ __le64 apfs_doc_id_fixup_cursor; ++ __le64 apfs_sec_root_tree_oid; ++/*450*/ __le32 apfs_sec_root_tree_type; ++} __packed; ++ ++/* Extended attributes constants */ ++#define APFS_XATTR_MAX_EMBEDDED_SIZE 3804 ++ ++/* Extended attributes names */ ++#define APFS_XATTR_NAME_SYMLINK "com.apple.fs.symlink" ++#define APFS_XATTR_NAME_COMPRESSED "com.apple.decmpfs" ++#define APFS_XATTR_NAME_RSRC_FORK "com.apple.ResourceFork" ++#define APFS_XATTR_NAME_SECURITY "com.apple.system.Security" ++#define APFS_XATTR_NAME_FINDER_INFO "com.apple.FinderInfo" ++ ++/* Extended attributes flags */ ++enum { ++ APFS_XATTR_DATA_STREAM = 0x00000001, ++ APFS_XATTR_DATA_EMBEDDED = 0x00000002, ++ APFS_XATTR_FILE_SYSTEM_OWNED = 0x00000004, ++ APFS_XATTR_RESERVED_8 = 0x00000008, ++ APFS_XATTR_UNKNOWN_10 = 0x00000010, ++}; ++ ++#define APFS_XATTR_VALID_FLAGS 0x0000001f ++ ++/* ++ * Structure of the value of an extended attributes record ++ */ ++struct apfs_xattr_val { ++ __le16 flags; ++ __le16 xdata_len; ++ u8 xdata[]; ++} __packed; ++ ++/* ++ * Structure used to store the data of an extended attributes record ++ */ ++struct apfs_xattr_dstream { ++ __le64 xattr_obj_id; ++ struct apfs_dstream dstream; ++} __packed; ++ ++/* ++ * Integrity metadata for a sealed volume ++ */ ++struct apfs_integrity_meta_phys { ++ struct apfs_obj_phys im_o; ++ ++ __le32 im_version; ++ __le32 im_flags; ++ __le32 im_hash_type; ++ __le32 im_root_hash_offset; ++ __le64 im_broken_xid; ++ __le64 im_reserved[9]; ++} __packed; ++ ++/* ++ * Version numbers for the integrity metadata structure ++ */ ++enum { ++ APFS_INTEGRITY_META_VERSION_INVALID = 0, ++ APFS_INTEGRITY_META_VERSION_1 = 1, ++ APFS_INTEGRITY_META_VERSION_2 = 2, ++ APFS_INTEGRITY_META_VERSION_HIGHEST = APFS_INTEGRITY_META_VERSION_2 ++}; ++ ++/* Flags used by integrity metadata */ ++#define APFS_SEAL_BROKEN (1U << 0) ++ ++/* ++ * Constants used to identify hash algorithms ++ */ ++enum { ++ APFS_HASH_INVALID = 0, ++ APFS_HASH_SHA256 = 0x1, ++ APFS_HASH_SHA512_256 = 0x2, ++ APFS_HASH_SHA384 = 0x3, ++ APFS_HASH_SHA512 = 0x4, ++ ++ APFS_HASH_MIN = APFS_HASH_SHA256, ++ APFS_HASH_MAX = APFS_HASH_SHA512, ++ APFS_HASH_DEFAULT = APFS_HASH_SHA256, ++}; ++ ++#define APFS_HASH_CCSHA256_SIZE 32 ++#define APFS_HASH_CCSHA512_256_SIZE 32 ++#define APFS_HASH_CCSHA384_SIZE 48 ++#define APFS_HASH_CCSHA512_SIZE 64 ++ ++#define APFS_HASH_MAX_SIZE 64 ++ ++/* ++ * Structure of a key in a fext tree ++ */ ++struct apfs_fext_tree_key { ++ __le64 private_id; ++ __le64 logical_addr; ++} __packed; ++ ++/* ++ * Structure of a value in a fext tree ++ */ ++struct apfs_fext_tree_val { ++ __le64 len_and_flags; ++ __le64 phys_block_num; ++} __packed; ++ ++/* ++ * Structure of the key for a file info record ++ */ ++struct apfs_file_info_key { ++ struct apfs_key_header hdr; ++ __le64 info_and_lba; ++} __packed; ++ ++#define APFS_FILE_INFO_LBA_MASK 0x00ffffffffffffffULL ++#define APFS_FILE_INFO_TYPE_MASK 0xff00000000000000ULL ++#define APFS_FILE_INFO_TYPE_SHIFT 56 ++ ++/* ++ * A hash of file data ++ */ ++struct apfs_file_data_hash_val { ++ __le16 hashed_len; ++ u8 hash_size; ++ u8 hash[]; ++} __packed; ++ ++#define APFS_FILE_INFO_DATA_HASH 1 ++ ++/* ++ * Structure of the value for a file info record ++ */ ++struct apfs_file_info_val { ++ union { ++ struct apfs_file_data_hash_val dhash; ++ }; ++} __packed; ++ ++#define APFS_BTREE_NODE_HASH_SIZE_MAX 64 ++ ++/* ++ * Structure of the value of an index record for a hashed catalog tree ++ */ ++struct apfs_btn_index_node_val { ++ __le64 binv_child_oid; ++ /* ++ * The reference seems to be wrong about the hash size, at least for ++ * SHA-256. TODO: check what happens with other hash functions. ++ */ ++ u8 binv_child_hash[APFS_HASH_CCSHA256_SIZE]; ++} __packed; ++ ++/* ++ * Compressed file header ++ */ ++struct apfs_compress_hdr { ++ __le32 signature; ++ __le32 algo; ++ __le64 size; ++} __packed; ++ ++#define APFS_COMPRESS_ZLIB_ATTR 3 ++#define APFS_COMPRESS_ZLIB_RSRC 4 ++#define APFS_COMPRESS_LZVN_ATTR 7 ++#define APFS_COMPRESS_LZVN_RSRC 8 ++#define APFS_COMPRESS_PLAIN_ATTR 9 ++#define APFS_COMPRESS_PLAIN_RSRC 10 ++#define APFS_COMPRESS_LZFSE_ATTR 11 ++#define APFS_COMPRESS_LZFSE_RSRC 12 ++#define APFS_COMPRESS_LZBITMAP_ATTR 13 ++#define APFS_COMPRESS_LZBITMAP_RSRC 14 ++ ++struct apfs_compress_rsrc_hdr { ++ __be32 data_offs; ++ __be32 mgmt_offs; ++ __be32 data_size; ++ __be32 mgmt_size; ++} __packed; ++ ++#define APFS_COMPRESS_BLOCK 0x10000 ++ ++struct apfs_compress_rsrc_data { ++ __le32 unknown; ++ __le32 num; ++ struct apfs_compress_rsrc_block { ++ __le32 offs; ++ __le32 size; ++ } __packed block[]; ++} __packed; ++ ++#define APFS_FUSION_TIER2_DEVICE_BYTE_ADDR 0x4000000000000000ULL ++ ++/* ++ * TODO: this is a placeholder, create some snapshots with the official ++ * implementation to find the actual limit. ++ */ ++#define APFS_SNAP_MAX_NAMELEN 255 ++ ++/* ++ * Structure of the value of a snapshot metadata record ++ */ ++struct apfs_snap_metadata_val { ++ __le64 extentref_tree_oid; ++ __le64 sblock_oid; ++ __le64 create_time; ++ __le64 change_time; ++ __le64 inum; ++ __le32 extentref_tree_type; ++ __le32 flags; ++ __le16 name_len; ++ u8 name[]; ++} __packed; ++ ++/* Snapshot metadata record flags */ ++enum { ++ APFS_SNAP_META_PENDING_DATALESS = 0x00000001, ++ APFS_SNAP_MERGE_IN_PROGRESS = 0x00000002, ++}; ++ ++/* ++ * Structure of the value of a snapshot name record ++ */ ++struct apfs_snap_name_val { ++ __le64 snap_xid; ++} __packed; ++ ++/* ++ * Structure of the extended snapshot metadata ++ */ ++struct apfs_snap_meta_ext { ++ struct apfs_obj_phys sme_o; ++ ++ __le32 sme_version; ++ __le32 sme_flags; ++ __le64 sme_snap_xid; ++ char sme_uuid[UUID_SIZE]; ++ __le64 sme_token; ++} __packed; ++ ++#define APFS_OBJECT_TYPE_KEYBAG 0x6b657973 /* Spells 'syek' */ ++ ++#define APFS_VOL_KEYBAG_ENTRY_MAX_SIZE 512 ++#define APFS_FV_PERSONAL_RECOVERY_KEY_UUID "EBC6C064-0000-11AA-AA11-00306543ECAC" ++ ++/* Keybag entry types */ ++enum { ++ KB_TAG_UNKNOWN = 0, ++ KB_TAG_RESERVED_1 = 1, ++ ++ KB_TAG_VOLUME_KEY = 2, ++ KB_TAG_VOLUME_UNLOCK_RECORDS = 3, ++ KB_TAG_VOLUME_PASSPHRASE_HINT = 4, ++ ++ KB_TAG_WRAPPING_M_KEY = 5, ++ KB_TAG_VOLUME_M_KEY = 6, ++ ++ KB_TAG_RESERVED_F8 = 0xF8 ++}; ++ ++/* ++ * Structure of a single entry in the keybag ++ */ ++struct apfs_keybag_entry { ++ char ke_uuid[UUID_SIZE]; ++ __le16 ke_tag; ++ __le16 ke_keylen; ++ __le32 padding; ++ u8 ke_keydata[]; ++} __packed; ++ ++#define APFS_KEYBAG_VERSION 2 ++ ++/* ++ * Structure of the locker in the keybag ++ */ ++struct apfs_kb_locker { ++ __le16 kl_version; ++ __le16 kl_nkeys; ++ __le32 kl_nbytes; ++ __le64 padding; ++ struct apfs_keybag_entry kl_entries[]; ++} __packed; ++ ++#endif /* _APFS_RAW_H */ +diff --git a/fs/apfs/btree.c b/fs/apfs/btree.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/btree.c +@@ -0,0 +1,1174 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++struct apfs_node *apfs_query_root(const struct apfs_query *query) ++{ ++ while (query->parent) ++ query = query->parent; ++ ASSERT(apfs_node_is_root(query->node)); ++ return query->node; ++} ++ ++static u64 apfs_catalog_base_oid(struct apfs_query *query) ++{ ++ struct apfs_query *root_query = NULL; ++ ++ root_query = query; ++ while (root_query->parent) ++ root_query = root_query->parent; ++ ++ return root_query->node->object.oid; ++} ++ ++/** ++ * apfs_child_from_query - Read the child id found by a successful nonleaf query ++ * @query: the query that found the record ++ * @child: Return parameter. The child id found. ++ * ++ * Reads the child id in the nonleaf node record into @child and performs a ++ * basic sanity check as a protection against crafted filesystems. Returns 0 ++ * on success or -EFSCORRUPTED otherwise. ++ */ ++static int apfs_child_from_query(struct apfs_query *query, u64 *child) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ ++ if (query->flags & APFS_QUERY_CAT && apfs_is_sealed(sb)) { ++ struct apfs_btn_index_node_val *index_val = NULL; ++ ++ if (query->len != sizeof(*index_val)) { ++ apfs_err(sb, "bad sealed index value length (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ index_val = (struct apfs_btn_index_node_val *)(raw + query->off); ++ *child = le64_to_cpu(index_val->binv_child_oid) + apfs_catalog_base_oid(query); ++ } else { ++ if (query->len != 8) { /* The value on a nonleaf node is the child id */ ++ apfs_err(sb, "bad index value length (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ *child = le64_to_cpup((__le64 *)(raw + query->off)); ++ } ++ return 0; ++} ++ ++/** ++ * apfs_omap_cache_lookup - Look for an oid in an omap's cache ++ * @omap: the object map ++ * @oid: object id to look up ++ * @bno: on return, the block number for the oid ++ * ++ * Returns 0 on success, or -1 if this mapping is not cached. ++ */ ++static int apfs_omap_cache_lookup(struct apfs_omap *omap, u64 oid, u64 *bno) ++{ ++ struct apfs_omap_cache *cache = &omap->omap_cache; ++ struct apfs_omap_rec *record = NULL; ++ int slot; ++ int ret = -1; ++ ++ if (cache->disabled) ++ return -1; ++ ++ /* Uninitialized cache records use OID 0, so check this just in case */ ++ if (!oid) ++ return -1; ++ ++ slot = oid & APFS_OMAP_CACHE_SLOT_MASK; ++ record = &cache->recs[slot]; ++ ++ spin_lock(&cache->lock); ++ if (record->oid == oid) { ++ *bno = record->bno; ++ ret = 0; ++ } ++ spin_unlock(&cache->lock); ++ ++ return ret; ++} ++ ++/** ++ * apfs_omap_cache_save - Save a record in an omap's cache ++ * @omap: the object map ++ * @oid: object id of the record ++ * @bno: block number for the oid ++ */ ++static void apfs_omap_cache_save(struct apfs_omap *omap, u64 oid, u64 bno) ++{ ++ struct apfs_omap_cache *cache = &omap->omap_cache; ++ struct apfs_omap_rec *record = NULL; ++ int slot; ++ ++ if (cache->disabled) ++ return; ++ ++ slot = oid & APFS_OMAP_CACHE_SLOT_MASK; ++ record = &cache->recs[slot]; ++ ++ spin_lock(&cache->lock); ++ record->oid = oid; ++ record->bno = bno; ++ spin_unlock(&cache->lock); ++} ++ ++/** ++ * apfs_omap_cache_delete - Try to delete a record from an omap's cache ++ * @omap: the object map ++ * @oid: object id of the record ++ */ ++static void apfs_omap_cache_delete(struct apfs_omap *omap, u64 oid) ++{ ++ struct apfs_omap_cache *cache = &omap->omap_cache; ++ struct apfs_omap_rec *record = NULL; ++ int slot; ++ ++ if (cache->disabled) ++ return; ++ ++ slot = oid & APFS_OMAP_CACHE_SLOT_MASK; ++ record = &cache->recs[slot]; ++ ++ spin_lock(&cache->lock); ++ if (record->oid == oid) { ++ record->oid = 0; ++ record->bno = 0; ++ } ++ spin_unlock(&cache->lock); ++} ++ ++/** ++ * apfs_mounted_xid - Returns the mounted xid for this superblock ++ * @sb: superblock structure ++ * ++ * This function is needed instead of APFS_NXI(@sb)->nx_xid in situations where ++ * we might be working with a snapshot. Snapshots are read-only and should ++ * mostly ignore xids, so this only appears to matter for omap lookups. ++ */ ++static inline u64 apfs_mounted_xid(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ ++ return sbi->s_snap_xid ? sbi->s_snap_xid : nxi->nx_xid; ++} ++ ++/** ++ * apfs_xid_in_snapshot - Check if an xid is part of a snapshot ++ * @omap: the object map ++ * @xid: the xid to check ++ */ ++static inline bool apfs_xid_in_snapshot(struct apfs_omap *omap, u64 xid) ++{ ++ return xid <= omap->omap_latest_snap; ++} ++ ++/** ++ * apfs_omap_lookup_block_with_xid - Find bno of a virtual object from oid/xid ++ * @sb: filesystem superblock ++ * @omap: object map to be searched ++ * @id: id of the node ++ * @xid: transaction id ++ * @block: on return, the found block number ++ * @write: get write access to the object? ++ * ++ * Searches @omap for the most recent matching object with a transaction id ++ * below @xid. Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_omap_lookup_block_with_xid(struct super_block *sb, struct apfs_omap *omap, u64 id, u64 xid, u64 *block, bool write) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_query *query; ++ struct apfs_omap_map map = {0}; ++ int ret = 0; ++ ++ if (!write) { ++ if (!apfs_omap_cache_lookup(omap, id, block)) ++ return 0; ++ } ++ ++ query = apfs_alloc_query(omap->omap_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_omap_key(id, xid, &query->key); ++ query->flags |= APFS_QUERY_OMAP; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ if (ret != -ENODATA) ++ apfs_err(sb, "query failed for oid 0x%llx, xid 0x%llx", id, xid); ++ goto fail; ++ } ++ ++ ret = apfs_omap_map_from_query(query, &map); ++ if (ret) { ++ apfs_alert(sb, "bad object map leaf block: 0x%llx", ++ query->node->object.block_nr); ++ goto fail; ++ } ++ *block = map.bno; ++ ++ if (write) { ++ struct apfs_omap_key key; ++ struct apfs_omap_val val; ++ struct buffer_head *new_bh; ++ bool preserve; ++ ++ preserve = apfs_xid_in_snapshot(omap, map.xid); ++ ++ new_bh = apfs_read_object_block(sb, *block, write, preserve); ++ if (IS_ERR(new_bh)) { ++ apfs_err(sb, "CoW failed for oid 0x%llx, xid 0x%llx", id, xid); ++ ret = PTR_ERR(new_bh); ++ goto fail; ++ } ++ ++ key.ok_oid = cpu_to_le64(id); ++ key.ok_xid = cpu_to_le64(nxi->nx_xid); ++ val.ov_flags = cpu_to_le32(map.flags); ++ val.ov_size = cpu_to_le32(sb->s_blocksize); ++ val.ov_paddr = cpu_to_le64(new_bh->b_blocknr); ++ ++ if (preserve) ++ ret = apfs_btree_insert(query, &key, sizeof(key), &val, sizeof(val)); ++ else ++ ret = apfs_btree_replace(query, &key, sizeof(key), &val, sizeof(val)); ++ if (ret) ++ apfs_err(sb, "CoW omap update failed (oid 0x%llx, xid 0x%llx)", id, xid); ++ ++ *block = new_bh->b_blocknr; ++ brelse(new_bh); ++ } ++ ++ apfs_omap_cache_save(omap, id, *block); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_omap_lookup_block - Find the block number of a b-tree node from its id ++ * @sb: filesystem superblock ++ * @omap: object map to be searched ++ * @id: id of the node ++ * @block: on return, the found block number ++ * @write: get write access to the object? ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_omap_lookup_block(struct super_block *sb, struct apfs_omap *omap, u64 id, u64 *block, bool write) ++{ ++ return apfs_omap_lookup_block_with_xid(sb, omap, id, apfs_mounted_xid(sb), block, write); ++} ++ ++/** ++ * apfs_omap_lookup_newest_block - Find newest bno for a virtual object's oid ++ * @sb: filesystem superblock ++ * @omap: object map to be searched ++ * @id: id of the object ++ * @block: on return, the found block number ++ * @write: get write access to the object? ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_omap_lookup_newest_block(struct super_block *sb, struct apfs_omap *omap, u64 id, u64 *block, bool write) ++{ ++ return apfs_omap_lookup_block_with_xid(sb, omap, id, -1, block, write); ++} ++ ++/** ++ * apfs_create_omap_rec - Create a record in the volume's omap tree ++ * @sb: filesystem superblock ++ * @oid: object id ++ * @bno: block number ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_create_omap_rec(struct super_block *sb, u64 oid, u64 bno) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_omap *omap = sbi->s_omap; ++ struct apfs_query *query; ++ struct apfs_omap_key raw_key; ++ struct apfs_omap_val raw_val; ++ int ret; ++ ++ query = apfs_alloc_query(omap->omap_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_omap_key(oid, nxi->nx_xid, &query->key); ++ query->flags |= APFS_QUERY_OMAP; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for oid 0x%llx, bno 0x%llx", oid, bno); ++ goto fail; ++ } ++ ++ raw_key.ok_oid = cpu_to_le64(oid); ++ raw_key.ok_xid = cpu_to_le64(nxi->nx_xid); ++ raw_val.ov_flags = 0; ++ raw_val.ov_size = cpu_to_le32(sb->s_blocksize); ++ raw_val.ov_paddr = cpu_to_le64(bno); ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), ++ &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for oid 0x%llx, bno 0x%llx", oid, bno); ++ goto fail; ++ } ++ ++ apfs_omap_cache_save(omap, oid, bno); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_delete_omap_rec - Delete an existing record from the volume's omap tree ++ * @sb: filesystem superblock ++ * @oid: object id for the record ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_delete_omap_rec(struct super_block *sb, u64 oid) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_omap *omap = sbi->s_omap; ++ struct apfs_query *query; ++ int ret; ++ ++ query = apfs_alloc_query(omap->omap_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_omap_key(oid, nxi->nx_xid, &query->key); ++ query->flags |= APFS_QUERY_OMAP; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret == -ENODATA) { ++ apfs_err(sb, "nonexistent record (oid 0x%llx)", oid); ++ ret = -EFSCORRUPTED; ++ goto fail; ++ } ++ if (ret) { ++ apfs_err(sb, "query failed (oid 0x%llx)", oid); ++ goto fail; ++ } ++ ret = apfs_btree_remove(query); ++ if (ret) { ++ apfs_err(sb, "removal failed (oid 0x%llx)", oid); ++ goto fail; ++ } ++ apfs_omap_cache_delete(omap, oid); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_alloc_query - Allocates a query structure ++ * @node: node to be searched ++ * @parent: query for the parent node ++ * ++ * Callers other than apfs_btree_query() should set @parent to NULL, and @node ++ * to the root of the b-tree. They should also initialize most of the query ++ * fields themselves; when @parent is not NULL the query will inherit them. ++ * ++ * Returns the allocated query, or NULL in case of failure. ++ */ ++struct apfs_query *apfs_alloc_query(struct apfs_node *node, ++ struct apfs_query *parent) ++{ ++ struct apfs_query *query; ++ ++ query = kzalloc(sizeof(*query), GFP_KERNEL); ++ if (!query) ++ return NULL; ++ ++ /* To be released by free_query. */ ++ query->node = node; ++ ++ if (parent) { ++ query->key = parent->key; ++ query->flags = parent->flags & ~(APFS_QUERY_DONE | APFS_QUERY_NEXT); ++ query->parent = parent; ++ query->depth = parent->depth + 1; ++ } ++ ++ /* ++ * We start the search with the last record and go backwards, but ++ * some queries later use the PREV flag later to list them in order. ++ */ ++ if (query->flags & APFS_QUERY_PREV) ++ query->index = -1; ++ else ++ query->index = node->records; ++ ++ return query; ++} ++ ++/** ++ * apfs_free_query - Free a query structure ++ * @query: query to free ++ * ++ * Also frees the ancestor queries, if they are kept. ++ */ ++void apfs_free_query(struct apfs_query *query) ++{ ++ while (query) { ++ struct apfs_query *parent = query->parent; ++ ++ /* The caller decides whether to free the root node */ ++ if (query->depth != 0) ++ apfs_node_free(query->node); ++ kfree(query); ++ query = parent; ++ } ++} ++ ++/** ++ * apfs_query_set_before_first - Set the query to point before the first record ++ * @sb: superblock structure ++ * @query: the query to set ++ * ++ * Queries set in this way are used to insert a record before the first one. ++ * Only the leaf gets set to the -1 entry; queries for other levels must be set ++ * to 0, since the first entry in each index node will need to be modified. ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_query_set_before_first(struct super_block *sb, struct apfs_query **query) ++{ ++ struct apfs_node *node = NULL; ++ struct apfs_query *parent = NULL; ++ u64 child_id; ++ u32 storage = apfs_query_storage(*query); ++ int err; ++ ++ while ((*query)->depth < 12) { ++ if (apfs_node_is_leaf((*query)->node)) { ++ (*query)->index = -1; ++ return 0; ++ } ++ apfs_node_query_first(*query); ++ ++ err = apfs_child_from_query(*query, &child_id); ++ if (err) { ++ apfs_alert(sb, "bad index block: 0x%llx", ++ (*query)->node->object.block_nr); ++ return err; ++ } ++ ++ /* Now go a level deeper */ ++ node = apfs_read_node(sb, child_id, storage, false /* write */); ++ if (IS_ERR(node)) { ++ apfs_err(sb, "failed to read child 0x%llx of node 0x%llx", child_id, (*query)->node->object.oid); ++ return PTR_ERR(node); ++ } ++ ++ parent = *query; ++ *query = apfs_alloc_query(node, parent); ++ if (!*query) { ++ apfs_node_free(node); ++ *query = parent; ++ return -ENOMEM; ++ } ++ node = NULL; ++ } ++ ++ apfs_err(sb, "btree is too high"); ++ return -EFSCORRUPTED; ++} ++ ++/** ++ * apfs_btree_query - Execute a query on a b-tree ++ * @sb: filesystem superblock ++ * @query: the query to execute ++ * ++ * Searches the b-tree starting at @query->index in @query->node, looking for ++ * the record corresponding to @query->key. ++ * ++ * Returns 0 in case of success and sets the @query->len, @query->off and ++ * @query->index fields to the results of the query. @query->node will now ++ * point to the leaf node holding the record. ++ * ++ * In case of failure returns an appropriate error code. ++ */ ++int apfs_btree_query(struct super_block *sb, struct apfs_query **query) ++{ ++ struct apfs_node *node; ++ struct apfs_query *parent; ++ u64 child_id; ++ u32 storage = apfs_query_storage(*query); ++ int err; ++ ++next_node: ++ if ((*query)->depth >= 12) { ++ /* ++ * We need a maximum depth for the tree so we can't loop ++ * forever if the filesystem is damaged. 12 should be more ++ * than enough to map every block. ++ */ ++ apfs_err(sb, "btree is too high"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ err = apfs_node_query(sb, *query); ++ if (err == -ENODATA && !(*query)->parent && (*query)->index == -1) { ++ /* ++ * We may be trying to insert a record before all others: don't ++ * let the query give up at the root node. ++ */ ++ err = apfs_query_set_before_first(sb, query); ++ if (err) { ++ apfs_err(sb, "failed to set before the first record"); ++ goto fail; ++ } ++ err = -ENODATA; ++ goto fail; ++ } else if (err == -EAGAIN) { ++ if (!(*query)->parent) { ++ /* We are at the root of the tree */ ++ err = -ENODATA; ++ goto fail; ++ } ++ ++ /* Move back up one level and continue the query */ ++ parent = (*query)->parent; ++ (*query)->parent = NULL; /* Don't free the parent */ ++ apfs_free_query(*query); ++ *query = parent; ++ goto next_node; ++ } else if (err) { ++ goto fail; ++ } ++ if (apfs_node_is_leaf((*query)->node)) /* All done */ ++ return 0; ++ ++ err = apfs_child_from_query(*query, &child_id); ++ if (err) { ++ apfs_alert(sb, "bad index block: 0x%llx", ++ (*query)->node->object.block_nr); ++ goto fail; ++ } ++ ++ /* Now go a level deeper and search the child */ ++ node = apfs_read_node(sb, child_id, storage, false /* write */); ++ if (IS_ERR(node)) { ++ apfs_err(sb, "failed to read node 0x%llx", child_id); ++ err = PTR_ERR(node); ++ goto fail; ++ } ++ ++ if (node->object.oid != child_id) ++ apfs_debug(sb, "corrupt b-tree"); ++ ++ /* ++ * Remember the parent node and index in case the search needs ++ * to be continued later. ++ */ ++ parent = *query; ++ *query = apfs_alloc_query(node, parent); ++ if (!*query) { ++ apfs_node_free(node); ++ *query = parent; ++ err = -ENOMEM; ++ goto fail; ++ } ++ node = NULL; ++ goto next_node; ++ ++fail: ++ /* Don't leave stale record info here or some callers will use it */ ++ (*query)->key_len = (*query)->len = 0; ++ return err; ++} ++ ++static int __apfs_btree_replace(struct apfs_query *query, void *key, int key_len, void *val, int val_len); ++ ++/** ++ * apfs_query_join_transaction - Add the found node to the current transaction ++ * @query: query that found the node ++ */ ++int apfs_query_join_transaction(struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ u64 oid = node->object.oid; ++ u32 storage = apfs_query_storage(query); ++ struct apfs_obj_phys *raw = NULL; ++ ++ /* ++ * Ephemeral objects are checkpoint data, and all of their xids get ++ * updated on commit. There is no real need to do it here as well, but ++ * it's better for consistency with the other object types. ++ */ ++ if (storage == APFS_OBJ_EPHEMERAL) { ++ ASSERT(node->object.ephemeral); ++ raw = (void *)node->object.data; ++ raw->o_xid = cpu_to_le64(APFS_NXI(sb)->nx_xid); ++ return 0; ++ } ++ ++ if (buffer_trans(node->object.o_bh)) /* Already in the transaction */ ++ return 0; ++ /* Root nodes should join the transaction before the query is created */ ++ ASSERT(!apfs_node_is_root(node)); ++ ++ node = apfs_read_node(sb, oid, storage, true /* write */); ++ if (IS_ERR(node)) { ++ apfs_err(sb, "Cow failed for node 0x%llx", oid); ++ return PTR_ERR(node); ++ } ++ apfs_node_free(query->node); ++ query->node = node; ++ ++ if (storage == APFS_OBJ_PHYSICAL && query->parent) { ++ __le64 bno = cpu_to_le64(node->object.block_nr); ++ ++ /* The parent node needs to report the new location */ ++ return __apfs_btree_replace(query->parent, NULL /* key */, 0 /* key_len */, &bno, sizeof(bno)); ++ } ++ return 0; ++} ++ ++/** ++ * apfs_btree_change_rec_count - Update the b-tree info before a record change ++ * @query: query used to insert/remove/replace the leaf record ++ * @change: change in the record count ++ * @key_len: length of the new leaf record key (0 if removed or unchanged) ++ * @val_len: length of the new leaf record value (0 if removed or unchanged) ++ * ++ * Don't call this function if @query->parent was reset to NULL, or if the same ++ * is true of any of its ancestor queries. ++ */ ++static void apfs_btree_change_rec_count(struct apfs_query *query, int change, ++ int key_len, int val_len) ++{ ++ struct super_block *sb; ++ struct apfs_node *root; ++ struct apfs_btree_node_phys *root_raw; ++ struct apfs_btree_info *info; ++ ++ if (change == -1) ++ ASSERT(!key_len && !val_len); ++ ASSERT(apfs_node_is_leaf(query->node)); ++ ++ root = apfs_query_root(query); ++ ASSERT(apfs_node_is_root(root)); ++ ++ sb = root->object.sb; ++ root_raw = (void *)root->object.data; ++ info = (void *)root_raw + sb->s_blocksize - sizeof(*info); ++ ++ apfs_assert_in_transaction(sb, &root_raw->btn_o); ++ if (key_len > le32_to_cpu(info->bt_longest_key)) ++ info->bt_longest_key = cpu_to_le32(key_len); ++ if (val_len > le32_to_cpu(info->bt_longest_val)) ++ info->bt_longest_val = cpu_to_le32(val_len); ++ le64_add_cpu(&info->bt_key_count, change); ++} ++ ++/** ++ * apfs_btree_change_node_count - Change the node count for a b-tree ++ * @query: query used to remove/create the node ++ * @change: change in the node count ++ * ++ * Also changes the node count in the volume superblock. Don't call this ++ * function if @query->parent was reset to NULL, or if the same is true of ++ * any of its ancestor queries. ++ */ ++void apfs_btree_change_node_count(struct apfs_query *query, int change) ++{ ++ struct super_block *sb; ++ struct apfs_node *root; ++ struct apfs_btree_node_phys *root_raw; ++ struct apfs_btree_info *info; ++ ++ root = apfs_query_root(query); ++ ASSERT(apfs_node_is_root(root)); ++ ++ sb = root->object.sb; ++ root_raw = (void *)root->object.data; ++ info = (void *)root_raw + sb->s_blocksize - sizeof(*info); ++ ++ apfs_assert_in_transaction(sb, &root_raw->btn_o); ++ le64_add_cpu(&info->bt_node_count, change); ++} ++ ++/** ++ * apfs_query_refresh - Recreate a catalog query invalidated by node splits ++ * @old_query: query chain to refresh ++ * @root: root node of the query chain ++ * @nodata: is the query expected to find nothing? ++ * ++ * On success, @old_query is left pointing to the same leaf record, but with ++ * valid ancestor queries as well. Returns a negative error code in case of ++ * failure, or 0 on success. ++ */ ++static int apfs_query_refresh(struct apfs_query *old_query, struct apfs_node *root, bool nodata) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_query *new_query = NULL; ++ int err = 0; ++ ++ sb = root->object.sb; ++ ++ if (!apfs_node_is_leaf(old_query->node)) { ++ apfs_alert(sb, "attempting refresh of non-leaf query"); ++ return -EFSCORRUPTED; ++ } ++ if (apfs_node_is_root(old_query->node)) { ++ apfs_alert(sb, "attempting refresh of root query"); ++ return -EFSCORRUPTED; ++ } ++ ++ new_query = apfs_alloc_query(root, NULL /* parent */); ++ if (!new_query) ++ return -ENOMEM; ++ new_query->key = old_query->key; ++ new_query->flags = old_query->flags & ~(APFS_QUERY_DONE | APFS_QUERY_NEXT); ++ ++ err = apfs_btree_query(sb, &new_query); ++ if (!nodata && err == -ENODATA) { ++ apfs_err(sb, "record should exist"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ if (err && err != -ENODATA) { ++ apfs_err(sb, "failed to rerun"); ++ goto fail; ++ } ++ err = 0; ++ ++ /* Replace the parent of the original query with the new valid one */ ++ apfs_free_query(old_query->parent); ++ old_query->parent = new_query->parent; ++ new_query->parent = NULL; ++ ++ /* ++ * The records may have moved around so update this too. TODO: rework ++ * the query struct so this stuff is not needed. ++ */ ++ ASSERT(old_query->node->object.oid == new_query->node->object.oid); ++ old_query->index = new_query->index; ++ old_query->key_off = new_query->key_off; ++ old_query->key_len = new_query->key_len; ++ old_query->off = new_query->off; ++ old_query->len = new_query->len; ++ old_query->depth = new_query->depth; ++ ++fail: ++ apfs_free_query(new_query); ++ return err; ++} ++ ++/** ++ * __apfs_btree_insert - Insert a new record into a b-tree (at any level) ++ * @query: query run to search for the record ++ * @key: on-disk record key ++ * @key_len: length of @key ++ * @val: on-disk record value (NULL for ghost records) ++ * @val_len: length of @val (0 for ghost records) ++ * ++ * The new record is placed right after the one found by @query. On success, ++ * returns 0 and sets @query to the new record; returns a negative error code ++ * in case of failure, which may be -EAGAIN if a split happened and the caller ++ * must retry. ++ */ ++int __apfs_btree_insert(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw; ++ int needed_room; ++ int err; ++ ++ apfs_assert_query_is_valid(query); ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ ++ node = query->node; ++ node_raw = (void *)node->object.data; ++ apfs_assert_in_transaction(node->object.sb, &node_raw->btn_o); ++ ++ needed_room = key_len + val_len; ++ if (!apfs_node_has_room(node, needed_room, false /* replace */)) { ++ if (node->records == 1) { ++ /* The new record just won't fit in the node */ ++ err = apfs_create_single_rec_node(query, key, key_len, val, val_len); ++ if (err && err != -EAGAIN) ++ apfs_err(sb, "failed to create single-record node"); ++ return err; ++ } ++ err = apfs_node_split(query); ++ if (err && err != -EAGAIN) { ++ apfs_err(sb, "node split failed"); ++ return err; ++ } ++ return -EAGAIN; ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ if (query->parent && query->index == -1) { ++ /* We are about to insert a record before all others */ ++ err = __apfs_btree_replace(query->parent, key, key_len, NULL /* val */, 0 /* val_len */); ++ if (err) { ++ if (err != -EAGAIN) ++ apfs_err(sb, "parent update failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ err = apfs_node_insert(query, key, key_len, val, val_len); ++ if (err) { ++ apfs_err(sb, "node record insertion failed"); ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_btree_insert - Insert a new record into a b-tree leaf ++ * @query: query run to search for the record ++ * @key: on-disk record key ++ * @key_len: length of @key ++ * @val: on-disk record value (NULL for ghost records) ++ * @val_len: length of @val (0 for ghost records) ++ * ++ * The new record is placed right after the one found by @query. On success, ++ * returns 0 and sets @query to the new record; returns a negative error code ++ * in case of failure. ++ */ ++int apfs_btree_insert(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_node *root = NULL, *leaf = NULL; ++ int err; ++ ++ root = apfs_query_root(query); ++ ASSERT(apfs_node_is_root(root)); ++ leaf = query->node; ++ ASSERT(apfs_node_is_leaf(leaf)); ++ sb = root->object.sb; ++ ++ while (true) { ++ err = __apfs_btree_insert(query, key, key_len, val, val_len); ++ if (err != -EAGAIN) { ++ if (err) ++ return err; ++ break; ++ } ++ err = apfs_query_refresh(query, root, true /* nodata */); ++ if (err) { ++ apfs_err(sb, "query refresh failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ apfs_btree_change_rec_count(query, 1 /* change */, key_len, val_len); ++ return 0; ++} ++ ++/** ++ * __apfs_btree_remove - Remove a record from a b-tree (at any level) ++ * @query: exact query that found the record ++ * ++ * Returns 0 on success, or a negative error code in case of failure, which may ++ * be -EAGAIN if a split happened and the caller must retry. ++ */ ++static int __apfs_btree_remove(struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw; ++ int later_entries = node->records - query->index - 1; ++ int err; ++ ++ apfs_assert_query_is_valid(query); ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ ++ node = query->node; ++ node_raw = (void *)query->node->object.data; ++ apfs_assert_in_transaction(node->object.sb, &node_raw->btn_o); ++ ++ if (query->parent && node->records == 1) { ++ /* Just get rid of the node */ ++ err = __apfs_btree_remove(query->parent); ++ if (err == -EAGAIN) ++ return -EAGAIN; ++ if (err) { ++ apfs_err(sb, "parent index removal failed"); ++ return err; ++ } ++ apfs_btree_change_node_count(query, -1 /* change */); ++ err = apfs_delete_node(node, query->flags & APFS_QUERY_TREE_MASK); ++ if (err) { ++ apfs_err(sb, "node deletion failed"); ++ return err; ++ } ++ return 0; ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ /* The first key in a node must match the parent record's */ ++ if (query->parent && query->index == 0) { ++ int first_key_len, first_key_off; ++ void *key; ++ ++ first_key_len = apfs_node_locate_key(node, 1, &first_key_off); ++ if (!first_key_len) ++ return -EFSCORRUPTED; ++ key = (void *)node_raw + first_key_off; ++ ++ err = __apfs_btree_replace(query->parent, key, first_key_len, NULL /* val */, 0 /* val_len */); ++ if (err == -EAGAIN) ++ return -EAGAIN; ++ if (err) { ++ apfs_err(sb, "parent update failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ /* Remove the entry from the table of contents */ ++ if (apfs_node_has_fixed_kv_size(node)) { ++ struct apfs_kvoff *toc_entry; ++ ++ toc_entry = (struct apfs_kvoff *)node_raw->btn_data + ++ query->index; ++ memmove(toc_entry, toc_entry + 1, ++ later_entries * sizeof(*toc_entry)); ++ } else { ++ struct apfs_kvloc *toc_entry; ++ ++ toc_entry = (struct apfs_kvloc *)node_raw->btn_data + ++ query->index; ++ memmove(toc_entry, toc_entry + 1, ++ later_entries * sizeof(*toc_entry)); ++ } ++ ++ apfs_node_free_range(node, query->key_off, query->key_len); ++ apfs_node_free_range(node, query->off, query->len); ++ ++ --node->records; ++ if (node->records == 0) { ++ /* All descendants are gone, root is the whole tree */ ++ node_raw->btn_level = 0; ++ node->flags |= APFS_BTNODE_LEAF; ++ } ++ apfs_update_node(node); ++ ++ --query->index; ++ return 0; ++} ++ ++/** ++ * apfs_btree_remove - Remove a record from a b-tree leaf ++ * @query: exact query that found the record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_btree_remove(struct apfs_query *query) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_node *root = NULL, *leaf = NULL; ++ int err; ++ ++ root = apfs_query_root(query); ++ ASSERT(apfs_node_is_root(root)); ++ leaf = query->node; ++ ASSERT(apfs_node_is_leaf(leaf)); ++ sb = root->object.sb; ++ ++ while (true) { ++ err = __apfs_btree_remove(query); ++ if (err != -EAGAIN) { ++ if (err) ++ return err; ++ break; ++ } ++ err = apfs_query_refresh(query, root, false /* nodata */); ++ if (err) { ++ apfs_err(sb, "query refresh failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ apfs_btree_change_rec_count(query, -1 /* change */, 0 /* key_len */, 0 /* val_len */); ++ return 0; ++} ++ ++/** ++ * __apfs_btree_replace - Replace a record in a b-tree (at any level) ++ * @query: exact query that found the record ++ * @key: new on-disk record key (NULL if unchanged) ++ * @key_len: length of @key ++ * @val: new on-disk record value (NULL if unchanged) ++ * @val_len: length of @val ++ * ++ * It's important that the order of the records is not changed by the new @key. ++ * This function is not needed to replace an old value with a new one of the ++ * same length: it can just be overwritten in place. ++ * ++ * Returns 0 on success, and @query is left pointing to the same record; returns ++ * a negative error code in case of failure, which may be -EAGAIN if a split ++ * happened and the caller must retry. ++ */ ++static int __apfs_btree_replace(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw; ++ int needed_room; ++ int err; ++ ++ ASSERT(key || val); ++ apfs_assert_query_is_valid(query); ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ ++ node = query->node; ++ node_raw = (void *)node->object.data; ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++ needed_room = key_len + val_len; ++ /* We can reuse the space of the replaced key/value */ ++ if (key) ++ needed_room -= query->key_len; ++ if (val) ++ needed_room -= query->len; ++ ++ if (!apfs_node_has_room(node, needed_room, true /* replace */)) { ++ if (node->records == 1) { ++ apfs_alert(sb, "no room in empty node?"); ++ return -EFSCORRUPTED; ++ } ++ err = apfs_node_split(query); ++ if (err && err != -EAGAIN) { ++ apfs_err(sb, "node split failed"); ++ return err; ++ } ++ return -EAGAIN; ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ /* The first key in a node must match the parent record's */ ++ if (key && query->parent && query->index == 0) { ++ err = __apfs_btree_replace(query->parent, key, key_len, NULL /* val */, 0 /* val_len */); ++ if (err) { ++ if (err != -EAGAIN) ++ apfs_err(sb, "parent update failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ ++ err = apfs_node_replace(query, key, key_len, val, val_len); ++ if (err) { ++ apfs_err(sb, "node record replacement failed"); ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_btree_replace - Replace a record in a b-tree leaf ++ * @query: exact query that found the record ++ * @key: new on-disk record key (NULL if unchanged) ++ * @key_len: length of @key ++ * @val: new on-disk record value (NULL if unchanged) ++ * @val_len: length of @val ++ * ++ * It's important that the order of the records is not changed by the new @key. ++ * This function is not needed to replace an old value with a new one of the ++ * same length: it can just be overwritten in place. ++ * ++ * Returns 0 on success, and @query is left pointing to the same record; returns ++ * a negative error code in case of failure. ++ */ ++int apfs_btree_replace(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_node *root = NULL, *leaf = NULL; ++ int err; ++ ++ root = apfs_query_root(query); ++ ASSERT(apfs_node_is_root(root)); ++ leaf = query->node; ++ ASSERT(apfs_node_is_leaf(leaf)); ++ sb = root->object.sb; ++ ++ while (true) { ++ err = __apfs_btree_replace(query, key, key_len, val, val_len); ++ if (err != -EAGAIN) { ++ if (err) ++ return err; ++ break; ++ } ++ err = apfs_query_refresh(query, root, false /* nodata */); ++ if (err) { ++ apfs_err(sb, "query refresh failed"); ++ return err; ++ } ++ } ++ ++ apfs_assert_query_is_valid(query); ++ apfs_btree_change_rec_count(query, 0 /* change */, key_len, val_len); ++ return 0; ++} ++ ++/** ++ * apfs_query_direct_forward - Set a query to start listing records forwards ++ * @query: a successfully executed query ++ * ++ * Multiple queries list records backwards, but queries marked with this ++ * function after execution will go in the opposite direction. ++ */ ++void apfs_query_direct_forward(struct apfs_query *query) ++{ ++ if (query->flags & APFS_QUERY_PREV) ++ return; ++ ++ apfs_assert_query_is_valid(query); ++ ASSERT(apfs_node_is_leaf(query->node)); ++ ++ while (query) { ++ query->flags |= APFS_QUERY_PREV; ++ query = query->parent; ++ } ++} +diff --git a/fs/apfs/compress.c b/fs/apfs/compress.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/compress.c +@@ -0,0 +1,478 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2020 Corellium LLC ++ */ ++ ++#include ++#include ++#include ++ ++#include "apfs.h" ++#include "libzbitmap.h" ++#include "lzfse/lzfse.h" ++#include "lzfse/lzvn_decode_base.h" ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) ++ ++#include ++ ++static inline void *kvmalloc(size_t size, gfp_t flags) ++{ ++ gfp_t kmalloc_flags = flags; ++ void *ret; ++ ++ if ((flags & GFP_KERNEL) != GFP_KERNEL) ++ return kmalloc(size, flags); ++ ++ if (size > PAGE_SIZE) ++ kmalloc_flags |= __GFP_NOWARN | __GFP_NORETRY; ++ ++ ret = kmalloc(size, flags); ++ if (ret || size < PAGE_SIZE) ++ return ret; ++ ++ return vmalloc(size); ++} ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) */ ++ ++struct apfs_compress_file_data { ++ struct apfs_compress_hdr hdr; ++ u8 *buf; ++ ssize_t bufblk; ++ size_t bufsize; ++ struct mutex mtx; ++ struct super_block *sb; ++ struct apfs_compressed_data cdata; ++}; ++ ++static inline int apfs_compress_is_rsrc(u32 algo) ++{ ++ return (algo & 1) == 0; ++} ++ ++static inline bool apfs_compress_is_supported(u32 algo) ++{ ++ switch (algo) { ++ case APFS_COMPRESS_ZLIB_RSRC: ++ case APFS_COMPRESS_ZLIB_ATTR: ++ case APFS_COMPRESS_LZVN_RSRC: ++ case APFS_COMPRESS_LZVN_ATTR: ++ case APFS_COMPRESS_PLAIN_RSRC: ++ case APFS_COMPRESS_PLAIN_ATTR: ++ case APFS_COMPRESS_LZFSE_RSRC: ++ case APFS_COMPRESS_LZFSE_ATTR: ++ case APFS_COMPRESS_LZBITMAP_RSRC: ++ case APFS_COMPRESS_LZBITMAP_ATTR: ++ return true; ++ default: ++ /* Once will usually be enough, don't flood the console */ ++ pr_err_once("APFS: unsupported compression algorithm (%u)\n", algo); ++ return false; ++ } ++} ++ ++static int apfs_compress_file_open(struct inode *inode, struct file *filp) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_compress_file_data *fd; ++ ssize_t res; ++ bool is_rsrc; ++ ++ /* ++ * The official implementation seems to transparently decompress files ++ * when you write to them. Doing that atomically inside the kernel is ++ * probably a chore, so for now I'll just leave it to the user to make ++ * an uncompressed copy themselves and replace the original. I might ++ * fix this in the future, but only if people complain (TODO). ++ */ ++ if (filp->f_mode & FMODE_WRITE) { ++ apfs_warn(sb, "writes to compressed files are not supported"); ++ apfs_warn(sb, "you can work with a copy of the file instead"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) ++ return -EOVERFLOW; ++ ++ fd = kzalloc(sizeof(*fd), GFP_KERNEL); ++ if (!fd) ++ return -ENOMEM; ++ mutex_init(&fd->mtx); ++ fd->sb = sb; ++ ++ down_read(&nxi->nx_big_sem); ++ ++ res = ____apfs_xattr_get(inode, APFS_XATTR_NAME_COMPRESSED, &fd->hdr, sizeof(fd->hdr), 0); ++ if (res != sizeof(fd->hdr)) { ++ apfs_err(sb, "decmpfs header read failed"); ++ goto fail; ++ } ++ ++ if (!apfs_compress_is_supported(le32_to_cpu(fd->hdr.algo))) { ++ res = -EOPNOTSUPP; ++ goto fail; ++ } ++ ++ fd->buf = kvmalloc(APFS_COMPRESS_BLOCK, GFP_KERNEL); ++ if (!fd->buf) { ++ res = -ENOMEM; ++ goto fail; ++ } ++ fd->bufblk = -1; ++ ++ is_rsrc = apfs_compress_is_rsrc(le32_to_cpu(fd->hdr.algo)); ++ res = apfs_xattr_get_compressed_data(inode, is_rsrc ? APFS_XATTR_NAME_RSRC_FORK : APFS_XATTR_NAME_COMPRESSED, &fd->cdata); ++ if (res) { ++ apfs_err(sb, "failed to get compressed data"); ++ goto fail; ++ } ++ ++ up_read(&nxi->nx_big_sem); ++ ++ filp->private_data = fd; ++ return 0; ++ ++fail: ++ apfs_release_compressed_data(&fd->cdata); ++ if (fd->buf) ++ kvfree(fd->buf); ++ up_read(&nxi->nx_big_sem); ++ kfree(fd); ++ if (res > 0) ++ res = -EINVAL; ++ return res; ++} ++ ++static int apfs_compress_file_read_block(struct apfs_compress_file_data *fd, loff_t block) ++{ ++ struct super_block *sb = fd->sb; ++ struct apfs_compressed_data *comp_data = &fd->cdata; ++ u8 *cdata = NULL; ++ u8 *tmp = fd->buf; ++ u32 doffs = 0, coffs; ++ size_t csize, bsize; ++ int res = 0; ++ ++ if (apfs_compress_is_rsrc(le32_to_cpu(fd->hdr.algo)) && ++ le32_to_cpu(fd->hdr.algo) != APFS_COMPRESS_LZBITMAP_RSRC && ++ le32_to_cpu(fd->hdr.algo) != APFS_COMPRESS_LZVN_RSRC && ++ le32_to_cpu(fd->hdr.algo) != APFS_COMPRESS_LZFSE_RSRC) { ++ struct apfs_compress_rsrc_hdr hdr = {0}; ++ struct apfs_compress_rsrc_data cd = {0}; ++ struct apfs_compress_rsrc_block blk = {0}; ++ u32 blk_off; ++ ++ res = apfs_compressed_data_read(comp_data, &hdr, sizeof(hdr), 0 /* offset */); ++ if (res) { ++ apfs_err(sb, "failed to read resource header"); ++ return res; ++ } ++ ++ doffs = be32_to_cpu(hdr.data_offs); ++ res = apfs_compressed_data_read(comp_data, &cd, sizeof(cd), doffs); ++ if (res) { ++ apfs_err(sb, "failed to read resource data header"); ++ return res; ++ } ++ if (block >= le32_to_cpu(cd.num)) ++ return 0; ++ ++ blk_off = doffs + sizeof(cd) + sizeof(blk) * block; ++ res = apfs_compressed_data_read(comp_data, &blk, sizeof(blk), blk_off); ++ if (res) { ++ apfs_err(sb, "failed to read resource block metadata"); ++ return res; ++ } ++ ++ bsize = le64_to_cpu(fd->hdr.size) - block * APFS_COMPRESS_BLOCK; ++ if (bsize > APFS_COMPRESS_BLOCK) ++ bsize = APFS_COMPRESS_BLOCK; ++ ++ csize = le32_to_cpu(blk.size); ++ coffs = le32_to_cpu(blk.offs) + 4; ++ } else if (apfs_compress_is_rsrc(le32_to_cpu(fd->hdr.algo))) { ++ __le32 blks[2]; ++ u32 blk_off; ++ ++ blk_off = doffs + sizeof(__le32) * block; ++ res = apfs_compressed_data_read(comp_data, blks, sizeof(blks), blk_off); ++ if (res) { ++ apfs_err(sb, "failed to read resource block metadata"); ++ return res; ++ } ++ ++ bsize = le64_to_cpu(fd->hdr.size) - block * APFS_COMPRESS_BLOCK; ++ if (bsize > APFS_COMPRESS_BLOCK) ++ bsize = APFS_COMPRESS_BLOCK; ++ ++ coffs = le32_to_cpu(blks[0]); ++ csize = le32_to_cpu(blks[1]) - coffs; ++ } else { ++ /* ++ * I think attr compression is only for single-block files, in ++ * fact none of these files ever seem to decompress to more than ++ * 2048 bytes. ++ */ ++ bsize = le64_to_cpu(fd->hdr.size); ++ if (block != 0 || bsize > APFS_COMPRESS_BLOCK) { ++ apfs_err(sb, "file too big for inline compression"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* The first few bytes are the decmpfs header */ ++ coffs = sizeof(struct apfs_compress_hdr); ++ csize = comp_data->size - sizeof(struct apfs_compress_hdr); ++ } ++ ++ cdata = kvmalloc(csize, GFP_KERNEL); ++ if (!cdata) ++ return -ENOMEM; ++ res = apfs_compressed_data_read(comp_data, cdata, csize, doffs + coffs); ++ if (res) { ++ apfs_err(sb, "failed to read compressed block"); ++ goto fail; ++ } ++ ++ switch (le32_to_cpu(fd->hdr.algo)) { ++ case APFS_COMPRESS_ZLIB_RSRC: ++ case APFS_COMPRESS_ZLIB_ATTR: ++ if (cdata[0] == 0x78 && csize >= 2) { ++ res = zlib_inflate_blob(tmp, bsize, cdata + 2, csize - 2); ++ if (res <= 0) { ++ apfs_err(sb, "zlib decompression failed"); ++ goto fail; ++ } ++ bsize = res; ++ res = 0; ++ } else if ((cdata[0] & 0x0F) == 0x0F) { ++ memcpy(tmp, &cdata[1], csize - 1); ++ bsize = csize - 1; ++ } else { ++ apfs_err(sb, "zlib decompression failed"); ++ res = -EINVAL; ++ goto fail; ++ } ++ break; ++ case APFS_COMPRESS_LZVN_RSRC: ++ case APFS_COMPRESS_LZVN_ATTR: ++ if (cdata[0] == 0x06) { ++ memcpy(tmp, &cdata[1], csize - 1); ++ bsize = csize - 1; ++ } else { ++ lzvn_decoder_state dstate = {0}; ++ ++ dstate.src = cdata; ++ dstate.src_end = dstate.src + csize; ++ dstate.dst = dstate.dst_begin = tmp; ++ dstate.dst_end = dstate.dst + bsize; ++ lzvn_decode(&dstate); ++ bsize = dstate.dst - tmp; ++ } ++ break; ++ case APFS_COMPRESS_LZBITMAP_RSRC: ++ case APFS_COMPRESS_LZBITMAP_ATTR: ++ if (cdata[0] == 0x5a) { ++ res = zbm_decompress(tmp, bsize, cdata, csize, &bsize); ++ if (res < 0) { ++ apfs_err(sb, "lzbitmap decompression failed"); ++ goto fail; ++ } ++ res = 0; ++ } else if ((cdata[0] & 0x0F) == 0x0F) { ++ memcpy(tmp, &cdata[1], csize - 1); ++ bsize = csize - 1; ++ } else { ++ apfs_err(sb, "lzbitmap decompression failed"); ++ res = -EINVAL; ++ goto fail; ++ } ++ break; ++ case APFS_COMPRESS_LZFSE_RSRC: ++ case APFS_COMPRESS_LZFSE_ATTR: ++ if (cdata[0] == 0x62 && csize >= 2) { ++ res = lzfse_decode_buffer(tmp, bsize, cdata, csize, NULL); ++ if (res == 0) { ++ apfs_err(sb, "lzfse decompression failed"); ++ /* Could be ENOMEM too... */ ++ res = -EINVAL; ++ goto fail; ++ } ++ bsize = res; ++ res = 0; ++ } else { ++ /* cdata[0] == 0xff, apparently */ ++ memcpy(tmp, &cdata[1], csize - 1); ++ bsize = csize - 1; ++ } ++ break; ++ case APFS_COMPRESS_PLAIN_RSRC: ++ case APFS_COMPRESS_PLAIN_ATTR: ++ memcpy(tmp, &cdata[1], csize - 1); ++ bsize = csize - 1; ++ break; ++ default: ++ res = -EINVAL; ++ goto fail; ++ } ++ fd->bufblk = block; ++ fd->bufsize = bsize; ++fail: ++ kvfree(cdata); ++ return res; ++} ++ ++static int apfs_compress_file_release(struct inode *inode, struct file *filp) ++{ ++ struct apfs_compress_file_data *fd = filp->private_data; ++ ++ apfs_release_compressed_data(&fd->cdata); ++ if (fd->buf) ++ kvfree(fd->buf); ++ kfree(fd); ++ return 0; ++} ++ ++static ssize_t apfs_compress_file_read_from_block(struct apfs_compress_file_data *fd, char *buf, size_t size, loff_t off) ++{ ++ struct super_block *sb = fd->sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_compressed_data cdata = fd->cdata; ++ loff_t block; ++ size_t bsize; ++ ssize_t res; ++ ++ /* ++ * Request reads of all blocks before actually working with any of them. ++ * The compressed data is typically small enough that this is effective. ++ * It would be much better to make an inode for the xattr dstream and ++ * work with readahead as usual, but I'm not confident I can get that ++ * right (TODO). ++ */ ++ if (cdata.has_dstream && off == 0) { ++ down_read(&nxi->nx_big_sem); ++ apfs_nonsparse_dstream_preread(cdata.dstream); ++ up_read(&nxi->nx_big_sem); ++ } ++ ++ if (off >= le64_to_cpu(fd->hdr.size)) ++ return 0; ++ if (size > le64_to_cpu(fd->hdr.size) - off) ++ size = le64_to_cpu(fd->hdr.size) - off; ++ ++ block = off / APFS_COMPRESS_BLOCK; ++ off -= block * APFS_COMPRESS_BLOCK; ++ if (block != fd->bufblk) { ++ down_read(&nxi->nx_big_sem); ++ res = apfs_compress_file_read_block(fd, block); ++ up_read(&nxi->nx_big_sem); ++ if (res) { ++ apfs_err(sb, "failed to read block into buffer"); ++ return res; ++ } ++ } ++ bsize = fd->bufsize; ++ ++ if (bsize < off) ++ return 0; ++ bsize -= off; ++ if (size > bsize) ++ size = bsize; ++ memcpy(buf, fd->buf + off, size); ++ return size; ++} ++ ++static ssize_t apfs_compress_file_read_page(struct file *filp, char *buf, loff_t off) ++{ ++ struct apfs_compress_file_data *fd = filp->private_data; ++ loff_t step; ++ ssize_t block, res; ++ size_t size = PAGE_SIZE; ++ ++ step = 0; ++ while (step < size) { ++ block = APFS_COMPRESS_BLOCK - ((off + step) & (APFS_COMPRESS_BLOCK - 1)); ++ if (block > size - step) ++ block = size - step; ++ mutex_lock(&fd->mtx); ++ res = apfs_compress_file_read_from_block(fd, buf + step, block, off + step); ++ mutex_unlock(&fd->mtx); ++ if (res < block) { ++ if (res < 0 && !step) ++ return res; ++ step += res > 0 ? res : 0; ++ break; ++ } ++ step += block; ++ } ++ return step; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++static int apfs_compress_read_folio(struct file *filp, struct folio *folio) ++{ ++ struct page *page = &folio->page; ++#else ++static int apfs_compress_readpage(struct file *filp, struct page *page) ++{ ++#endif ++ char *addr = NULL; ++ ssize_t ret; ++ loff_t off; ++ ++ /* Mostly copied from ext4_read_inline_page() */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) ++ off = page_folio(page)->index << PAGE_SHIFT; ++#else ++ off = page->index << PAGE_SHIFT; ++#endif ++ addr = kmap(page); ++ ret = apfs_compress_file_read_page(filp, addr, off); ++ flush_dcache_page(page); ++ kunmap(page); ++ if (ret >= 0) { ++ zero_user_segment(page, ret, PAGE_SIZE); ++ SetPageUptodate(page); ++ ret = 0; ++ } ++ ++ unlock_page(page); ++ return ret; ++} ++ ++const struct address_space_operations apfs_compress_aops = { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ .read_folio = apfs_compress_read_folio, ++#else ++ .readpage = apfs_compress_readpage, ++#endif ++}; ++ ++/* TODO: these operations are all happening without proper locks */ ++const struct file_operations apfs_compress_file_operations = { ++ .open = apfs_compress_file_open, ++ .llseek = generic_file_llseek, ++ .read_iter = generic_file_read_iter, ++ .release = apfs_compress_file_release, ++ .mmap = apfs_file_mmap, ++}; ++ ++int apfs_compress_get_size(struct inode *inode, loff_t *size) ++{ ++ struct apfs_compress_hdr hdr; ++ int res = ____apfs_xattr_get(inode, APFS_XATTR_NAME_COMPRESSED, &hdr, sizeof(hdr), 0); ++ ++ if (res < 0) ++ return res; ++ if (res != sizeof(hdr)) { ++ apfs_err(inode->i_sb, "decmpfs header read failed"); ++ return 1; ++ } ++ ++ if (!apfs_compress_is_supported(le32_to_cpu(hdr.algo))) ++ return 1; ++ ++ *size = le64_to_cpu(hdr.size); ++ return 0; ++} +diff --git a/fs/apfs/dir.c b/fs/apfs/dir.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/dir.c +@@ -0,0 +1,1504 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_drec_from_query - Read the directory record found by a successful query ++ * @query: the query that found the record ++ * @drec: Return parameter. The directory record found. ++ * @hashed: is this record hashed? ++ * ++ * Reads the directory record into @drec and performs some basic sanity checks ++ * as a protection against crafted filesystems. Returns 0 on success or ++ * -EFSCORRUPTED otherwise. ++ * ++ * The caller must not free @query while @drec is in use, because @drec->name ++ * points to data on disk. ++ */ ++static int apfs_drec_from_query(struct apfs_query *query, struct apfs_drec *drec, bool hashed) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ struct apfs_drec_hashed_key *de_hkey = NULL; ++ struct apfs_drec_key *de_ukey = NULL; ++ struct apfs_drec_val *de; ++ int namelen, xlen; ++ char *xval = NULL, *name; ++ ++ namelen = query->key_len - (hashed ? sizeof(*de_hkey) : sizeof(*de_ukey)); ++ if (namelen < 1) { ++ apfs_err(sb, "key is too small (%d)", query->key_len); ++ return -EFSCORRUPTED; ++ } ++ if (query->len < sizeof(*de)) { ++ apfs_err(sb, "value is too small (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ ++ de = (struct apfs_drec_val *)(raw + query->off); ++ if (hashed) { ++ de_hkey = (struct apfs_drec_hashed_key *)(raw + query->key_off); ++ if (namelen != (le32_to_cpu(de_hkey->name_len_and_hash) & APFS_DREC_LEN_MASK)) { ++ apfs_err(sb, "inconsistent name length"); ++ return -EFSCORRUPTED; ++ } ++ name = de_hkey->name; ++ } else { ++ de_ukey = (struct apfs_drec_key *)(raw + query->key_off); ++ if (namelen != le16_to_cpu(de_ukey->name_len)) { ++ apfs_err(sb, "inconsistent name length"); ++ return -EFSCORRUPTED; ++ } ++ name = de_ukey->name; ++ } ++ ++ /* Filename must be NULL-terminated */ ++ if (name[namelen - 1] != 0) { ++ apfs_err(sb, "null termination missing"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* The dentry may have at most one xfield: the sibling id */ ++ drec->sibling_id = 0; ++ xlen = apfs_find_xfield(de->xfields, query->len - sizeof(*de), ++ APFS_DREC_EXT_TYPE_SIBLING_ID, &xval); ++ if (xlen >= sizeof(__le64)) { ++ __le64 *sib_id = (__le64 *)xval; ++ ++ drec->sibling_id = le64_to_cpup(sib_id); ++ } ++ ++ drec->name = name; ++ drec->name_len = namelen - 1; /* Don't count the NULL termination */ ++ drec->ino = le64_to_cpu(de->file_id); ++ ++ drec->type = le16_to_cpu(de->flags) & APFS_DREC_TYPE_MASK; ++ if (drec->type != DT_FIFO && drec->type & 1) /* Invalid file type */ ++ drec->type = DT_UNKNOWN; ++ return 0; ++} ++ ++/** ++ * apfs_dentry_lookup - Lookup a dentry record in the catalog b-tree ++ * @dir: parent directory ++ * @child: filename ++ * @drec: on return, the directory record found ++ * ++ * Runs a catalog query for @name in the @dir directory. On success, sets ++ * @drec and returns a pointer to the query structure. On failure, returns ++ * an appropriate error pointer. ++ */ ++static struct apfs_query *apfs_dentry_lookup(struct inode *dir, ++ const struct qstr *child, ++ struct apfs_drec *drec) ++{ ++ struct super_block *sb = dir->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ u64 cnid = apfs_ino(dir); ++ bool hashed = apfs_is_normalization_insensitive(sb); ++ int err; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return ERR_PTR(-ENOMEM); ++ apfs_init_drec_key(sb, cnid, child->name, child->len, &query->key); ++ ++ /* ++ * Distinct filenames in the same directory may (rarely) share the same ++ * hash. The query code cannot handle that because their order in the ++ * b-tree would depend on their unnormalized original names. Just get ++ * all the candidates and check them one by one. ++ * ++ * This is very wasteful for normalization-sensitive filesystems: there ++ * are no hashes so we just check every single file in the directory for ++ * no reason. This would be easy to avoid but does it matter? (TODO) ++ */ ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_ANY_NAME | APFS_QUERY_EXACT; ++ do { ++ err = apfs_btree_query(sb, &query); ++ if (err) ++ goto fail; ++ err = apfs_drec_from_query(query, drec, hashed); ++ if (err) ++ goto fail; ++ } while (unlikely(apfs_filename_cmp(sb, child->name, child->len, drec->name, drec->name_len))); ++ ++ /* ++ * We may need to refresh the query later, but the refresh code doesn't ++ * know how to deal with hash collisions. Instead set the key to the ++ * unnormalized name and pretend that this was never a multiple query ++ * in the first place. ++ */ ++ query->key.name = drec->name; ++ query->flags &= ~(APFS_QUERY_MULTIPLE | APFS_QUERY_DONE | APFS_QUERY_NEXT); ++ return query; ++ ++fail: ++ if (err != -ENODATA) ++ apfs_err(sb, "query failed in dir 0x%llx", cnid); ++ apfs_free_query(query); ++ return ERR_PTR(err); ++} ++ ++/** ++ * apfs_inode_by_name - Find the cnid for a given filename ++ * @dir: parent directory ++ * @child: filename ++ * @ino: on return, the inode number found ++ * ++ * Returns 0 and the inode number (which is the cnid of the file ++ * record); otherwise, return the appropriate error code. ++ */ ++int apfs_inode_by_name(struct inode *dir, const struct qstr *child, u64 *ino) ++{ ++ struct super_block *sb = dir->i_sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_query *query; ++ struct apfs_drec drec; ++ int err = 0; ++ ++ down_read(&nxi->nx_big_sem); ++ query = apfs_dentry_lookup(dir, child, &drec); ++ if (IS_ERR(query)) { ++ err = PTR_ERR(query); ++ goto out; ++ } ++ *ino = drec.ino; ++ apfs_free_query(query); ++out: ++ up_read(&nxi->nx_big_sem); ++ return err; ++} ++ ++static int apfs_readdir(struct file *file, struct dir_context *ctx) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_query *query; ++ u64 cnid = apfs_ino(inode); ++ loff_t pos; ++ bool hashed = apfs_is_normalization_insensitive(sb); ++ int err = 0; ++ ++ down_read(&nxi->nx_big_sem); ++ ++ /* Inode numbers might overflow here; follow btrfs in ignoring that */ ++ if (!dir_emit_dots(file, ctx)) ++ goto out; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ /* We want all the children for the cnid, regardless of the name */ ++ apfs_init_drec_key(sb, cnid, NULL /* name */, 0 /* name_len */, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_MULTIPLE | APFS_QUERY_EXACT; ++ ++ pos = ctx->pos - 2; ++ while (1) { ++ struct apfs_drec drec; ++ /* ++ * We query for the matching records, one by one. After we ++ * pass ctx->pos we begin to emit them. ++ * ++ * TODO: Faster approach for large directories? ++ */ ++ ++ err = apfs_btree_query(sb, &query); ++ if (err == -ENODATA) { /* Got all the records */ ++ err = 0; ++ break; ++ } ++ if (err) ++ break; ++ ++ err = apfs_drec_from_query(query, &drec, hashed); ++ if (err) { ++ apfs_alert(sb, "bad dentry record in directory 0x%llx", ++ cnid); ++ break; ++ } ++ ++ err = 0; ++ if (pos <= 0) { ++ if (!dir_emit(ctx, drec.name, drec.name_len, ++ drec.ino, drec.type)) ++ break; ++ ++ctx->pos; ++ } ++ pos--; ++ } ++ apfs_free_query(query); ++ ++out: ++ up_read(&nxi->nx_big_sem); ++ return err; ++} ++ ++const struct file_operations apfs_dir_operations = { ++ .llseek = generic_file_llseek, ++ .read = generic_read_dir, ++ .iterate_shared = apfs_readdir, ++ .fsync = apfs_fsync, ++ .unlocked_ioctl = apfs_dir_ioctl, ++}; ++ ++/** ++ * apfs_build_dentry_unhashed_key - Allocate and initialize the key for an unhashed dentry record ++ * @qname: filename ++ * @parent_id: inode number for the parent of the dentry ++ * @key_p: on return, a pointer to the new on-disk key structure ++ * ++ * Returns the length of the key, or a negative error code in case of failure. ++ */ ++static int apfs_build_dentry_unhashed_key(const struct qstr *qname, u64 parent_id, ++ struct apfs_drec_key **key_p) ++{ ++ struct apfs_drec_key *key; ++ u16 namelen = qname->len + 1; /* We count the null-termination */ ++ int key_len; ++ ++ key_len = sizeof(*key) + namelen; ++ key = kmalloc(key_len, GFP_KERNEL); ++ if (!key) ++ return -ENOMEM; ++ ++ apfs_key_set_hdr(APFS_TYPE_DIR_REC, parent_id, key); ++ key->name_len = cpu_to_le16(namelen); ++ strscpy(key->name, qname->name, namelen); ++ ++ *key_p = key; ++ return key_len; ++} ++ ++/** ++ * apfs_build_dentry_hashed_key - Allocate and initialize the key for a hashed dentry record ++ * @qname: filename ++ * @hash: filename hash ++ * @parent_id: inode number for the parent of the dentry ++ * @key_p: on return, a pointer to the new on-disk key structure ++ * ++ * Returns the length of the key, or a negative error code in case of failure. ++ */ ++static int apfs_build_dentry_hashed_key(const struct qstr *qname, u64 hash, u64 parent_id, ++ struct apfs_drec_hashed_key **key_p) ++{ ++ struct apfs_drec_hashed_key *key; ++ u16 namelen = qname->len + 1; /* We count the null-termination */ ++ int key_len; ++ ++ key_len = sizeof(*key) + namelen; ++ key = kmalloc(key_len, GFP_KERNEL); ++ if (!key) ++ return -ENOMEM; ++ ++ apfs_key_set_hdr(APFS_TYPE_DIR_REC, parent_id, key); ++ key->name_len_and_hash = cpu_to_le32(namelen | hash); ++ strscpy(key->name, qname->name, namelen); ++ ++ *key_p = key; ++ return key_len; ++} ++ ++/** ++ * apfs_build_dentry_val - Allocate and initialize the value for a dentry record ++ * @inode: vfs inode for the dentry ++ * @sibling_id: sibling id for this hardlink (0 for none) ++ * @val_p: on return, a pointer to the new on-disk value structure ++ * ++ * Returns the length of the value, or a negative error code in case of failure. ++ */ ++static int apfs_build_dentry_val(struct inode *inode, u64 sibling_id, ++ struct apfs_drec_val **val_p) ++{ ++ struct apfs_drec_val *val; ++ struct apfs_x_field xkey; ++ int total_xlen = 0, val_len; ++ __le64 raw_sibling_id = cpu_to_le64(sibling_id); ++ struct timespec64 now = current_time(inode); ++ ++ /* The dentry record may have one xfield: the sibling id */ ++ if (sibling_id) ++ total_xlen += sizeof(struct apfs_xf_blob) + ++ sizeof(xkey) + sizeof(raw_sibling_id); ++ ++ val_len = sizeof(*val) + total_xlen; ++ val = kmalloc(val_len, GFP_KERNEL); ++ if (!val) ++ return -ENOMEM; ++ *val_p = val; ++ ++ val->file_id = cpu_to_le64(apfs_ino(inode)); ++ val->date_added = cpu_to_le64(timespec64_to_ns(&now)); ++ val->flags = cpu_to_le16((inode->i_mode >> 12) & 15); /* File type */ ++ ++ if (!sibling_id) ++ return val_len; ++ ++ /* The buffer was just allocated: none of these functions should fail */ ++ apfs_init_xfields(val->xfields, val_len - sizeof(*val)); ++ xkey.x_type = APFS_DREC_EXT_TYPE_SIBLING_ID; ++ xkey.x_flags = 0; /* TODO: proper flags here? */ ++ xkey.x_size = cpu_to_le16(sizeof(raw_sibling_id)); ++ apfs_insert_xfield(val->xfields, total_xlen, &xkey, &raw_sibling_id); ++ return val_len; ++} ++ ++/** ++ * apfs_create_dentry_rec - Create a dentry record in the catalog b-tree ++ * @inode: vfs inode for the dentry ++ * @qname: filename ++ * @parent_id: inode number for the parent of the dentry ++ * @sibling_id: sibling id for this hardlink (0 for none) ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_dentry_rec(struct inode *inode, const struct qstr *qname, ++ u64 parent_id, u64 sibling_id) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ void *raw_key = NULL; ++ struct apfs_drec_val *raw_val = NULL; ++ int key_len, val_len; ++ bool hashed = apfs_is_normalization_insensitive(sb); ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_drec_key(sb, parent_id, qname->name, qname->len, &query->key); ++ query->flags |= APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed in dir 0x%llx (hash 0x%llx)", parent_id, query->key.number); ++ goto fail; ++ } ++ ++ if (hashed) ++ key_len = apfs_build_dentry_hashed_key(qname, query->key.number, parent_id, ++ (struct apfs_drec_hashed_key **)&raw_key); ++ else ++ key_len = apfs_build_dentry_unhashed_key(qname, parent_id, ++ (struct apfs_drec_key **)&raw_key); ++ if (key_len < 0) { ++ ret = key_len; ++ goto fail; ++ } ++ ++ val_len = apfs_build_dentry_val(inode, sibling_id, &raw_val); ++ if (val_len < 0) { ++ ret = val_len; ++ goto fail; ++ } ++ /* TODO: deal with hash collisions */ ++ ret = apfs_btree_insert(query, raw_key, key_len, raw_val, val_len); ++ if (ret) ++ apfs_err(sb, "insertion failed in dir 0x%llx (hash 0x%llx)", parent_id, query->key.number); ++ ++fail: ++ kfree(raw_val); ++ kfree(raw_key); ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_build_sibling_val - Allocate and initialize a sibling link's value ++ * @dentry: in-memory dentry for this hardlink ++ * @val_p: on return, a pointer to the new on-disk value structure ++ * ++ * Returns the length of the value, or a negative error code in case of failure. ++ */ ++static int apfs_build_sibling_val(struct dentry *dentry, ++ struct apfs_sibling_val **val_p) ++{ ++ struct apfs_sibling_val *val; ++ const struct qstr *qname = &dentry->d_name; ++ u16 namelen = qname->len + 1; /* We count the null-termination */ ++ struct inode *parent = d_inode(dentry->d_parent); ++ int val_len; ++ ++ val_len = sizeof(*val) + namelen; ++ val = kmalloc(val_len, GFP_KERNEL); ++ if (!val) ++ return -ENOMEM; ++ ++ val->parent_id = cpu_to_le64(apfs_ino(parent)); ++ val->name_len = cpu_to_le16(namelen); ++ strscpy(val->name, qname->name, namelen); ++ ++ *val_p = val; ++ return val_len; ++} ++ ++/** ++ * apfs_create_sibling_link_rec - Create a sibling link record for a dentry ++ * @dentry: the in-memory dentry ++ * @inode: vfs inode for the dentry ++ * @sibling_id: sibling id for this hardlink ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_sibling_link_rec(struct dentry *dentry, ++ struct inode *inode, u64 sibling_id) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_sibling_link_key raw_key; ++ struct apfs_sibling_val *raw_val; ++ int val_len; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_sibling_link_key(apfs_ino(inode), sibling_id, &query->key); ++ query->flags |= APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for ino 0x%llx, sibling 0x%llx", apfs_ino(inode), sibling_id); ++ goto fail; ++ } ++ ++ apfs_key_set_hdr(APFS_TYPE_SIBLING_LINK, apfs_ino(inode), &raw_key); ++ raw_key.sibling_id = cpu_to_le64(sibling_id); ++ val_len = apfs_build_sibling_val(dentry, &raw_val); ++ if (val_len < 0) ++ goto fail; ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), raw_val, val_len); ++ if (ret) ++ apfs_err(sb, "insertion failed for ino 0x%llx, sibling 0x%llx", apfs_ino(inode), sibling_id); ++ kfree(raw_val); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_create_sibling_map_rec - Create a sibling map record for a dentry ++ * @dentry: the in-memory dentry ++ * @inode: vfs inode for the dentry ++ * @sibling_id: sibling id for this hardlink ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_sibling_map_rec(struct dentry *dentry, ++ struct inode *inode, u64 sibling_id) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_sibling_map_key raw_key; ++ struct apfs_sibling_map_val raw_val; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_sibling_map_key(sibling_id, &query->key); ++ query->flags |= APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for sibling 0x%llx", sibling_id); ++ goto fail; ++ } ++ ++ apfs_key_set_hdr(APFS_TYPE_SIBLING_MAP, sibling_id, &raw_key); ++ raw_val.file_id = cpu_to_le64(apfs_ino(inode)); ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "insertion failed for sibling 0x%llx", sibling_id); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_create_sibling_recs - Create sibling link and map records for a dentry ++ * @dentry: the in-memory dentry ++ * @inode: vfs inode for the dentry ++ * @sibling_id: on return, the sibling id for this hardlink ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_sibling_recs(struct dentry *dentry, ++ struct inode *inode, u64 *sibling_id) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ u64 cnid; ++ int ret; ++ ++ /* Sibling ids come from the same pool as the inode numbers */ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ cnid = le64_to_cpu(vsb_raw->apfs_next_obj_id); ++ le64_add_cpu(&vsb_raw->apfs_next_obj_id, 1); ++ ++ ret = apfs_create_sibling_link_rec(dentry, inode, cnid); ++ if (ret) ++ return ret; ++ ret = apfs_create_sibling_map_rec(dentry, inode, cnid); ++ if (ret) ++ return ret; ++ ++ *sibling_id = cnid; ++ return 0; ++} ++ ++/** ++ * apfs_create_dentry - Create all records for a new dentry ++ * @dentry: the in-memory dentry ++ * @inode: vfs inode for the dentry ++ * ++ * Creates the dentry record itself, as well as the sibling records if needed; ++ * also updates the child count for the parent inode. Returns 0 on success or ++ * a negative error code in case of failure. ++ */ ++static int apfs_create_dentry(struct dentry *dentry, struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct inode *parent = d_inode(dentry->d_parent); ++ u64 sibling_id = 0; ++ int err; ++ ++ if (inode->i_nlink > 1) { ++ /* This is optional for a single link, so don't waste space */ ++ err = apfs_create_sibling_recs(dentry, inode, &sibling_id); ++ if (err) { ++ apfs_err(sb, "failed to create sibling recs for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ } ++ ++ err = apfs_create_dentry_rec(inode, &dentry->d_name, apfs_ino(parent), sibling_id); ++ if (err) { ++ apfs_err(sb, "failed to create drec for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ /* Now update the parent inode */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ parent->i_mtime = parent->i_ctime = current_time(inode); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ parent->i_mtime = inode_set_ctime_current(parent); ++#else ++ inode_set_mtime_to_ts(parent, inode_set_ctime_current(parent)); ++#endif ++ ++APFS_I(parent)->i_nchildren; ++ apfs_inode_join_transaction(parent->i_sb, parent); ++ return 0; ++} ++ ++/** ++ * apfs_undo_create_dentry - Clean up apfs_create_dentry() ++ * @dentry: the in-memory dentry ++ */ ++static void apfs_undo_create_dentry(struct dentry *dentry) ++{ ++ struct inode *parent = d_inode(dentry->d_parent); ++ ++ --APFS_I(parent)->i_nchildren; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) ++ ++static inline void discard_new_inode(struct inode *inode) ++{ ++ unlock_new_inode(inode); ++ iput(inode); ++} ++ ++#endif ++ ++int apfs_mkany(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t rdev, const char *symname) ++{ ++ struct super_block *sb = dir->i_sb; ++ struct inode *inode; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ inode = apfs_new_inode(dir, mode, rdev); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ goto out_abort; ++ } ++ ++ err = apfs_create_inode_rec(sb, inode, dentry); ++ if (err) { ++ apfs_err(sb, "failed to create inode rec for ino 0x%llx", apfs_ino(inode)); ++ goto out_discard_inode; ++ } ++ ++ err = apfs_create_dentry(dentry, inode); ++ if (err) { ++ apfs_err(sb, "failed to create dentry recs for ino 0x%llx", apfs_ino(inode)); ++ goto out_discard_inode; ++ } ++ ++ if (symname) { ++ err = apfs_xattr_set(inode, APFS_XATTR_NAME_SYMLINK, symname, ++ strlen(symname) + 1, 0 /* flags */); ++ if (err == -ERANGE) { ++ err = -ENAMETOOLONG; ++ goto out_undo_create; ++ } ++ if (err) { ++ apfs_err(sb, "failed to set symlink xattr for ino 0x%llx", apfs_ino(inode)); ++ goto out_undo_create; ++ } ++ } ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto out_undo_create; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) ++ /* Apparently there is a lockdep bug here, but it doesn't matter */ ++ unlock_new_inode(inode); ++ d_instantiate(dentry, inode); ++#else ++ d_instantiate_new(dentry, inode); ++#endif ++ return 0; ++ ++out_undo_create: ++ apfs_undo_create_dentry(dentry); ++out_discard_inode: ++ /* Don't reset nlink: on-disk cleanup is unneeded and would deadlock */ ++ discard_new_inode(inode); ++out_abort: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++int apfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t rdev) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++int apfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode, dev_t rdev) ++#else ++int apfs_mknod(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, dev_t rdev) ++#endif ++{ ++ return apfs_mkany(dir, dentry, mode, rdev, NULL /* symname */); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ ++int apfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ return apfs_mknod(dir, dentry, mode | S_IFDIR, 0 /* rdev */); ++} ++ ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ ++int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode) ++{ ++ return apfs_mknod(mnt_userns, dir, dentry, mode | S_IFDIR, 0 /* rdev */); ++} ++ ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 15, 0) ++ ++int apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode) ++{ ++ return apfs_mknod(idmap, dir, dentry, mode | S_IFDIR, 0 /* rdev */); ++} ++ ++#else ++ ++struct dentry *apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ return ERR_PTR(apfs_mknod(idmap, dir, dentry, mode | S_IFDIR, 0 /* rdev */)); ++} ++ ++#endif ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ ++int apfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool excl) ++{ ++ return apfs_mknod(dir, dentry, mode, 0 /* rdev */); ++} ++ ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ ++int apfs_create(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl) ++{ ++ return apfs_mknod(mnt_userns, dir, dentry, mode, 0 /* rdev */); ++} ++ ++#else ++ ++int apfs_create(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl) ++{ ++ return apfs_mknod(idmap, dir, dentry, mode, 0 /* rdev */); ++} ++ ++#endif ++ ++ ++/** ++ * apfs_prepare_dentry_for_link - Assign a sibling id and records to a dentry ++ * @dentry: the in-memory dentry (should be for a primary link) ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_prepare_dentry_for_link(struct dentry *dentry) ++{ ++ struct inode *parent = d_inode(dentry->d_parent); ++ struct super_block *sb = parent->i_sb; ++ struct apfs_query *query; ++ struct apfs_drec drec; ++ u64 sibling_id; ++ int ret; ++ ++ query = apfs_dentry_lookup(parent, &dentry->d_name, &drec); ++ if (IS_ERR(query)) { ++ apfs_err(sb, "lookup failed in dir 0x%llx", apfs_ino(parent)); ++ return PTR_ERR(query); ++ } ++ if (drec.sibling_id) { ++ /* This dentry already has a sibling id xfield */ ++ apfs_free_query(query); ++ return 0; ++ } ++ ++ /* Don't modify the dentry record, just delete it to make a new one */ ++ ret = apfs_btree_remove(query); ++ apfs_free_query(query); ++ if (ret) { ++ apfs_err(sb, "removal failed in dir 0x%llx", apfs_ino(parent)); ++ return ret; ++ } ++ ++ ret = apfs_create_sibling_recs(dentry, d_inode(dentry), &sibling_id); ++ if (ret) { ++ apfs_err(sb, "failed to create sibling recs in dir 0x%llx", apfs_ino(parent)); ++ return ret; ++ } ++ return apfs_create_dentry_rec(d_inode(dentry), &dentry->d_name, ++ apfs_ino(parent), sibling_id); ++} ++ ++/** ++ * __apfs_undo_link - Clean up __apfs_link() ++ * @dentry: the in-memory dentry ++ * @inode: target inode ++ */ ++static void __apfs_undo_link(struct dentry *dentry, struct inode *inode) ++{ ++ apfs_undo_create_dentry(dentry); ++ drop_nlink(inode); ++} ++ ++/** ++ * __apfs_link - Link a dentry ++ * @old_dentry: dentry for the old link ++ * @dentry: new dentry to link ++ * ++ * Does the same as apfs_link(), but without starting a transaction, taking a ++ * new reference to @old_dentry->d_inode, or instantiating @dentry. ++ */ ++static int __apfs_link(struct dentry *old_dentry, struct dentry *dentry) ++{ ++ struct inode *inode = d_inode(old_dentry); ++ struct super_block *sb = inode->i_sb; ++ int err; ++ ++ /* First update the inode's link count */ ++ inc_nlink(inode); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_ctime = current_time(inode); ++#else ++ inode_set_ctime_current(inode); ++#endif ++ apfs_inode_join_transaction(inode->i_sb, inode); ++ ++ if (inode->i_nlink == 2) { ++ /* A single link may lack sibling records, so create them now */ ++ err = apfs_prepare_dentry_for_link(old_dentry); ++ if (err) { ++ apfs_err(sb, "failed to prepare original dentry"); ++ goto fail; ++ } ++ } ++ ++ err = apfs_create_dentry(dentry, inode); ++ if (err) { ++ apfs_err(sb, "failed to create new dentry"); ++ goto fail; ++ } ++ return 0; ++ ++fail: ++ drop_nlink(inode); ++ return err; ++} ++ ++int apfs_link(struct dentry *old_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ struct super_block *sb = dir->i_sb; ++ struct inode *inode = d_inode(old_dentry); ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ err = __apfs_link(old_dentry, dentry); ++ if (err) ++ goto out_abort; ++ ihold(inode); ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto out_undo_link; ++ ++ d_instantiate(dentry, inode); ++ return 0; ++ ++out_undo_link: ++ iput(inode); ++ __apfs_undo_link(dentry, inode); ++out_abort: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_delete_sibling_link_rec - Delete the sibling link record for a dentry ++ * @dentry: the in-memory dentry ++ * @sibling_id: sibling id for this hardlink ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_delete_sibling_link_rec(struct dentry *dentry, u64 sibling_id) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct inode *inode = d_inode(dentry); ++ struct apfs_query *query = NULL; ++ int ret; ++ ++ ASSERT(sibling_id); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_sibling_link_key(apfs_ino(inode), sibling_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret == -ENODATA) { ++ /* A dentry with a sibling id must have sibling records */ ++ ret = -EFSCORRUPTED; ++ } ++ if (ret) { ++ apfs_err(sb, "query failed for ino 0x%llx, sibling 0x%llx", apfs_ino(inode), sibling_id); ++ goto fail; ++ } ++ ret = apfs_btree_remove(query); ++ if (ret) ++ apfs_err(sb, "removal failed for ino 0x%llx, sibling 0x%llx", apfs_ino(inode), sibling_id); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_delete_sibling_map_rec - Delete the sibling map record for a dentry ++ * @dentry: the in-memory dentry ++ * @sibling_id: sibling id for this hardlink ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_delete_sibling_map_rec(struct dentry *dentry, u64 sibling_id) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ int ret; ++ ++ ASSERT(sibling_id); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_sibling_map_key(sibling_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret == -ENODATA) { ++ /* A dentry with a sibling id must have sibling records */ ++ ret = -EFSCORRUPTED; ++ } ++ if (ret) { ++ apfs_err(sb, "query failed for sibling 0x%llx", sibling_id); ++ goto fail; ++ } ++ ret = apfs_btree_remove(query); ++ if (ret) ++ apfs_err(sb, "removal failed for sibling 0x%llx", sibling_id); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_delete_dentry - Delete all records for a dentry ++ * @dentry: the in-memory dentry ++ * ++ * Deletes the dentry record itself, as well as the sibling records if they ++ * exist; also updates the child count for the parent inode. Returns 0 on ++ * success or a negative error code in case of failure. ++ */ ++static int apfs_delete_dentry(struct dentry *dentry) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct inode *parent = d_inode(dentry->d_parent); ++ struct apfs_query *query; ++ struct apfs_drec drec; ++ int err; ++ ++ query = apfs_dentry_lookup(parent, &dentry->d_name, &drec); ++ if (IS_ERR(query)) ++ return PTR_ERR(query); ++ err = apfs_btree_remove(query); ++ apfs_free_query(query); ++ if (err) { ++ apfs_err(sb, "drec removal failed"); ++ return err; ++ } ++ ++ if (drec.sibling_id) { ++ err = apfs_delete_sibling_link_rec(dentry, drec.sibling_id); ++ if (err) { ++ apfs_err(sb, "sibling link removal failed"); ++ return err; ++ } ++ err = apfs_delete_sibling_map_rec(dentry, drec.sibling_id); ++ if (err) { ++ apfs_err(sb, "sibling map removal failed"); ++ return err; ++ } ++ } ++ ++ /* Now update the parent inode */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ parent->i_mtime = parent->i_ctime = current_time(parent); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ parent->i_mtime = inode_set_ctime_current(parent); ++#else ++ inode_set_mtime_to_ts(parent, inode_set_ctime_current(parent)); ++#endif ++ --APFS_I(parent)->i_nchildren; ++ apfs_inode_join_transaction(sb, parent); ++ return err; ++} ++ ++/** ++ * apfs_undo_delete_dentry - Clean up apfs_delete_dentry() ++ * @dentry: the in-memory dentry ++ */ ++static inline void apfs_undo_delete_dentry(struct dentry *dentry) ++{ ++ struct inode *parent = d_inode(dentry->d_parent); ++ ++ /* Cleanup for the on-disk changes will happen on transaction abort */ ++ ++APFS_I(parent)->i_nchildren; ++} ++ ++/** ++ * apfs_sibling_link_from_query - Read the sibling link record found by a query ++ * @query: the query that found the record ++ * @name: on return, the name of link ++ * @parent: on return, the inode number for the link's parent ++ * ++ * Reads the sibling link information into @parent and @name, and performs some ++ * basic sanity checks as a protection against crafted filesystems. The caller ++ * must free @name after use. Returns 0 on success or a negative error code in ++ * case of failure. ++ */ ++static int apfs_sibling_link_from_query(struct apfs_query *query, ++ char **name, u64 *parent) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ struct apfs_sibling_val *siblink; ++ int namelen = query->len - sizeof(*siblink); ++ ++ if (namelen < 1) { ++ apfs_err(sb, "value is too small (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ siblink = (struct apfs_sibling_val *)(raw + query->off); ++ ++ if (namelen != le16_to_cpu(siblink->name_len)) { ++ apfs_err(sb, "inconsistent name length"); ++ return -EFSCORRUPTED; ++ } ++ /* Filename must be NULL-terminated */ ++ if (siblink->name[namelen - 1] != 0) { ++ apfs_err(sb, "null termination missing"); ++ return -EFSCORRUPTED; ++ } ++ ++ *name = kmalloc(namelen, GFP_KERNEL); ++ if (!*name) ++ return -ENOMEM; ++ strscpy(*name, siblink->name, namelen); ++ *parent = le64_to_cpu(siblink->parent_id); ++ return 0; ++} ++ ++/** ++ * apfs_find_primary_link - Find the primary link for an inode ++ * @inode: the vfs inode ++ * @name: on return, the name of the primary link ++ * @parent: on return, the inode number for the primary parent ++ * ++ * On success, returns 0 and sets @parent and @name; the second must be freed ++ * by the caller after use. Returns a negative error code in case of failure. ++ */ ++static int apfs_find_primary_link(struct inode *inode, char **name, u64 *parent) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ int err; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_sibling_link_key(apfs_ino(inode), 0 /* sibling_id */, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_ANY_NUMBER | APFS_QUERY_EXACT; ++ ++ /* The primary link is the one with the lowest sibling id */ ++ *name = NULL; ++ while (1) { ++ err = apfs_btree_query(sb, &query); ++ if (err == -ENODATA) /* No more link records */ ++ break; ++ kfree(*name); ++ if (err) { ++ apfs_err(sb, "query failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ ++ err = apfs_sibling_link_from_query(query, name, parent); ++ if (err) { ++ apfs_err(sb, "bad sibling link record for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ } ++ err = *name ? 0 : -EFSCORRUPTED; /* Sibling records must exist */ ++ if (err) ++ apfs_err(sb, "query failed for ino 0x%llx", apfs_ino(inode)); ++ ++fail: ++ apfs_free_query(query); ++ return err; ++} ++ ++/** ++ * apfs_orphan_name - Get the name for an orphan inode's invisible link ++ * @ino: the inode number ++ * @qname: on return, the name assigned to the link ++ * ++ * Returns 0 on success; the caller must remember to free @qname->name after ++ * use. Returns a negative error code in case of failure. ++ */ ++static int apfs_orphan_name(u64 ino, struct qstr *qname) ++{ ++ int max_len; ++ char *name; ++ ++ /* The name is the inode number in hex, with '-dead' suffix */ ++ max_len = 2 + 16 + 5 + 1; ++ name = kmalloc(max_len, GFP_KERNEL); ++ if (!name) ++ return -ENOMEM; ++ qname->len = snprintf(name, max_len, "0x%llx-dead", ino); ++ qname->name = name; ++ return 0; ++} ++ ++/** ++ * apfs_create_orphan_link - Create a link for an orphan inode under private-dir ++ * @inode: the vfs inode ++ * ++ * On success, returns 0. Returns a negative error code in case of failure. ++ */ ++static int apfs_create_orphan_link(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct inode *priv_dir = sbi->s_private_dir; ++ struct qstr qname; ++ int err = 0; ++ ++ err = apfs_orphan_name(apfs_ino(inode), &qname); ++ if (err) ++ return err; ++ err = apfs_create_dentry_rec(inode, &qname, apfs_ino(priv_dir), 0 /* sibling_id */); ++ if (err) { ++ apfs_err(sb, "failed to create drec for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ ++ /* Now update the child count for private-dir */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ priv_dir->i_mtime = priv_dir->i_ctime = current_time(priv_dir); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ priv_dir->i_mtime = inode_set_ctime_current(priv_dir); ++#else ++ inode_set_mtime_to_ts(priv_dir, inode_set_ctime_current(priv_dir)); ++#endif ++ ++APFS_I(priv_dir)->i_nchildren; ++ apfs_inode_join_transaction(sb, priv_dir); ++ ++fail: ++ kfree(qname.name); ++ return err; ++} ++ ++/** ++ * apfs_delete_orphan_link - Delete the link for an orphan inode ++ * @inode: the vfs inode ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_delete_orphan_link(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct inode *priv_dir = sbi->s_private_dir; ++ struct apfs_query *query; ++ struct qstr qname; ++ struct apfs_drec drec; ++ int err; ++ ++ err = apfs_orphan_name(apfs_ino(inode), &qname); ++ if (err) ++ return err; ++ ++ query = apfs_dentry_lookup(priv_dir, &qname, &drec); ++ if (IS_ERR(query)) { ++ apfs_err(sb, "dentry lookup failed"); ++ err = PTR_ERR(query); ++ query = NULL; ++ goto fail; ++ } ++ err = apfs_btree_remove(query); ++ if (err) { ++ apfs_err(sb, "dentry removal failed"); ++ goto fail; ++ } ++ ++ /* Now update the child count for private-dir */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ priv_dir->i_mtime = priv_dir->i_ctime = current_time(priv_dir); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ priv_dir->i_mtime = inode_set_ctime_current(priv_dir); ++#else ++ inode_set_mtime_to_ts(priv_dir, inode_set_ctime_current(priv_dir)); ++#endif ++ --APFS_I(priv_dir)->i_nchildren; ++ apfs_inode_join_transaction(sb, priv_dir); ++ ++fail: ++ apfs_free_query(query); ++ kfree(qname.name); ++ return err; ++} ++ ++/** ++ * __apfs_undo_unlink - Clean up __apfs_unlink() ++ * @dentry: dentry to unlink ++ */ ++static void __apfs_undo_unlink(struct dentry *dentry) ++{ ++ struct inode *inode = d_inode(dentry); ++ ++ inode->i_state |= I_LINKABLE; /* Silence warning about nlink 0->1 */ ++ inc_nlink(inode); ++ inode->i_state &= ~I_LINKABLE; ++ ++ apfs_undo_delete_dentry(dentry); ++} ++ ++/** ++ * apfs_vol_filecnt_dec - Update the volume file count after a new orphaning ++ * @orphan: the new orphan ++ */ ++static void apfs_vol_filecnt_dec(struct inode *orphan) ++{ ++ struct super_block *sb = orphan->i_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ ++ switch (orphan->i_mode & S_IFMT) { ++ case S_IFREG: ++ le64_add_cpu(&vsb_raw->apfs_num_files, -1); ++ break; ++ case S_IFDIR: ++ le64_add_cpu(&vsb_raw->apfs_num_directories, -1); ++ break; ++ case S_IFLNK: ++ le64_add_cpu(&vsb_raw->apfs_num_symlinks, -1); ++ break; ++ default: ++ le64_add_cpu(&vsb_raw->apfs_num_other_fsobjects, -1); ++ break; ++ } ++} ++ ++/** ++ * __apfs_unlink - Unlink a dentry ++ * @dir: parent directory ++ * @dentry: dentry to unlink ++ * ++ * Does the same as apfs_unlink(), but without starting a transaction. ++ */ ++static int __apfs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ struct inode *inode = d_inode(dentry); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ char *primary_name = NULL; ++ int err; ++ ++ err = apfs_delete_dentry(dentry); ++ if (err) { ++ apfs_err(sb, "failed to delete dentry recs for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ drop_nlink(inode); ++ if (!inode->i_nlink) { ++ /* Orphaned inodes continue to report their old location */ ++ err = apfs_create_orphan_link(inode); ++ /* Orphans are not included in the volume file counts */ ++ apfs_vol_filecnt_dec(inode); ++ } else { ++ /* We may have deleted the primary link, so get the new one */ ++ err = apfs_find_primary_link(inode, &primary_name, ++ &ai->i_parent_id); ++ } ++ if (err) ++ goto fail; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_ctime = dir->i_ctime; ++#else ++ inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); ++#endif ++ /* TODO: defer write of the primary name? */ ++ err = apfs_update_inode(inode, primary_name); ++ if (err) ++ apfs_err(sb, "inode update failed for 0x%llx", apfs_ino(inode)); ++ ++fail: ++ kfree(primary_name); ++ primary_name = NULL; ++ if (err) ++ __apfs_undo_unlink(dentry); ++ return err; ++} ++ ++int apfs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ struct super_block *sb = dir->i_sb; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_DEL); ++ if (err) ++ return err; ++ ++ err = __apfs_unlink(dir, dentry); ++ if (err) ++ goto out_abort; ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto out_undo_unlink; ++ return 0; ++ ++out_undo_unlink: ++ __apfs_undo_unlink(dentry); ++out_abort: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++int apfs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ struct inode *inode = d_inode(dentry); ++ ++ if (APFS_I(inode)->i_nchildren) ++ return -ENOTEMPTY; ++ return apfs_unlink(dir, dentry); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++int apfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, ++ unsigned int flags) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++int apfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, ++ struct dentry *old_dentry, struct inode *new_dir, ++ struct dentry *new_dentry, unsigned int flags) ++#else ++int apfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, ++ struct dentry *old_dentry, struct inode *new_dir, ++ struct dentry *new_dentry, unsigned int flags) ++#endif ++{ ++ struct super_block *sb = old_dir->i_sb; ++ struct inode *old_inode = d_inode(old_dentry); ++ struct inode *new_inode = d_inode(new_dentry); ++ int err; ++ ++ if (new_inode && APFS_I(new_inode)->i_nchildren) ++ return -ENOTEMPTY; ++ ++ if (flags & ~RENAME_NOREPLACE) /* TODO: support RENAME_EXCHANGE */ ++ return -EINVAL; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ if (new_inode) { ++ err = __apfs_unlink(new_dir, new_dentry); ++ if (err) { ++ apfs_err(sb, "unlink failed for replaced dentry"); ++ goto out_abort; ++ } ++ } ++ ++ err = __apfs_link(old_dentry, new_dentry); ++ if (err) { ++ apfs_err(sb, "link failed for new dentry"); ++ goto out_undo_unlink_new; ++ } ++ ++ err = __apfs_unlink(old_dir, old_dentry); ++ if (err) { ++ apfs_err(sb, "unlink failed for old dentry"); ++ goto out_undo_link; ++ } ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto out_undo_unlink_old; ++ return 0; ++ ++out_undo_unlink_old: ++ __apfs_undo_unlink(old_dentry); ++out_undo_link: ++ __apfs_undo_link(new_dentry, old_inode); ++out_undo_unlink_new: ++ if (new_inode) ++ __apfs_undo_unlink(new_dentry); ++out_abort: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_any_orphan_ino - Find the inode number for any orphaned regular file ++ * @sb: filesytem superblock ++ * @ino_p: on return, the inode number found ++ * ++ * Returns 0 on success, or a negative error code in case of failure, which may ++ * be -ENODATA if there are no orphan files. ++ */ ++u64 apfs_any_orphan_ino(struct super_block *sb, u64 *ino_p) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_drec drec = {0}; ++ struct qstr qname = {0}; ++ bool hashed = apfs_is_normalization_insensitive(sb); ++ bool found = false; ++ int err; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_drec_key(sb, APFS_PRIV_DIR_INO_NUM, NULL /* name */, 0 /* name_len */, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_MULTIPLE | APFS_QUERY_EXACT; ++ ++ while (!found) { ++ err = apfs_btree_query(sb, &query); ++ if (err) { ++ if (err == -ENODATA) ++ goto out; ++ apfs_err(sb, "drec query failed for private dir"); ++ goto out; ++ } ++ err = apfs_drec_from_query(query, &drec, hashed); ++ if (err) { ++ apfs_alert(sb, "bad dentry record in private dir"); ++ goto out; ++ } ++ ++ /* These files are deleted immediately by ->evict_inode() */ ++ if (drec.type != DT_REG) ++ continue; ++ ++ /* ++ * Confirm that this is an orphan file, because the official ++ * reference allows other uses for the private directory. ++ */ ++ err = apfs_orphan_name(drec.ino, &qname); ++ if (err) ++ goto out; ++ found = strcmp(drec.name, qname.name) == 0; ++ kfree(qname.name); ++ qname.name = NULL; ++ } ++ *ino_p = drec.ino; ++ ++out: ++ apfs_free_query(query); ++ query = NULL; ++ return err; ++} +diff --git a/fs/apfs/extents.c b/fs/apfs/extents.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/extents.c +@@ -0,0 +1,2374 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_ext_is_hole - Does this extent represent a hole in a sparse file? ++ * @extent: the extent to check ++ */ ++static inline bool apfs_ext_is_hole(struct apfs_file_extent *extent) ++{ ++ return extent->phys_block_num == 0; ++} ++ ++/** ++ * apfs_size_to_blocks - Return the block count for a given size, rounded up ++ * @sb: filesystem superblock ++ * @size: size in bytes ++ * ++ * TODO: reuse for inode.c ++ */ ++static inline u64 apfs_size_to_blocks(struct super_block *sb, u64 size) ++{ ++ return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; ++} ++ ++/** ++ * apfs_extent_from_query - Read the extent found by a successful query ++ * @query: the query that found the record ++ * @extent: Return parameter. The extent found. ++ * ++ * Reads the extent record into @extent and performs some basic sanity checks ++ * as a protection against crafted filesystems. Returns 0 on success or ++ * -EFSCORRUPTED otherwise. ++ */ ++int apfs_extent_from_query(struct apfs_query *query, ++ struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ u64 ext_len; ++ ++ if (!apfs_is_sealed(sb)) { ++ struct apfs_file_extent_val *ext = NULL; ++ struct apfs_file_extent_key *ext_key = NULL; ++ ++ if (query->len != sizeof(*ext) || query->key_len != sizeof(*ext_key)) { ++ apfs_err(sb, "bad length of key (%d) or value (%d)", query->key_len, query->len); ++ return -EFSCORRUPTED; ++ } ++ ++ ext = (struct apfs_file_extent_val *)(raw + query->off); ++ ext_key = (struct apfs_file_extent_key *)(raw + query->key_off); ++ ext_len = le64_to_cpu(ext->len_and_flags) & APFS_FILE_EXTENT_LEN_MASK; ++ ++ extent->logical_addr = le64_to_cpu(ext_key->logical_addr); ++ extent->phys_block_num = le64_to_cpu(ext->phys_block_num); ++ extent->crypto_id = le64_to_cpu(ext->crypto_id); ++ } else { ++ struct apfs_fext_tree_val *fext_val = NULL; ++ struct apfs_fext_tree_key *fext_key = NULL; ++ ++ if (query->len != sizeof(*fext_val) || query->key_len != sizeof(*fext_key)) { ++ apfs_err(sb, "bad length of sealed key (%d) or value (%d)", query->key_len, query->len); ++ return -EFSCORRUPTED; ++ } ++ ++ fext_val = (struct apfs_fext_tree_val *)(raw + query->off); ++ fext_key = (struct apfs_fext_tree_key *)(raw + query->key_off); ++ ext_len = le64_to_cpu(fext_val->len_and_flags) & APFS_FILE_EXTENT_LEN_MASK; ++ ++ extent->logical_addr = le64_to_cpu(fext_key->logical_addr); ++ extent->phys_block_num = le64_to_cpu(fext_val->phys_block_num); ++ extent->crypto_id = 0; ++ } ++ ++ /* Extent length must be a multiple of the block size */ ++ if (ext_len & (sb->s_blocksize - 1)) { ++ apfs_err(sb, "invalid length (0x%llx)", ext_len); ++ return -EFSCORRUPTED; ++ } ++ extent->len = ext_len; ++ return 0; ++} ++ ++/** ++ * apfs_extent_read - Read the extent record that covers a block ++ * @dstream: data stream info ++ * @dsblock: logical number of the wanted block (must be in range) ++ * @extent: Return parameter. The extent found. ++ * ++ * Finds and caches the extent record. On success, returns a pointer to the ++ * cache record; on failure, returns an error code. ++ */ ++static int apfs_extent_read(struct apfs_dstream_info *dstream, sector_t dsblock, ++ struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_key key; ++ struct apfs_query *query; ++ struct apfs_file_extent *cache = &dstream->ds_cached_ext; ++ u64 iaddr = dsblock << sb->s_blocksize_bits; ++ struct apfs_node *root = NULL; ++ int ret = 0; ++ ++ spin_lock(&dstream->ds_ext_lock); ++ if (iaddr >= cache->logical_addr && ++ iaddr < cache->logical_addr + cache->len) { ++ *extent = *cache; ++ spin_unlock(&dstream->ds_ext_lock); ++ return 0; ++ } ++ spin_unlock(&dstream->ds_ext_lock); ++ ++ /* We will search for the extent that covers iblock */ ++ if (!apfs_is_sealed(sb)) { ++ apfs_init_file_extent_key(dstream->ds_id, iaddr, &key); ++ root = sbi->s_cat_root; ++ } else { ++ apfs_init_fext_key(dstream->ds_id, iaddr, &key); ++ root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_fext_tree_oid), APFS_OBJ_PHYSICAL, false /* write */); ++ if (IS_ERR(root)) { ++ apfs_err(sb, "failed to read fext root 0x%llx", le64_to_cpu(vsb_raw->apfs_fext_tree_oid)); ++ return PTR_ERR(root); ++ } ++ } ++ ++ query = apfs_alloc_query(root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ query->key = key; ++ query->flags = apfs_is_sealed(sb) ? APFS_QUERY_FEXT : APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx, addr 0x%llx", dstream->ds_id, iaddr); ++ if (ret == -ENODATA) ++ ret = -EFSCORRUPTED; ++ goto done; ++ } ++ ++ ret = apfs_extent_from_query(query, extent); ++ if (ret) { ++ apfs_err(sb, "bad extent record for dstream 0x%llx", dstream->ds_id); ++ goto done; ++ } ++ if (iaddr < extent->logical_addr || iaddr >= extent->logical_addr + extent->len) { ++ apfs_err(sb, "no extent for addr 0x%llx in dstream 0x%llx", iaddr, dstream->ds_id); ++ ret = -EFSCORRUPTED; ++ goto done; ++ } ++ ++ /* ++ * For now prioritize the deferral of writes. ++ * i_extent_dirty is protected by the read semaphore. ++ */ ++ if (!dstream->ds_ext_dirty) { ++ spin_lock(&dstream->ds_ext_lock); ++ *cache = *extent; ++ spin_unlock(&dstream->ds_ext_lock); ++ } ++ ++done: ++ apfs_free_query(query); ++ if (apfs_is_sealed(sb)) ++ apfs_node_free(root); ++ return ret; ++} ++ ++/** ++ * apfs_logic_to_phys_bno - Find the physical block number for a dstream block ++ * @dstream: data stream info ++ * @dsblock: logical number of the wanted block ++ * @bno: on return, the physical block number (or zero for holes) ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_logic_to_phys_bno(struct apfs_dstream_info *dstream, sector_t dsblock, u64 *bno) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_file_extent ext; ++ u64 blk_off; ++ int ret; ++ ++ ret = apfs_extent_read(dstream, dsblock, &ext); ++ if (ret) ++ return ret; ++ ++ if (apfs_ext_is_hole(&ext)) { ++ *bno = 0; ++ return 0; ++ } ++ ++ /* Find the block offset of iblock within the extent */ ++ blk_off = dsblock - (ext.logical_addr >> sb->s_blocksize_bits); ++ *bno = ext.phys_block_num + blk_off; ++ return 0; ++} ++ ++/* This does the same as apfs_get_block(), but without taking any locks */ ++int __apfs_get_block(struct apfs_dstream_info *dstream, sector_t dsblock, ++ struct buffer_head *bh_result, int create) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_file_extent ext; ++ u64 blk_off, bno, map_len; ++ int ret; ++ ++ ASSERT(!create); ++ ++ if (dsblock >= apfs_size_to_blocks(sb, dstream->ds_size)) ++ return 0; ++ ++ ret = apfs_extent_read(dstream, dsblock, &ext); ++ if (ret) { ++ apfs_err(sb, "extent read failed"); ++ return ret; ++ } ++ ++ /* Find the block offset of iblock within the extent */ ++ blk_off = dsblock - (ext.logical_addr >> sb->s_blocksize_bits); ++ ++ /* Make sure we don't read past the extent boundaries */ ++ map_len = ext.len - (blk_off << sb->s_blocksize_bits); ++ if (bh_result->b_size > map_len) ++ bh_result->b_size = map_len; ++ ++ /* ++ * Save the requested mapping length as apfs_map_bh() replaces it with ++ * the filesystem block size ++ */ ++ map_len = bh_result->b_size; ++ /* Extents representing holes have block number 0 */ ++ if (!apfs_ext_is_hole(&ext)) { ++ /* Find the block number of iblock within the disk */ ++ bno = ext.phys_block_num + blk_off; ++ apfs_map_bh(bh_result, sb, bno); ++ } ++ bh_result->b_size = map_len; ++ return 0; ++} ++ ++int apfs_get_block(struct inode *inode, sector_t iblock, ++ struct buffer_head *bh_result, int create) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(inode->i_sb); ++ struct apfs_inode_info *ai = APFS_I(inode); ++ int ret; ++ ++ down_read(&nxi->nx_big_sem); ++ ret = __apfs_get_block(&ai->i_dstream, iblock, bh_result, create); ++ up_read(&nxi->nx_big_sem); ++ return ret; ++} ++ ++/** ++ * apfs_set_extent_length - Set a new length in an extent record's value ++ * @ext: the extent record's value ++ * @len: the new length ++ * ++ * Preserves the flags, though none are defined yet and I don't know if that ++ * will ever be important. ++ */ ++static inline void apfs_set_extent_length(struct apfs_file_extent_val *ext, u64 len) ++{ ++ u64 len_and_flags = le64_to_cpu(ext->len_and_flags); ++ u64 flags = len_and_flags & APFS_FILE_EXTENT_FLAG_MASK; ++ ++ ext->len_and_flags = cpu_to_le64(flags | len); ++} ++ ++static int apfs_range_put_reference(struct super_block *sb, u64 paddr, u64 length); ++ ++/** ++ * apfs_shrink_extent_head - Shrink an extent record in its head ++ * @query: the query that found the record ++ * @dstream: data stream info ++ * @start: new logical start for the extent ++ * ++ * Also deletes the physical extent records for the head. Returns 0 on success ++ * or a negative error code in case of failure. ++ */ ++static int apfs_shrink_extent_head(struct apfs_query *query, struct apfs_dstream_info *dstream, u64 start) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_file_extent_key key; ++ struct apfs_file_extent_val val; ++ struct apfs_file_extent extent; ++ u64 new_len, head_len; ++ void *raw = NULL; ++ int err = 0; ++ ++ err = apfs_extent_from_query(query, &extent); ++ if (err) { ++ apfs_err(sb, "bad extent record for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ raw = query->node->object.data; ++ key = *(struct apfs_file_extent_key *)(raw + query->key_off); ++ val = *(struct apfs_file_extent_val *)(raw + query->off); ++ ++ new_len = extent.logical_addr + extent.len - start; ++ head_len = extent.len - new_len; ++ ++ /* Delete the physical records for the blocks lost in the shrinkage */ ++ if (!apfs_ext_is_hole(&extent)) { ++ err = apfs_range_put_reference(sb, extent.phys_block_num, head_len); ++ if (err) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", extent.phys_block_num, head_len); ++ return err; ++ } ++ } else { ++ dstream->ds_sparse_bytes -= head_len; ++ } ++ ++ /* This is the actual shrinkage of the logical extent */ ++ key.logical_addr = cpu_to_le64(start); ++ apfs_set_extent_length(&val, new_len); ++ if (!apfs_ext_is_hole(&extent)) ++ le64_add_cpu(&val.phys_block_num, head_len >> sb->s_blocksize_bits); ++ return apfs_btree_replace(query, &key, sizeof(key), &val, sizeof(val)); ++} ++ ++/** ++ * apfs_shrink_extent_tail - Shrink an extent record in its tail ++ * @query: the query that found the record ++ * @dstream: data stream info ++ * @end: new logical end for the extent ++ * ++ * Also puts the physical extent records for the tail. Returns 0 on success or ++ * a negative error code in case of failure. ++ */ ++static int apfs_shrink_extent_tail(struct apfs_query *query, struct apfs_dstream_info *dstream, u64 end) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_file_extent_val *val; ++ struct apfs_file_extent extent; ++ u64 new_len, new_blkcount, tail_len; ++ void *raw; ++ int err = 0; ++ ++ ASSERT((end & (sb->s_blocksize - 1)) == 0); ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ ++ err = apfs_extent_from_query(query, &extent); ++ if (err) { ++ apfs_err(sb, "bad extent record for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ val = raw + query->off; ++ ++ new_len = end - extent.logical_addr; ++ new_blkcount = new_len >> sb->s_blocksize_bits; ++ tail_len = extent.len - new_len; ++ ++ /* Delete the physical records for the blocks lost in the shrinkage */ ++ if (!apfs_ext_is_hole(&extent)) { ++ err = apfs_range_put_reference(sb, extent.phys_block_num + new_blkcount, tail_len); ++ if (err) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", extent.phys_block_num + new_blkcount, tail_len); ++ return err; ++ } ++ } else { ++ dstream->ds_sparse_bytes -= tail_len; ++ } ++ ++ /* This is the actual shrinkage of the logical extent */ ++ apfs_set_extent_length(val, new_len); ++ return err; ++} ++ ++/** ++ * apfs_query_found_extent - Did this query find an extent with the right id? ++ * @query: the (successful) query that found the record ++ */ ++static inline bool apfs_query_found_extent(struct apfs_query *query) ++{ ++ void *raw = query->node->object.data; ++ struct apfs_key_header *hdr; ++ ++ if (query->key_len < sizeof(*hdr)) ++ return false; ++ hdr = raw + query->key_off; ++ ++ if (apfs_cat_type(hdr) != APFS_TYPE_FILE_EXTENT) ++ return false; ++ if (apfs_cat_cnid(hdr) != query->key.id) ++ return false; ++ return true; ++} ++ ++/** ++ * apfs_update_tail_extent - Grow the tail extent for a data stream ++ * @dstream: data stream info ++ * @extent: new in-memory extent ++ * ++ * Also takes care of any needed changes to the physical extent records. Returns ++ * 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_update_tail_extent(struct apfs_dstream_info *dstream, const struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_file_extent_key raw_key; ++ struct apfs_file_extent_val raw_val; ++ u64 extent_id = dstream->ds_id; ++ int ret; ++ u64 new_crypto; ++ ++ apfs_key_set_hdr(APFS_TYPE_FILE_EXTENT, extent_id, &raw_key); ++ raw_key.logical_addr = cpu_to_le64(extent->logical_addr); ++ raw_val.len_and_flags = cpu_to_le64(extent->len); ++ raw_val.phys_block_num = cpu_to_le64(extent->phys_block_num); ++ if (apfs_vol_is_encrypted(sb)) ++ new_crypto = extent_id; ++ else ++ new_crypto = 0; ++ raw_val.crypto_id = cpu_to_le64(new_crypto); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ /* We want the last extent record */ ++ apfs_init_file_extent_key(extent_id, -1, &query->key); ++ query->flags = APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for last extent of id 0x%llx", extent_id); ++ goto out; ++ } ++ ++ if (ret == -ENODATA || !apfs_query_found_extent(query)) { ++ /* We are creating the first extent for the file */ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ } else { ++ struct apfs_file_extent tail; ++ ++ ret = apfs_extent_from_query(query, &tail); ++ if (ret) { ++ apfs_err(sb, "bad extent record for dstream 0x%llx", dstream->ds_id); ++ goto out; ++ } ++ ++ if (tail.logical_addr > extent->logical_addr) { ++ apfs_alert(sb, "extent is not tail - bug!"); ++ ret = -EOPNOTSUPP; ++ goto out; ++ } else if (tail.logical_addr == extent->logical_addr) { ++ ret = apfs_btree_replace(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "update failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ if (apfs_ext_is_hole(&tail)) { ++ dstream->ds_sparse_bytes -= tail.len; ++ } else if (tail.phys_block_num != extent->phys_block_num) { ++ ret = apfs_range_put_reference(sb, tail.phys_block_num, tail.len); ++ if (ret) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", tail.phys_block_num, tail.len); ++ goto out; ++ } ++ } ++ if (new_crypto == tail.crypto_id) ++ goto out; ++ ret = apfs_crypto_adj_refcnt(sb, tail.crypto_id, -1); ++ if (ret) { ++ apfs_err(sb, "failed to put crypto id 0x%llx", tail.crypto_id); ++ goto out; ++ } ++ } else { ++ /* ++ * TODO: we could actually also continue the tail extent ++ * if it's right next to the new one (both logically and ++ * physically), even if they don't overlap. Or maybe we ++ * should always make sure that the tail extent is in ++ * the cache before a write... ++ */ ++ if (extent->logical_addr < tail.logical_addr + tail.len) { ++ ret = apfs_shrink_extent_tail(query, dstream, extent->logical_addr); ++ if (ret) { ++ apfs_err(sb, "failed to shrink tail of dstream 0x%llx", extent_id); ++ goto out; ++ } ++ } ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ } ++ } ++ ++ ret = apfs_crypto_adj_refcnt(sb, new_crypto, 1); ++ if (ret) ++ apfs_err(sb, "failed to take crypto id 0x%llx", new_crypto); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_split_extent - Break an extent in two ++ * @query: query pointing to the extent ++ * @div: logical address for the division ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_split_extent(struct apfs_query *query, u64 div) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_file_extent_val *val1; ++ struct apfs_file_extent_key key2; ++ struct apfs_file_extent_val val2; ++ struct apfs_file_extent extent; ++ u64 len1, len2, blkcount1; ++ void *raw; ++ int err = 0; ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ ++ err = apfs_extent_from_query(query, &extent); ++ if (err) { ++ apfs_err(sb, "bad extent record"); ++ return err; ++ } ++ val1 = raw + query->off; ++ val2 = *(struct apfs_file_extent_val *)(raw + query->off); ++ key2 = *(struct apfs_file_extent_key *)(raw + query->key_off); ++ ++ len1 = div - extent.logical_addr; ++ blkcount1 = len1 >> sb->s_blocksize_bits; ++ len2 = extent.len - len1; ++ ++ /* Modify the current extent in place to become the first half */ ++ apfs_set_extent_length(val1, len1); ++ ++ /* Insert the second half right after the first */ ++ key2.logical_addr = cpu_to_le64(div); ++ if (!apfs_ext_is_hole(&extent)) ++ val2.phys_block_num = cpu_to_le64(extent.phys_block_num + blkcount1); ++ apfs_set_extent_length(&val2, len2); ++ err = apfs_btree_insert(query, &key2, sizeof(key2), &val2, sizeof(val2)); ++ if (err) { ++ apfs_err(sb, "insertion failed in division 0x%llx", div); ++ return err; ++ } ++ ++ return apfs_crypto_adj_refcnt(sb, extent.crypto_id, 1); ++} ++ ++/** ++ * apfs_update_mid_extent - Create or update a non-tail extent for a dstream ++ * @dstream: data stream info ++ * @extent: new in-memory extent ++ * ++ * Also takes care of any needed changes to the physical extent records. Returns ++ * 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_update_mid_extent(struct apfs_dstream_info *dstream, const struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_key key; ++ struct apfs_query *query; ++ struct apfs_file_extent_key raw_key; ++ struct apfs_file_extent_val raw_val; ++ struct apfs_file_extent prev_ext; ++ u64 extent_id = dstream->ds_id; ++ u64 prev_crypto, new_crypto; ++ u64 prev_start, prev_end; ++ bool second_run = false; ++ int ret; ++ ++ apfs_key_set_hdr(APFS_TYPE_FILE_EXTENT, extent_id, &raw_key); ++ raw_key.logical_addr = cpu_to_le64(extent->logical_addr); ++ raw_val.len_and_flags = cpu_to_le64(extent->len); ++ raw_val.phys_block_num = cpu_to_le64(extent->phys_block_num); ++ if (apfs_vol_is_encrypted(sb)) ++ new_crypto = extent_id; ++ else ++ new_crypto = 0; ++ raw_val.crypto_id = cpu_to_le64(new_crypto); ++ ++ apfs_init_file_extent_key(extent_id, extent->logical_addr, &key); ++ ++search_and_insert: ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ query->key = key; ++ query->flags = APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ ++ if (ret == -ENODATA || !apfs_query_found_extent(query)) { ++ /* ++ * The new extent goes in a hole we just made, right at the ++ * beginning of the file. ++ */ ++ if (!second_run) { ++ apfs_err(sb, "missing extent on dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ } else { ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ } ++ goto out; ++ } ++ ++ if (apfs_extent_from_query(query, &prev_ext)) { ++ apfs_err(sb, "bad mid extent record on dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ prev_crypto = prev_ext.crypto_id; ++ prev_start = prev_ext.logical_addr; ++ prev_end = prev_ext.logical_addr + prev_ext.len; ++ ++ if (prev_end == extent->logical_addr && second_run) { ++ /* The new extent goes in the hole we just made */ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ } else if (prev_start == extent->logical_addr && prev_ext.len == extent->len) { ++ /* The old and new extents are the same logical block */ ++ ret = apfs_btree_replace(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "update failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ if (apfs_ext_is_hole(&prev_ext)) { ++ dstream->ds_sparse_bytes -= prev_ext.len; ++ } else if (prev_ext.phys_block_num != extent->phys_block_num) { ++ ret = apfs_range_put_reference(sb, prev_ext.phys_block_num, prev_ext.len); ++ if (ret) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", prev_ext.phys_block_num, prev_ext.len); ++ goto out; ++ } ++ } ++ ret = apfs_crypto_adj_refcnt(sb, prev_crypto, -1); ++ if (ret) { ++ apfs_err(sb, "failed to put crypto id 0x%llx", prev_crypto); ++ goto out; ++ } ++ } else if (prev_start == extent->logical_addr) { ++ /* The new extent is the first logical block of the old one */ ++ if (second_run) { ++ /* I don't know if this is possible, but be safe */ ++ apfs_alert(sb, "recursion shrinking extent head for dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ret = apfs_shrink_extent_head(query, dstream, extent->logical_addr + extent->len); ++ if (ret) { ++ apfs_err(sb, "failed to shrink extent in dstream 0x%llx", extent_id); ++ goto out; ++ } ++ /* The query should point to the previous record, start again */ ++ apfs_free_query(query); ++ second_run = true; ++ goto search_and_insert; ++ } else if (prev_end == extent->logical_addr + extent->len) { ++ /* The new extent is the last logical block of the old one */ ++ ret = apfs_shrink_extent_tail(query, dstream, extent->logical_addr); ++ if (ret) { ++ apfs_err(sb, "failed to shrink extent in dstream 0x%llx", extent_id); ++ goto out; ++ } ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, extent->logical_addr); ++ goto out; ++ } ++ } else if (prev_start < extent->logical_addr && prev_end > extent->logical_addr + extent->len) { ++ /* The new extent is logically in the middle of the old one */ ++ if (second_run) { ++ /* I don't know if this is possible, but be safe */ ++ apfs_alert(sb, "recursion when splitting extents for dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ret = apfs_split_extent(query, extent->logical_addr + extent->len); ++ if (ret) { ++ apfs_err(sb, "failed to split extent in dstream 0x%llx", extent_id); ++ goto out; ++ } ++ /* The split may make the query invalid */ ++ apfs_free_query(query); ++ second_run = true; ++ goto search_and_insert; ++ } else { ++ /* I don't know what this is, be safe */ ++ apfs_alert(sb, "strange extents for dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ ret = apfs_crypto_adj_refcnt(sb, new_crypto, 1); ++ if (ret) ++ apfs_err(sb, "failed to take crypto id 0x%llx", new_crypto); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_update_extent - Create or update the extent record for an extent ++ * @dstream: data stream info ++ * @extent: new in-memory file extent ++ * ++ * The @extent must either be a new tail for the dstream, or a single block. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_update_extent(struct apfs_dstream_info *dstream, const struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ ++ if (extent->logical_addr + extent->len >= dstream->ds_size) ++ return apfs_update_tail_extent(dstream, extent); ++ if (extent->len > sb->s_blocksize) { ++ apfs_err(sb, "can't create mid extents of length 0x%llx", extent->len); ++ return -EOPNOTSUPP; ++ } ++ return apfs_update_mid_extent(dstream, extent); ++} ++ ++static int apfs_extend_phys_extent(struct apfs_query *query, u64 bno, u64 blkcnt, u64 dstream_id) ++{ ++ struct apfs_phys_ext_key raw_key; ++ struct apfs_phys_ext_val raw_val; ++ u64 kind = (u64)APFS_KIND_NEW << APFS_PEXT_KIND_SHIFT; ++ ++ apfs_key_set_hdr(APFS_TYPE_EXTENT, bno, &raw_key); ++ raw_val.len_and_kind = cpu_to_le64(kind | blkcnt); ++ raw_val.owning_obj_id = cpu_to_le64(dstream_id); ++ raw_val.refcnt = cpu_to_le32(1); ++ return apfs_btree_replace(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++} ++ ++static int apfs_insert_new_phys_extent(struct apfs_query *query, u64 bno, u64 blkcnt, u64 dstream_id) ++{ ++ struct apfs_phys_ext_key raw_key; ++ struct apfs_phys_ext_val raw_val; ++ u64 kind = (u64)APFS_KIND_NEW << APFS_PEXT_KIND_SHIFT; ++ ++ apfs_key_set_hdr(APFS_TYPE_EXTENT, bno, &raw_key); ++ raw_val.len_and_kind = cpu_to_le64(kind | blkcnt); ++ raw_val.owning_obj_id = cpu_to_le64(dstream_id); ++ raw_val.refcnt = cpu_to_le32(1); ++ return apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++} ++ ++static int apfs_phys_ext_from_query(struct apfs_query *query, struct apfs_phys_extent *pext); ++ ++/** ++ * apfs_insert_phys_extent - Create or grow the physical record for an extent ++ * @dstream: data stream info for the extent ++ * @extent: new in-memory file extent ++ * ++ * Only works for appending to extents, for now. TODO: reference counting. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_insert_phys_extent(struct apfs_dstream_info *dstream, const struct apfs_file_extent *extent) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_node *extref_root; ++ struct apfs_query *query = NULL; ++ struct apfs_phys_extent pext; ++ u64 blkcnt = extent->len >> sb->s_blocksize_bits; ++ u64 last_bno, new_base, new_blkcnt; ++ int ret; ++ ++ extref_root = apfs_read_node(sb, ++ le64_to_cpu(vsb_raw->apfs_extentref_tree_oid), ++ APFS_OBJ_PHYSICAL, true /* write */); ++ if (IS_ERR(extref_root)) { ++ apfs_err(sb, "failed to read extref root 0x%llx", le64_to_cpu(vsb_raw->apfs_extentref_tree_oid)); ++ return PTR_ERR(extref_root); ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_extentref_tree_oid = cpu_to_le64(extref_root->object.oid); ++ ++ query = apfs_alloc_query(extref_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ /* ++ * The cached logical extent may have been split into multiple physical ++ * extents because of clones. If that happens, we want to grow the last ++ * one. ++ */ ++ last_bno = extent->phys_block_num + blkcnt - 1; ++ apfs_init_extent_key(last_bno, &query->key); ++ query->flags = APFS_QUERY_EXTENTREF; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for paddr 0x%llx", last_bno); ++ goto out; ++ } ++ ++ if (ret == -ENODATA) { ++ /* This is a fresh new physical extent */ ++ ret = apfs_insert_new_phys_extent(query, extent->phys_block_num, blkcnt, dstream->ds_id); ++ if (ret) ++ apfs_err(sb, "insertion failed for paddr 0x%llx", extent->phys_block_num); ++ goto out; ++ } ++ ++ ret = apfs_phys_ext_from_query(query, &pext); ++ if (ret) { ++ apfs_err(sb, "bad pext record for bno 0x%llx", last_bno); ++ goto out; ++ } ++ if (pext.bno + pext.blkcount <= extent->phys_block_num) { ++ /* Also a fresh new physical extent */ ++ ret = apfs_insert_new_phys_extent(query, extent->phys_block_num, blkcnt, dstream->ds_id); ++ if (ret) ++ apfs_err(sb, "insertion failed for paddr 0x%llx", extent->phys_block_num); ++ goto out; ++ } ++ ++ /* ++ * There is an existing physical extent that overlaps the new one. The ++ * cache was dirty, so the existing extent can't cover the whole tail. ++ */ ++ if (pext.bno + pext.blkcount >= extent->phys_block_num + blkcnt) { ++ apfs_err(sb, "dirty cache tail covered by existing physical extent 0x%llx-0x%llx", pext.bno, pext.blkcount); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ if (pext.refcnt == 1) { ++ new_base = pext.bno; ++ new_blkcnt = extent->phys_block_num + blkcnt - new_base; ++ ret = apfs_extend_phys_extent(query, new_base, new_blkcnt, dstream->ds_id); ++ if (ret) ++ apfs_err(sb, "update failed for paddr 0x%llx", new_base); ++ } else { ++ /* ++ * We can't extend this one, because it would extend the other ++ * references as well. ++ */ ++ new_base = pext.bno + pext.blkcount; ++ new_blkcnt = extent->phys_block_num + blkcnt - new_base; ++ ret = apfs_insert_new_phys_extent(query, new_base, new_blkcnt, dstream->ds_id); ++ if (ret) ++ apfs_err(sb, "insertion failed for paddr 0x%llx", new_base); ++ } ++ ++out: ++ apfs_free_query(query); ++ apfs_node_free(extref_root); ++ return ret; ++} ++ ++/** ++ * apfs_phys_ext_from_query - Read the physical extent record found by a query ++ * @query: the (successful) query that found the record ++ * @pext: on return, the physical extent read ++ * ++ * Reads the physical extent record into @pext and performs some basic sanity ++ * checks as a protection against crafted filesystems. Returns 0 on success or ++ * -EFSCORRUPTED otherwise. ++ */ ++static int apfs_phys_ext_from_query(struct apfs_query *query, struct apfs_phys_extent *pext) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_phys_ext_key *key; ++ struct apfs_phys_ext_val *val; ++ char *raw = query->node->object.data; ++ ++ if (query->len != sizeof(*val) || query->key_len != sizeof(*key)) { ++ apfs_err(sb, "bad length of key (%d) or value (%d)", query->key_len, query->len); ++ return -EFSCORRUPTED; ++ } ++ ++ key = (struct apfs_phys_ext_key *)(raw + query->key_off); ++ val = (struct apfs_phys_ext_val *)(raw + query->off); ++ ++ pext->bno = apfs_cat_cnid(&key->hdr); ++ pext->blkcount = le64_to_cpu(val->len_and_kind) & APFS_PEXT_LEN_MASK; ++ pext->len = pext->blkcount << sb->s_blocksize_bits; ++ pext->refcnt = le32_to_cpu(val->refcnt); ++ pext->kind = le64_to_cpu(val->len_and_kind) >> APFS_PEXT_KIND_SHIFT; ++ return 0; ++} ++ ++/** ++ * apfs_free_phys_ext - Add all blocks in a physical extent to the free queue ++ * @sb: superblock structure ++ * @pext: physical range to free ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_free_phys_ext(struct super_block *sb, struct apfs_phys_extent *pext) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, -pext->blkcount); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_freed, pext->blkcount); ++ ++ return apfs_free_queue_insert(sb, pext->bno, pext->blkcount); ++} ++ ++/** ++ * apfs_put_phys_extent - Reduce the reference count for a physical extent ++ * @pext: physical extent data, already read ++ * @query: query that found the extent ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_put_phys_extent(struct apfs_phys_extent *pext, struct apfs_query *query) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_phys_ext_val *val; ++ void *raw; ++ int err; ++ ++ if (--pext->refcnt == 0) { ++ err = apfs_btree_remove(query); ++ if (err) { ++ apfs_err(sb, "removal failed for paddr 0x%llx", pext->bno); ++ return err; ++ } ++ return pext->kind == APFS_KIND_NEW ? apfs_free_phys_ext(sb, pext) : 0; ++ } ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ val = raw + query->off; ++ val->refcnt = cpu_to_le32(pext->refcnt); ++ return 0; ++} ++ ++/** ++ * apfs_take_phys_extent - Increase the reference count for a physical extent ++ * @pext: physical extent data, already read ++ * @query: query that found the extent ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_take_phys_extent(struct apfs_phys_extent *pext, struct apfs_query *query) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_phys_ext_val *val; ++ void *raw; ++ int err; ++ ++ /* An update extent may be dropped when a reference is taken */ ++ if (++pext->refcnt == 0) ++ return apfs_btree_remove(query); ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ val = raw + query->off; ++ val->refcnt = cpu_to_le32(pext->refcnt); ++ return 0; ++} ++ ++/** ++ * apfs_set_phys_ext_length - Set new length in a physical extent record's value ++ * @pext: the physical extent record's value ++ * @len: the new length (in blocks) ++ * ++ * Preserves the kind, though I doubt that's the right thing to do in general. ++ */ ++static inline void apfs_set_phys_ext_length(struct apfs_phys_ext_val *pext, u64 len) ++{ ++ u64 len_and_kind = le64_to_cpu(pext->len_and_kind); ++ u64 kind = len_and_kind & APFS_PEXT_KIND_MASK; ++ ++ pext->len_and_kind = cpu_to_le64(kind | len); ++} ++ ++/** ++ * apfs_split_phys_ext - Break a physical extent in two ++ * @query: query pointing to the extent ++ * @div: first physical block number to come after the division ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_split_phys_ext(struct apfs_query *query, u64 div) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_phys_ext_val *val1; ++ struct apfs_phys_ext_key key2; ++ struct apfs_phys_ext_val val2; ++ struct apfs_phys_extent pextent; ++ u64 blkcount1, blkcount2; ++ void *raw; ++ int err = 0; ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ ++ err = apfs_phys_ext_from_query(query, &pextent); ++ if (err) { ++ apfs_err(sb, "bad pext record over div 0x%llx", div); ++ return err; ++ } ++ val1 = raw + query->off; ++ val2 = *(struct apfs_phys_ext_val *)(raw + query->off); ++ key2 = *(struct apfs_phys_ext_key *)(raw + query->key_off); ++ ++ blkcount1 = div - pextent.bno; ++ blkcount2 = pextent.blkcount - blkcount1; ++ ++ /* Modify the current extent in place to become the first half */ ++ apfs_set_phys_ext_length(val1, blkcount1); ++ ++ /* Insert the second half right after the first */ ++ apfs_key_set_hdr(APFS_TYPE_EXTENT, div, &key2); ++ apfs_set_phys_ext_length(&val2, blkcount2); ++ return apfs_btree_insert(query, &key2, sizeof(key2), &val2, sizeof(val2)); ++} ++ ++/** ++ * apfs_create_update_pext - Create a reference update physical extent record ++ * @query: query that searched for the physical extent ++ * @extent: range of physical blocks to update ++ * @diff: reference count change ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_update_pext(struct apfs_query *query, const struct apfs_file_extent *extent, u32 diff) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_phys_ext_key key = {0}; ++ struct apfs_phys_ext_val val = {0}; ++ ++ apfs_key_set_hdr(APFS_TYPE_EXTENT, extent->phys_block_num, &key); ++ val.len_and_kind = cpu_to_le64((u64)APFS_KIND_UPDATE << APFS_PEXT_KIND_SHIFT | extent->len >> sb->s_blocksize_bits); ++ val.owning_obj_id = cpu_to_le64(APFS_OWNING_OBJ_ID_INVALID); ++ val.refcnt = cpu_to_le32(diff); ++ return apfs_btree_insert(query, &key, sizeof(key), &val, sizeof(val)); ++} ++ ++/** ++ * apfs_dstream_cache_is_tail - Is the tail of this dstream in its extent cache? ++ * @dstream: dstream to check ++ */ ++static inline bool apfs_dstream_cache_is_tail(struct apfs_dstream_info *dstream) ++{ ++ struct apfs_file_extent *cache = &dstream->ds_cached_ext; ++ ++ /* nx_big_sem provides the locking for the cache here */ ++ return cache->len && (dstream->ds_size <= cache->logical_addr + cache->len); ++} ++ ++/** ++ * apfs_flush_extent_cache - Write the cached extent to the catalog, if dirty ++ * @dstream: data stream to flush ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_flush_extent_cache(struct apfs_dstream_info *dstream) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_file_extent *ext = &dstream->ds_cached_ext; ++ int err; ++ ++ if (!dstream->ds_ext_dirty) ++ return 0; ++ ASSERT(ext->len > 0); ++ ++ err = apfs_update_extent(dstream, ext); ++ if (err) { ++ apfs_err(sb, "extent update failed"); ++ return err; ++ } ++ err = apfs_insert_phys_extent(dstream, ext); ++ if (err) { ++ apfs_err(sb, "pext insertion failed"); ++ return err; ++ } ++ ++ /* ++ * TODO: keep track of the byte and block count through the use of ++ * inode_add_bytes() and inode_set_bytes(). This hasn't been done with ++ * care in the rest of the module and it doesn't seem to matter beyond ++ * stat(), so I'm ignoring it for now. ++ */ ++ ++ dstream->ds_ext_dirty = false; ++ return 0; ++} ++ ++/** ++ * apfs_create_hole - Create and insert a hole extent for the dstream ++ * @dstream: data stream info ++ * @start: first logical block number for the hole ++ * @end: first logical block number right after the hole ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ * TODO: what happens to the crypto refcount? ++ */ ++static int apfs_create_hole(struct apfs_dstream_info *dstream, u64 start, u64 end) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_file_extent_key raw_key; ++ struct apfs_file_extent_val raw_val; ++ u64 extent_id = dstream->ds_id; ++ int ret; ++ ++ if (start == end) ++ return 0; ++ ++ /* File extent records use addresses, not block numbers */ ++ start <<= sb->s_blocksize_bits; ++ end <<= sb->s_blocksize_bits; ++ ++ apfs_key_set_hdr(APFS_TYPE_FILE_EXTENT, extent_id, &raw_key); ++ raw_key.logical_addr = cpu_to_le64(start); ++ raw_val.len_and_flags = cpu_to_le64(end - start); ++ raw_val.phys_block_num = cpu_to_le64(0); /* It's a hole... */ ++ raw_val.crypto_id = cpu_to_le64(apfs_vol_is_encrypted(sb) ? extent_id : 0); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_file_extent_key(extent_id, start, &query->key); ++ query->flags = APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for id 0x%llx, addr 0x%llx", extent_id, start); ++ goto out; ++ } ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", extent_id, start); ++ dstream->ds_sparse_bytes += end - start; ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_zero_dstream_tail - Zero out stale bytes in a data stream's last block ++ * @dstream: data stream info ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_zero_dstream_tail(struct apfs_dstream_info *dstream) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct inode *inode = NULL; ++ struct page *page = NULL; ++ void *fsdata = NULL; ++ int valid_length; ++ int err; ++ ++ /* No stale bytes if no actual content */ ++ if (dstream->ds_size <= dstream->ds_sparse_bytes) ++ return 0; ++ ++ /* No stale tail if the last block is fully used */ ++ valid_length = dstream->ds_size & (sb->s_blocksize - 1); ++ if (valid_length == 0) ++ return 0; ++ ++ inode = dstream->ds_inode; ++ if (!inode) { ++ /* This should never happen, but be safe */ ++ apfs_alert(sb, "attempt to zero the tail of xattr dstream 0x%llx", dstream->ds_id); ++ return -EFSCORRUPTED; ++ } ++ ++ /* This will take care of the CoW and zeroing */ ++ err = __apfs_write_begin(NULL, inode->i_mapping, inode->i_size, 0, 0, &page, &fsdata); ++ if (err) ++ return err; ++ return __apfs_write_end(NULL, inode->i_mapping, inode->i_size, 0, 0, page, fsdata); ++} ++ ++/** ++ * apfs_zero_bh_tail - Zero out stale bytes in a buffer head ++ * @sb: filesystem superblock ++ * @bh: buffer head to zero ++ * @length: length of valid bytes to be left alone ++ */ ++static void apfs_zero_bh_tail(struct super_block *sb, struct buffer_head *bh, u64 length) ++{ ++ ASSERT(buffer_trans(bh)); ++ if (length < sb->s_blocksize) ++ memset(bh->b_data + length, 0, sb->s_blocksize - length); ++} ++ ++/** ++ * apfs_range_in_snap - Check if a given block range overlaps a snapshot ++ * @sb: filesystem superblock ++ * @bno: first block in the range ++ * @blkcnt: block count for the range ++ * @in_snap: on return, the result ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_range_in_snap(struct super_block *sb, u64 bno, u64 blkcnt, bool *in_snap) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_node *extref_root = NULL; ++ struct apfs_query *query = NULL; ++ struct apfs_phys_extent pext = {0}; ++ int ret; ++ ++ /* Avoid the tree queries when we don't even have snapshots */ ++ if (vsb_raw->apfs_num_snapshots == 0) { ++ *in_snap = false; ++ return 0; ++ } ++ ++ /* ++ * Now check if the current physical extent tree has an entry for ++ * these blocks ++ */ ++ extref_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_extentref_tree_oid), APFS_OBJ_PHYSICAL, false /* write */); ++ if (IS_ERR(extref_root)) { ++ apfs_err(sb, "failed to read extref root 0x%llx", le64_to_cpu(vsb_raw->apfs_extentref_tree_oid)); ++ return PTR_ERR(extref_root); ++ } ++ ++ query = apfs_alloc_query(extref_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ apfs_init_extent_key(bno, &query->key); ++ query->flags = APFS_QUERY_EXTENTREF; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for paddr 0x%llx", bno); ++ goto out; ++ } ++ if (ret == -ENODATA) { ++ *in_snap = false; ++ ret = 0; ++ goto out; ++ } ++ ++ ret = apfs_phys_ext_from_query(query, &pext); ++ if (ret) { ++ apfs_err(sb, "bad pext record for paddr 0x%llx", bno); ++ goto out; ++ } ++ ++ if (pext.bno <= bno && pext.bno + pext.blkcount >= bno + blkcnt) { ++ if (pext.kind == APFS_KIND_NEW) { ++ *in_snap = false; ++ goto out; ++ } ++ } ++ ++ /* ++ * I think the file extent could still be covered by two different ++ * physical extents from the current tree, but it's easier to just ++ * assume the worst here. ++ */ ++ *in_snap = true; ++ ++out: ++ apfs_free_query(query); ++ apfs_node_free(extref_root); ++ return ret; ++} ++ ++/** ++ * apfs_dstream_cache_in_snap - Check if the cached extent overlaps a snapshot ++ * @dstream: the data stream to check ++ * @in_snap: on return, the result ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_dstream_cache_in_snap(struct apfs_dstream_info *dstream, bool *in_snap) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_file_extent *cache = NULL; ++ ++ /* All changes to extents get flushed when a snaphot is created */ ++ if (dstream->ds_ext_dirty) { ++ *in_snap = false; ++ return 0; ++ } ++ ++ cache = &dstream->ds_cached_ext; ++ return apfs_range_in_snap(sb, cache->phys_block_num, cache->len >> sb->s_blocksize_bits, in_snap); ++} ++ ++/** ++ * apfs_dstream_get_new_block - Like the get_block_t function, but for dstreams ++ * @dstream: data stream info ++ * @dsblock: logical dstream block to map ++ * @bh_result: buffer head to map (NULL if none) ++ * @bno: if not NULL, the new block number is returned here ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_dstream_get_new_block(struct apfs_dstream_info *dstream, u64 dsblock, struct buffer_head *bh_result, u64 *bno) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_file_extent *cache = NULL; ++ u64 phys_bno, logical_addr, cache_blks, dstream_blks; ++ bool in_snap = true; ++ int err; ++ ++ /* TODO: preallocate tail blocks */ ++ logical_addr = dsblock << sb->s_blocksize_bits; ++ ++ err = apfs_spaceman_allocate_block(sb, &phys_bno, false /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ return err; ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, 1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_alloced, 1); ++ if (bno) ++ *bno = phys_bno; ++ ++ if (bh_result) { ++ apfs_map_bh(bh_result, sb, phys_bno); ++ err = apfs_transaction_join(sb, bh_result); ++ if (err) ++ return err; ++ ++ if (!buffer_uptodate(bh_result)) { ++ /* ++ * Truly new buffers need to be marked as such, to get ++ * zeroed; this also takes care of holes in sparse files ++ */ ++ set_buffer_new(bh_result); ++ } else if (dstream->ds_size > logical_addr) { ++ /* ++ * The last block may have stale data left from a ++ * truncation ++ */ ++ apfs_zero_bh_tail(sb, bh_result, dstream->ds_size - logical_addr); ++ } ++ } ++ ++ dstream_blks = apfs_size_to_blocks(sb, dstream->ds_size); ++ if (dstream_blks < dsblock) { ++ /* ++ * This recurses into apfs_dstream_get_new_block() and dirties ++ * the extent cache, so it must happen before flushing it. ++ */ ++ err = apfs_zero_dstream_tail(dstream); ++ if (err) { ++ apfs_err(sb, "failed to zero tail for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ } ++ ++ err = apfs_dstream_cache_in_snap(dstream, &in_snap); ++ if (err) ++ return err; ++ ++ cache = &dstream->ds_cached_ext; ++ cache_blks = apfs_size_to_blocks(sb, cache->len); ++ ++ /* TODO: allow dirty caches of several blocks in the middle of a file */ ++ if (!in_snap && apfs_dstream_cache_is_tail(dstream) && ++ logical_addr == cache->logical_addr + cache->len && ++ phys_bno == cache->phys_block_num + cache_blks) { ++ cache->len += sb->s_blocksize; ++ dstream->ds_ext_dirty = true; ++ return 0; ++ } ++ ++ err = apfs_flush_extent_cache(dstream); ++ if (err) { ++ apfs_err(sb, "extent cache flush failed for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ ++ if (dstream_blks < dsblock) { ++ /* ++ * This puts new extents after the reported end of the file, so ++ * it must happen after the flush to avoid conflict with those ++ * extent operations. ++ */ ++ err = apfs_create_hole(dstream, dstream_blks, dsblock); ++ if (err) { ++ apfs_err(sb, "hole creation failed for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ } ++ ++ cache->logical_addr = logical_addr; ++ cache->phys_block_num = phys_bno; ++ cache->len = sb->s_blocksize; ++ dstream->ds_ext_dirty = true; ++ return 0; ++} ++ ++/** ++ * apfs_dstream_get_new_bno - Allocate a new block inside a dstream ++ * @dstream: data stream info ++ * @dsblock: logical dstream block to allocate ++ * @bno: on return, the new block number ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_dstream_get_new_bno(struct apfs_dstream_info *dstream, u64 dsblock, u64 *bno) ++{ ++ return apfs_dstream_get_new_block(dstream, dsblock, NULL /* bh_result */, bno); ++} ++ ++int apfs_get_new_block(struct inode *inode, sector_t iblock, ++ struct buffer_head *bh_result, int create) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ ++ ASSERT(create); ++ return apfs_dstream_get_new_block(&ai->i_dstream, iblock, bh_result, NULL /* bno */); ++} ++ ++/** ++ * apfs_shrink_dstream_last_extent - Shrink last extent of dstream being resized ++ * @dstream: data stream info ++ * @new_size: new size for the whole data stream ++ * ++ * Deletes, shrinks or zeroes the last extent, as needed for the truncation of ++ * the data stream. ++ * ++ * Only works with the last extent, so it needs to be called repeatedly to ++ * complete the truncation. Returns -EAGAIN in that case, or 0 when the process ++ * is complete. Returns other negative error codes in case of failure. ++ */ ++static int apfs_shrink_dstream_last_extent(struct apfs_dstream_info *dstream, loff_t new_size) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_file_extent tail; ++ u64 extent_id = dstream->ds_id; ++ int ret = 0; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_file_extent_key(extent_id, -1, &query->key); ++ query->flags = APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for last extent of id 0x%llx", extent_id); ++ goto out; ++ } ++ ++ if (!apfs_query_found_extent(query)) { ++ /* No more extents, we deleted the whole file already? */ ++ if (new_size) { ++ apfs_err(sb, "missing extent for dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; ++ } else { ++ ret = 0; ++ } ++ goto out; ++ } ++ ++ ret = apfs_extent_from_query(query, &tail); ++ if (ret) { ++ apfs_err(sb, "bad tail extent record on dstream 0x%llx", extent_id); ++ goto out; ++ } ++ ++ if (tail.logical_addr + tail.len < new_size) { ++ apfs_err(sb, "missing extent for dstream 0x%llx", extent_id); ++ ret = -EFSCORRUPTED; /* Tail extent missing */ ++ } else if (tail.logical_addr + tail.len == new_size) { ++ ret = 0; /* Nothing more to be done */ ++ } else if (tail.logical_addr >= new_size) { ++ /* This whole extent needs to go */ ++ ret = apfs_btree_remove(query); ++ if (ret) { ++ apfs_err(sb, "removal failed for id 0x%llx, addr 0x%llx", dstream->ds_id, tail.logical_addr); ++ goto out; ++ } ++ if (apfs_ext_is_hole(&tail)) { ++ dstream->ds_sparse_bytes -= tail.len; ++ } else { ++ ret = apfs_range_put_reference(sb, tail.phys_block_num, tail.len); ++ if (ret) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", tail.phys_block_num, tail.len); ++ goto out; ++ } ++ } ++ ret = apfs_crypto_adj_refcnt(sb, tail.crypto_id, -1); ++ if (ret) { ++ apfs_err(sb, "failed to take crypto id 0x%llx", tail.crypto_id); ++ goto out; ++ } ++ ret = tail.logical_addr == new_size ? 0 : -EAGAIN; ++ } else { ++ /* ++ * The file is being truncated in the middle of this extent. ++ * TODO: preserve the physical tail to be overwritten later. ++ */ ++ new_size = apfs_size_to_blocks(sb, new_size) << sb->s_blocksize_bits; ++ ret = apfs_shrink_extent_tail(query, dstream, new_size); ++ if (ret) ++ apfs_err(sb, "failed to shrink tail of dstream 0x%llx", extent_id); ++ } ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_shrink_dstream - Shrink a data stream's extents to a new length ++ * @dstream: data stream info ++ * @new_size: the new size ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_shrink_dstream(struct apfs_dstream_info *dstream, loff_t new_size) ++{ ++ int ret; ++ ++ do { ++ ret = apfs_shrink_dstream_last_extent(dstream, new_size); ++ } while (ret == -EAGAIN); ++ ++ return ret; ++} ++ ++/** ++ * apfs_truncate - Truncate a data stream's content ++ * @dstream: data stream info ++ * @new_size: the new size ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_truncate(struct apfs_dstream_info *dstream, loff_t new_size) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ u64 old_blks, new_blks; ++ struct apfs_file_extent *cache = &dstream->ds_cached_ext; ++ int err; ++ ++ /* TODO: don't write the cached extent if it will be deleted */ ++ err = apfs_flush_extent_cache(dstream); ++ if (err) { ++ apfs_err(sb, "extent cache flush failed for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ dstream->ds_ext_dirty = false; ++ ++ /* TODO: keep the cache valid on truncation */ ++ cache->len = 0; ++ ++ /* "<=", because a partial write may have left extents beyond the end */ ++ if (new_size <= dstream->ds_size) ++ return apfs_shrink_dstream(dstream, new_size); ++ ++ err = apfs_zero_dstream_tail(dstream); ++ if (err) { ++ apfs_err(sb, "failed to zero tail for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ new_blks = apfs_size_to_blocks(sb, new_size); ++ old_blks = apfs_size_to_blocks(sb, dstream->ds_size); ++ return apfs_create_hole(dstream, old_blks, new_blks); ++} ++ ++/** ++ * apfs_dstream_delete_front - Deletes as many leading extents as possible ++ * @sb: filesystem superblock ++ * @ds_id: id for the dstream to delete ++ * ++ * Returns 0 on success, or a negative error code in case of failure, which may ++ * be -ENODATA if there are no more extents, or -EAGAIN if the free queue is ++ * getting too full. ++ */ ++static int apfs_dstream_delete_front(struct super_block *sb, u64 ds_id) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_spaceman_free_queue *fq = NULL; ++ struct apfs_query *query = NULL; ++ struct apfs_file_extent head; ++ bool first_match = true; ++ int ret; ++ ++ fq = &sm_raw->sm_fq[APFS_SFQ_MAIN]; ++ if (le64_to_cpu(fq->sfq_count) > APFS_TRANS_MAIN_QUEUE_MAX) ++ return -EAGAIN; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_file_extent_key(ds_id, 0, &query->key); ++ query->flags = APFS_QUERY_CAT; ++ ++next_extent: ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for first extent of id 0x%llx", ds_id); ++ goto out; ++ } ++ apfs_query_direct_forward(query); ++ if (!apfs_query_found_extent(query)) { ++ /* ++ * After the original lookup, the query may not be set to the ++ * first extent, but instead to the record that comes right ++ * before. ++ */ ++ if (first_match) { ++ first_match = false; ++ goto next_extent; ++ } ++ ret = -ENODATA; ++ goto out; ++ } ++ first_match = false; ++ ++ ret = apfs_extent_from_query(query, &head); ++ if (ret) { ++ apfs_err(sb, "bad head extent record on dstream 0x%llx", ds_id); ++ goto out; ++ } ++ ret = apfs_btree_remove(query); ++ if (ret) { ++ apfs_err(sb, "removal failed for id 0x%llx, addr 0x%llx", ds_id, head.logical_addr); ++ goto out; ++ } ++ ++ /* ++ * The official fsck doesn't complain about wrong sparse byte counts ++ * for orphans, so I guess we don't need to update them here ++ */ ++ if (!apfs_ext_is_hole(&head)) { ++ ret = apfs_range_put_reference(sb, head.phys_block_num, head.len); ++ if (ret) { ++ apfs_err(sb, "failed to put range 0x%llx-0x%llx", head.phys_block_num, head.len); ++ goto out; ++ } ++ ret = apfs_crypto_adj_refcnt(sb, head.crypto_id, -1); ++ if (ret) { ++ apfs_err(sb, "failed to take crypto id 0x%llx", head.crypto_id); ++ goto out; ++ } ++ } ++ ++ if (le64_to_cpu(fq->sfq_count) <= APFS_TRANS_MAIN_QUEUE_MAX) ++ goto next_extent; ++ ret = -EAGAIN; ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_inode_delete_front - Deletes as many leading extents as possible ++ * @inode: inode to delete ++ * ++ * Tries to delete all extents for @inode, in which case it returns 0. If the ++ * free queue is getting too full, deletes as much as is reasonable and returns ++ * -EAGAIN. May return other negative error codes as well. ++ */ ++int apfs_inode_delete_front(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_dstream_info *dstream = NULL; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ int ret; ++ ++ if (!ai->i_has_dstream) ++ return 0; ++ ++ dstream = &ai->i_dstream; ++ ret = apfs_flush_extent_cache(dstream); ++ if (ret) { ++ apfs_err(sb, "extent cache flush failed for dstream 0x%llx", dstream->ds_id); ++ return ret; ++ } ++ ++ ret = apfs_dstream_delete_front(sb, dstream->ds_id); ++ if (ret == -ENODATA) ++ return 0; ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) ++loff_t apfs_remap_file_range(struct file *src_file, loff_t off, struct file *dst_file, loff_t destoff, loff_t len, unsigned int remap_flags) ++#else ++int apfs_clone_file_range(struct file *src_file, loff_t off, struct file *dst_file, loff_t destoff, u64 len) ++#endif ++{ ++ struct inode *src_inode = file_inode(src_file); ++ struct inode *dst_inode = file_inode(dst_file); ++ struct apfs_inode_info *src_ai = APFS_I(src_inode); ++ struct apfs_inode_info *dst_ai = APFS_I(dst_inode); ++ struct apfs_dstream_info *src_ds = &src_ai->i_dstream; ++ struct apfs_dstream_info *dst_ds = &dst_ai->i_dstream; ++ struct super_block *sb = src_inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ const u64 xfield_flags = APFS_INODE_MAINTAIN_DIR_STATS | APFS_INODE_IS_SPARSE | APFS_INODE_HAS_PURGEABLE_FLAGS; ++ int err; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) ++ if (remap_flags & ~(REMAP_FILE_ADVISORY)) ++ return -EINVAL; ++#endif ++ if (src_inode == dst_inode) ++ return -EINVAL; ++ ++ /* We only want to clone whole files, like in the official driver */ ++ if (off != 0 || destoff != 0 || len != 0) ++ return -EINVAL; ++ ++ /* ++ * Clones here work in two steps: first the user creates an empty target ++ * file, and then the user calls the ioctl, which replaces the file with ++ * a clone. This is not atomic, of course. ++ */ ++ if (dst_ai->i_has_dstream || dst_ai->i_bsd_flags & APFS_INOBSD_COMPRESSED) { ++ apfs_warn(sb, "clones can only replace freshly created files"); ++ return -EOPNOTSUPP; ++ } ++ if (dst_ai->i_int_flags & xfield_flags) { ++ apfs_warn(sb, "clone can't replace a file that has xfields"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (!src_ai->i_has_dstream) { ++ apfs_warn(sb, "can't clone a file with no dstream"); ++ return -EOPNOTSUPP; ++ } ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ apfs_inode_join_transaction(sb, src_inode); ++ apfs_inode_join_transaction(sb, dst_inode); ++ ++ err = apfs_flush_extent_cache(src_ds); ++ if (err) { ++ apfs_err(sb, "extent cache flush failed for dstream 0x%llx", src_ds->ds_id); ++ goto fail; ++ } ++ err = apfs_dstream_adj_refcnt(src_ds, +1); ++ if (err) { ++ apfs_err(sb, "failed to take dstream id 0x%llx", src_ds->ds_id); ++ goto fail; ++ } ++ src_ds->ds_shared = true; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ dst_inode->i_mtime = dst_inode->i_ctime = current_time(dst_inode); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ dst_inode->i_mtime = inode_set_ctime_current(dst_inode); ++#else ++ inode_set_mtime_to_ts(dst_inode, inode_set_ctime_current(dst_inode)); ++#endif ++ dst_inode->i_size = src_inode->i_size; ++ dst_ai->i_key_class = src_ai->i_key_class; ++ dst_ai->i_int_flags = src_ai->i_int_flags; ++ dst_ai->i_bsd_flags = src_ai->i_bsd_flags; ++ dst_ai->i_has_dstream = true; ++ ++ dst_ds->ds_sb = src_ds->ds_sb; ++ dst_ds->ds_inode = dst_inode; ++ dst_ds->ds_id = src_ds->ds_id; ++ dst_ds->ds_size = src_ds->ds_size; ++ dst_ds->ds_sparse_bytes = src_ds->ds_sparse_bytes; ++ dst_ds->ds_cached_ext = src_ds->ds_cached_ext; ++ dst_ds->ds_ext_dirty = false; ++ dst_ds->ds_shared = true; ++ ++ dst_ai->i_int_flags |= APFS_INODE_WAS_EVER_CLONED | APFS_INODE_WAS_CLONED; ++ src_ai->i_int_flags |= APFS_INODE_WAS_EVER_CLONED; ++ ++ /* ++ * The sparse flag is the important one here: if we need it, it will get ++ * set later by apfs_update_inode(), after the xfield gets created. ++ */ ++ dst_ai->i_int_flags &= ~xfield_flags; ++ ++ /* ++ * Commit the transaction to make sure all buffers in the source inode ++ * go through copy-on-write. This is a bit excessive, but I don't expect ++ * clones to be created often enough for it to matter. ++ */ ++ sbi->s_nxi->nx_transaction.t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return dst_ds->ds_size; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_extent_create_record - Create a logical extent record for a dstream id ++ * @sb: filesystem superblock ++ * @dstream_id: the dstream id ++ * @extent: extent info for the record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_extent_create_record(struct super_block *sb, u64 dstream_id, struct apfs_file_extent *extent) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_file_extent_val raw_val; ++ struct apfs_file_extent_key raw_key; ++ int ret = 0; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_file_extent_key(dstream_id, extent->logical_addr, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for id 0x%llx, addr 0x%llx", dstream_id, extent->logical_addr); ++ goto out; ++ } ++ ++ apfs_key_set_hdr(APFS_TYPE_FILE_EXTENT, dstream_id, &raw_key); ++ raw_key.logical_addr = cpu_to_le64(extent->logical_addr); ++ raw_val.len_and_flags = cpu_to_le64(extent->len); ++ raw_val.phys_block_num = cpu_to_le64(extent->phys_block_num); ++ raw_val.crypto_id = cpu_to_le64(apfs_vol_is_encrypted(sb) ? dstream_id : 0); /* TODO */ ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "insertion failed for id 0x%llx, addr 0x%llx", dstream_id, extent->logical_addr); ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_put_single_extent - Put a reference to a single extent ++ * @sb: filesystem superblock ++ * @paddr_end: first block after the extent to put ++ * @paddr_min: don't put references before this block ++ * ++ * Puts a reference to the physical extent range that ends in @paddr_end. Sets ++ * @paddr_end to the beginning of the extent, so that the caller can continue ++ * with the previous one. Returns 0 on success, or a negative error code in ++ * case of failure. ++ * ++ * TODO: unify this with apfs_take_single_extent(), they are almost the same. ++ */ ++static int apfs_put_single_extent(struct super_block *sb, u64 *paddr_end, u64 paddr_min) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_node *extref_root = NULL; ++ struct apfs_key key; ++ struct apfs_query *query = NULL; ++ struct apfs_phys_extent prev_ext; ++ u64 prev_start, prev_end; ++ bool cropped_head = false, cropped_tail = false; ++ struct apfs_file_extent tmp = {0}; /* TODO: clean up all the fake extent interfaces? */ ++ int ret; ++ ++ extref_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_extentref_tree_oid), APFS_OBJ_PHYSICAL, true /* write */); ++ if (IS_ERR(extref_root)) { ++ apfs_err(sb, "failed to read extref root 0x%llx", le64_to_cpu(vsb_raw->apfs_extentref_tree_oid)); ++ return PTR_ERR(extref_root); ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_extentref_tree_oid = cpu_to_le64(extref_root->object.oid); ++ ++ apfs_init_extent_key(*paddr_end - 1, &key); ++ ++restart: ++ query = apfs_alloc_query(extref_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ query->key = key; ++ query->flags = APFS_QUERY_EXTENTREF; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for paddr 0x%llx", *paddr_end - 1); ++ goto out; ++ } ++ ++ if (ret == -ENODATA) { ++ /* The whole range to put is part of a snapshot */ ++ tmp.phys_block_num = paddr_min; ++ tmp.len = (*paddr_end - paddr_min) << sb->s_blocksize_bits; ++ ret = apfs_create_update_pext(query, &tmp, -1); ++ *paddr_end = paddr_min; ++ goto out; ++ } ++ ++ ret = apfs_phys_ext_from_query(query, &prev_ext); ++ if (ret) { ++ apfs_err(sb, "bad pext record over paddr 0x%llx", *paddr_end - 1); ++ goto out; ++ } ++ prev_start = prev_ext.bno; ++ prev_end = prev_ext.bno + prev_ext.blkcount; ++ if (prev_end < *paddr_end) { ++ /* The extent to put is part of a snapshot */ ++ tmp.phys_block_num = max(prev_end, paddr_min); ++ tmp.len = (*paddr_end - tmp.phys_block_num) << sb->s_blocksize_bits; ++ ret = apfs_create_update_pext(query, &tmp, -1); ++ *paddr_end = tmp.phys_block_num; ++ goto out; ++ } ++ ++ if ((cropped_tail && prev_end > *paddr_end) || (cropped_head && prev_start < paddr_min)) { ++ /* This should never happen, but be safe */ ++ apfs_alert(sb, "recursion cropping physical extent 0x%llx-0x%llx", prev_start, prev_end); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ if (prev_end > *paddr_end) { ++ ret = apfs_split_phys_ext(query, *paddr_end); ++ if (ret) { ++ apfs_err(sb, "failed to split pext at 0x%llx", *paddr_end); ++ goto out; ++ } ++ /* The split may make the query invalid */ ++ apfs_free_query(query); ++ cropped_tail = true; ++ goto restart; ++ } ++ ++ if (prev_start < paddr_min) { ++ ret = apfs_split_phys_ext(query, paddr_min); ++ if (ret) { ++ apfs_err(sb, "failed to split pext at 0x%llx", paddr_min); ++ goto out; ++ } ++ /* The split may make the query invalid */ ++ apfs_free_query(query); ++ cropped_head = true; ++ goto restart; ++ } ++ ++ /* The extent to put already exists */ ++ ret = apfs_put_phys_extent(&prev_ext, query); ++ if (ret) ++ apfs_err(sb, "failed to put pext at 0x%llx", prev_ext.bno); ++ *paddr_end = prev_start; ++ ++out: ++ apfs_free_query(query); ++ apfs_node_free(extref_root); ++ return ret; ++} ++ ++/** ++ * apfs_range_put_reference - Put a reference to a physical range ++ * @sb: filesystem superblock ++ * @paddr: first block of the range ++ * @length: length of the range (in bytes) ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_range_put_reference(struct super_block *sb, u64 paddr, u64 length) ++{ ++ u64 extent_end; ++ int err; ++ ++ ASSERT(paddr); ++ ++ extent_end = paddr + (length >> sb->s_blocksize_bits); ++ while (extent_end > paddr) { ++ err = apfs_put_single_extent(sb, &extent_end, paddr); ++ if (err) ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_take_single_extent - Take a reference to a single extent ++ * @sb: filesystem superblock ++ * @paddr_end: first block after the extent to take ++ * @paddr_min: don't take references before this block ++ * ++ * Takes a reference to the physical extent range that ends in @paddr_end. Sets ++ * @paddr_end to the beginning of the extent, so that the caller can continue ++ * with the previous one. Returns 0 on success, or a negative error code in ++ * case of failure. ++ */ ++static int apfs_take_single_extent(struct super_block *sb, u64 *paddr_end, u64 paddr_min) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_node *extref_root = NULL; ++ struct apfs_key key; ++ struct apfs_query *query = NULL; ++ struct apfs_phys_extent prev_ext; ++ u64 prev_start, prev_end; ++ bool cropped_head = false, cropped_tail = false; ++ struct apfs_file_extent tmp = {0}; /* TODO: clean up all the fake extent interfaces? */ ++ int ret; ++ ++ extref_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_extentref_tree_oid), APFS_OBJ_PHYSICAL, true /* write */); ++ if (IS_ERR(extref_root)) { ++ apfs_err(sb, "failed to read extref root 0x%llx", le64_to_cpu(vsb_raw->apfs_extentref_tree_oid)); ++ return PTR_ERR(extref_root); ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_extentref_tree_oid = cpu_to_le64(extref_root->object.oid); ++ ++ apfs_init_extent_key(*paddr_end - 1, &key); ++ ++restart: ++ query = apfs_alloc_query(extref_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ query->key = key; ++ query->flags = APFS_QUERY_EXTENTREF; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for paddr 0x%llx", *paddr_end - 1); ++ goto out; ++ } ++ ++ if (ret == -ENODATA) { ++ /* The whole range to take is part of a snapshot */ ++ tmp.phys_block_num = paddr_min; ++ tmp.len = (*paddr_end - paddr_min) << sb->s_blocksize_bits; ++ ret = apfs_create_update_pext(query, &tmp, +1); ++ *paddr_end = paddr_min; ++ goto out; ++ } ++ ++ ret = apfs_phys_ext_from_query(query, &prev_ext); ++ if (ret) { ++ apfs_err(sb, "bad pext record over paddr 0x%llx", *paddr_end - 1); ++ goto out; ++ } ++ prev_start = prev_ext.bno; ++ prev_end = prev_ext.bno + prev_ext.blkcount; ++ if (prev_end < *paddr_end) { ++ /* The extent to take is part of a snapshot */ ++ tmp.phys_block_num = max(prev_end, paddr_min); ++ tmp.len = (*paddr_end - tmp.phys_block_num) << sb->s_blocksize_bits; ++ ret = apfs_create_update_pext(query, &tmp, +1); ++ *paddr_end = tmp.phys_block_num; ++ goto out; ++ } ++ ++ if ((cropped_tail && prev_end > *paddr_end) || (cropped_head && prev_start < paddr_min)) { ++ /* This should never happen, but be safe */ ++ apfs_alert(sb, "recursion cropping physical extent 0x%llx-0x%llx", prev_start, prev_end); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ if (prev_end > *paddr_end) { ++ ret = apfs_split_phys_ext(query, *paddr_end); ++ if (ret) { ++ apfs_err(sb, "failed to split pext at 0x%llx", *paddr_end); ++ goto out; ++ } ++ /* The split may make the query invalid */ ++ apfs_free_query(query); ++ cropped_tail = true; ++ goto restart; ++ } ++ ++ if (prev_start < paddr_min) { ++ ret = apfs_split_phys_ext(query, paddr_min); ++ if (ret) { ++ apfs_err(sb, "failed to split pext at 0x%llx", paddr_min); ++ goto out; ++ } ++ /* The split may make the query invalid */ ++ apfs_free_query(query); ++ cropped_head = true; ++ goto restart; ++ } ++ ++ /* The extent to take already exists */ ++ ret = apfs_take_phys_extent(&prev_ext, query); ++ if (ret) ++ apfs_err(sb, "failed to take pext at 0x%llx", prev_ext.bno); ++ *paddr_end = prev_start; ++ ++out: ++ apfs_free_query(query); ++ apfs_node_free(extref_root); ++ return ret; ++} ++ ++/** ++ * apfs_range_take_reference - Take a reference to a physical range ++ * @sb: filesystem superblock ++ * @paddr: first block of the range ++ * @length: length of the range (in bytes) ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_range_take_reference(struct super_block *sb, u64 paddr, u64 length) ++{ ++ u64 extent_end; ++ int err; ++ ++ ASSERT(paddr); ++ ++ extent_end = paddr + (length >> sb->s_blocksize_bits); ++ while (extent_end > paddr) { ++ err = apfs_take_single_extent(sb, &extent_end, paddr); ++ if (err) ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_clone_single_extent - Make a copy of an extent in a dstream to a new one ++ * @dstream: old dstream ++ * @new_id: id of the new dstream ++ * @log_addr: logical address for the extent ++ * ++ * Duplicates the logical extent, and updates the references to the physical ++ * extents as required. Sets @addr to the end of the extent, so that the caller ++ * can continue in the same place. Returns 0 on success, or a negative error ++ * code in case of failure. ++ */ ++static int apfs_clone_single_extent(struct apfs_dstream_info *dstream, u64 new_id, u64 *log_addr) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_file_extent extent; ++ int err; ++ ++ err = apfs_extent_read(dstream, *log_addr >> sb->s_blocksize_bits, &extent); ++ if (err) { ++ apfs_err(sb, "failed to read an extent to clone for dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ err = apfs_extent_create_record(sb, new_id, &extent); ++ if (err) { ++ apfs_err(sb, "failed to create extent record for clone of dstream 0x%llx", dstream->ds_id); ++ return err; ++ } ++ ++ if (!apfs_ext_is_hole(&extent)) { ++ err = apfs_range_take_reference(sb, extent.phys_block_num, extent.len); ++ if (err) { ++ apfs_err(sb, "failed to take a reference to physical range 0x%llx-0x%llx", extent.phys_block_num, extent.len); ++ return err; ++ } ++ } ++ ++ *log_addr += extent.len; ++ return 0; ++} ++ ++/** ++ * apfs_clone_extents - Make a copy of all extents in a dstream to a new one ++ * @dstream: old dstream ++ * @new_id: id for the new dstream ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_clone_extents(struct apfs_dstream_info *dstream, u64 new_id) ++{ ++ u64 next = 0; ++ int err; ++ ++ while (next < dstream->ds_size) { ++ err = apfs_clone_single_extent(dstream, new_id, &next); ++ if (err) ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_nonsparse_dstream_read - Read from a dstream without holes ++ * @dstream: dstream to read ++ * @buf: destination buffer ++ * @count: exact number of bytes to read ++ * @offset: dstream offset to read from ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_nonsparse_dstream_read(struct apfs_dstream_info *dstream, void *buf, size_t count, u64 offset) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ u64 logical_start_block, logical_end_block, log_bno, blkcnt, idx; ++ struct buffer_head **bhs = NULL; ++ int ret = 0; ++ ++ /* Save myself from thinking about overflow here */ ++ if (count >= APFS_MAX_FILE_SIZE || offset >= APFS_MAX_FILE_SIZE) { ++ apfs_err(sb, "dstream read overflow (0x%llx-0x%llx)", offset, (unsigned long long)count); ++ return -EFBIG; ++ } ++ ++ if (offset + count > dstream->ds_size) { ++ apfs_err(sb, "reading past the end (0x%llx-0x%llx)", offset, (unsigned long long)count); ++ /* No caller is expected to legitimately read out-of-bounds */ ++ return -EFSCORRUPTED; ++ } ++ ++ logical_start_block = offset >> sb->s_blocksize_bits; ++ logical_end_block = (offset + count + sb->s_blocksize - 1) >> sb->s_blocksize_bits; ++ blkcnt = logical_end_block - logical_start_block; ++ bhs = kcalloc(blkcnt, sizeof(*bhs), GFP_KERNEL); ++ if (!bhs) ++ return -ENOMEM; ++ ++ for (log_bno = logical_start_block; log_bno < logical_end_block; log_bno++) { ++ struct buffer_head *bh = NULL; ++ u64 bno = 0; ++ ++ idx = log_bno - logical_start_block; ++ ++ ret = apfs_logic_to_phys_bno(dstream, log_bno, &bno); ++ if (ret) ++ goto out; ++ if (bno == 0) { ++ apfs_err(sb, "nonsparse dstream has a hole"); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ bhs[idx] = __apfs_getblk(sb, bno); ++ if (!bhs[idx]) { ++ apfs_err(sb, "failed to map block 0x%llx", bno); ++ ret = -EIO; ++ goto out; ++ } ++ ++ bh = bhs[idx]; ++ if (!buffer_uptodate(bh)) { ++ get_bh(bh); ++ lock_buffer(bh); ++ bh->b_end_io = end_buffer_read_sync; ++ apfs_submit_bh(REQ_OP_READ, 0, bh); ++ } ++ } ++ ++ for (log_bno = logical_start_block; log_bno < logical_end_block; log_bno++) { ++ int off_in_block, left_in_block; ++ ++ idx = log_bno - logical_start_block; ++ wait_on_buffer(bhs[idx]); ++ if (!buffer_uptodate(bhs[idx])) { ++ apfs_err(sb, "failed to read a block"); ++ ret = -EIO; ++ goto out; ++ } ++ ++ if (log_bno == logical_start_block) ++ off_in_block = offset & (sb->s_blocksize - 1); ++ else ++ off_in_block = 0; ++ ++ if (log_bno == logical_end_block - 1) ++ left_in_block = count + offset - (log_bno << sb->s_blocksize_bits) - off_in_block; ++ else ++ left_in_block = sb->s_blocksize - off_in_block; ++ ++ memcpy(buf, bhs[idx]->b_data + off_in_block, left_in_block); ++ buf += left_in_block; ++ } ++ ++out: ++ if (bhs) { ++ for (idx = 0; idx < blkcnt; idx++) ++ brelse(bhs[idx]); ++ kfree(bhs); ++ } ++ return ret; ++} ++ ++/** ++ * apfs_nonsparse_dstream_preread - Attempt to preread a dstream without holes ++ * @dstream: dstream to preread ++ * ++ * Requests reads for all blocks of a dstream, but doesn't wait for the result. ++ */ ++void apfs_nonsparse_dstream_preread(struct apfs_dstream_info *dstream) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ u64 logical_end_block, log_bno; ++ ++ logical_end_block = (dstream->ds_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; ++ ++ for (log_bno = 0; log_bno < logical_end_block; log_bno++) { ++ struct buffer_head *bh = NULL; ++ u64 bno = 0; ++ int ret; ++ ++ ret = apfs_logic_to_phys_bno(dstream, log_bno, &bno); ++ if (ret || bno == 0) ++ return; ++ ++ bh = __apfs_getblk(sb, bno); ++ if (!bh) ++ return; ++ if (!buffer_uptodate(bh)) { ++ get_bh(bh); ++ lock_buffer(bh); ++ bh->b_end_io = end_buffer_read_sync; ++ apfs_submit_bh(REQ_OP_READ, 0, bh); ++ } ++ brelse(bh); ++ bh = NULL; ++ } ++} +diff --git a/fs/apfs/file.c b/fs/apfs/file.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/file.c +@@ -0,0 +1,224 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include "apfs.h" ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++#include ++#endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) ++typedef int vm_fault_t; ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) ++static void wait_for_stable_page(struct page *page) ++{ ++ return folio_wait_stable(page_folio(page)); ++} ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) ++static vm_fault_t apfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++#else ++static vm_fault_t apfs_page_mkwrite(struct vm_fault *vmf) ++{ ++ struct vm_area_struct *vma = vmf->vma; ++#endif ++ struct page *page = vmf->page; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) ++ struct folio *folio; ++#endif ++ struct inode *inode = file_inode(vma->vm_file); ++ struct super_block *sb = inode->i_sb; ++ struct buffer_head *bh, *head; ++ vm_fault_t ret = VM_FAULT_LOCKED; ++ unsigned int blocksize, block_start, len; ++ u64 size; ++ int err = 0; ++ ++ sb_start_pagefault(inode->i_sb); ++ file_update_time(vma->vm_file); ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ goto out; ++ apfs_inode_join_transaction(sb, inode); ++ ++ err = apfs_inode_create_exclusive_dstream(inode); ++ if (err) { ++ apfs_err(sb, "dstream creation failed for ino 0x%llx", apfs_ino(inode)); ++ goto out_abort; ++ } ++ ++ lock_page(page); ++ wait_for_stable_page(page); ++ if (page->mapping != inode->i_mapping) { ++ ret = VM_FAULT_NOPAGE; ++ goto out_unlock; ++ } ++ ++ if (!page_has_buffers(page)) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ create_empty_buffers(page, sb->s_blocksize, 0); ++#else ++ folio = page_folio(page); ++ bh = folio_buffers(folio); ++ if (!bh) ++ bh = create_empty_buffers(folio, sb->s_blocksize, 0); ++#endif ++ } ++ ++ size = i_size_read(inode); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) ++ if (page_folio(page)->index == size >> PAGE_SHIFT) ++#else ++ if (page->index == size >> PAGE_SHIFT) ++#endif ++ len = size & ~PAGE_MASK; ++ else ++ len = PAGE_SIZE; ++ ++ /* The blocks were read on the fault, mark them as unmapped for CoW */ ++ head = page_buffers(page); ++ blocksize = head->b_size; ++ for (bh = head, block_start = 0; bh != head || !block_start; ++ block_start += blocksize, bh = bh->b_this_page) { ++ if (len > block_start) { ++ /* If it's not a hole, the fault read it already */ ++ ASSERT(!buffer_mapped(bh) || buffer_uptodate(bh)); ++ if (buffer_trans(bh)) ++ continue; ++ clear_buffer_mapped(bh); ++ } ++ } ++ unlock_page(page); /* XXX: race? */ ++ ++ err = block_page_mkwrite(vma, vmf, apfs_get_new_block); ++ if (err) { ++ apfs_err(sb, "mkwrite failed for ino 0x%llx", apfs_ino(inode)); ++ goto out_abort; ++ } ++ set_page_dirty(page); ++ ++ /* An immediate commit would leave the page unlocked */ ++ APFS_SB(sb)->s_nxi->nx_transaction.t_state |= APFS_NX_TRANS_DEFER_COMMIT; ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto out_unlock; ++ goto out; ++ ++out_unlock: ++ unlock_page(page); ++out_abort: ++ apfs_transaction_abort(sb); ++out: ++ if (err) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && !RHEL_VERSION_GE(9, 5) ++ ret = block_page_mkwrite_return(err); ++#else ++ ret = vmf_fs_error(err); ++#endif ++ sb_end_pagefault(inode->i_sb); ++ return ret; ++} ++ ++static const struct vm_operations_struct apfs_file_vm_ops = { ++ .fault = filemap_fault, ++ .map_pages = filemap_map_pages, ++ .page_mkwrite = apfs_page_mkwrite, ++}; ++ ++int apfs_file_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ struct address_space *mapping = file->f_mapping; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ if (!mapping->a_ops->read_folio) ++#else ++ if (!mapping->a_ops->readpage) ++#endif ++ return -ENOEXEC; ++ file_accessed(file); ++ vma->vm_ops = &apfs_file_vm_ops; ++ return 0; ++} ++ ++/* ++ * Just flush the whole transaction for now (TODO), since that's technically ++ * correct and easy to implement. ++ */ ++int apfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) ++{ ++ struct inode *inode = file->f_mapping->host; ++ struct super_block *sb = inode->i_sb; ++ ++ return apfs_sync_fs(sb, true /* wait */); ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++static ssize_t apfs_copy_file_range(struct file *src_file, loff_t src_off, ++ struct file *dst_file, loff_t dst_off, ++ size_t len, unsigned int flags) ++{ ++ return (splice_copy_file_range(src_file, src_off, ++ dst_file, dst_off, len)); ++} ++#endif ++ ++const struct file_operations apfs_file_operations = { ++ .llseek = generic_file_llseek, ++ .read_iter = generic_file_read_iter, ++ .write_iter = generic_file_write_iter, ++ .mmap = apfs_file_mmap, ++ .open = generic_file_open, ++ .fsync = apfs_fsync, ++ .unlocked_ioctl = apfs_file_ioctl, ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++ .copy_file_range = apfs_copy_file_range, ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) ++ .copy_file_range = generic_copy_file_range, ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) ++ .remap_file_range = apfs_remap_file_range, ++#else ++ .clone_file_range = apfs_clone_file_range, ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) ++ .splice_read = generic_file_splice_read, ++#else ++ .splice_read = filemap_splice_read, ++#endif ++ .splice_write = iter_file_splice_write, ++}; ++ ++#if LINUX_VERSION_CODE == KERNEL_VERSION(5, 3, 0) ++/* ++ * This is needed mainly to test clones with xfstests, so we only support the ++ * kernel version I use during testing. TODO: support all kernel versions. ++ */ ++int apfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len) ++{ ++ return generic_block_fiemap(inode, fieinfo, start, len, apfs_get_block); ++} ++#endif ++ ++const struct inode_operations apfs_file_inode_operations = { ++ .getattr = apfs_getattr, ++ .listxattr = apfs_listxattr, ++ .setattr = apfs_setattr, ++ .update_time = apfs_update_time, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) ++ .fileattr_get = apfs_fileattr_get, ++ .fileattr_set = apfs_fileattr_set, ++#endif ++#if LINUX_VERSION_CODE == KERNEL_VERSION(5, 3, 0) ++ .fiemap = apfs_fiemap, ++#endif ++}; +diff --git a/fs/apfs/inode.c b/fs/apfs/inode.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/inode.c +@@ -0,0 +1,2594 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "apfs.h" ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++#include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) ++#include ++#endif ++ ++#define MAX_PFK_LEN 512 ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) ++static struct page *grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index) ++{ ++ return pagecache_get_page(mapping, index, FGP_WRITEBEGIN, mapping_gfp_mask(mapping)); ++} ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ ++static int apfs_read_folio(struct file *file, struct folio *folio) ++{ ++ return mpage_read_folio(folio, apfs_get_block); ++} ++ ++#else ++ ++static int apfs_readpage(struct file *file, struct page *page) ++{ ++ return mpage_readpage(page, apfs_get_block); ++} ++ ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) /* Misses mpage_readpages() */ ++ ++static void apfs_readahead(struct readahead_control *rac) ++{ ++ mpage_readahead(rac, apfs_get_block); ++} ++ ++#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) */ ++ ++static int apfs_readpages(struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned int nr_pages) ++{ ++ return mpage_readpages(mapping, pages, nr_pages, apfs_get_block); ++} ++ ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) */ ++ ++/** ++ * apfs_create_dstream_rec - Create a data stream record ++ * @dstream: data stream info ++ * ++ * Does nothing if the record already exists. TODO: support cloned files. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_dstream_rec(struct apfs_dstream_info *dstream) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_dstream_id_key raw_key; ++ struct apfs_dstream_id_val raw_val; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_dstream_id_key(dstream->ds_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret != -ENODATA) /* Either an error, or the record already exists */ ++ goto out; ++ ++ apfs_key_set_hdr(APFS_TYPE_DSTREAM_ID, dstream->ds_id, &raw_key); ++ raw_val.refcnt = cpu_to_le32(1); ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) { ++ apfs_err(sb, "insertion failed for id 0x%llx", dstream->ds_id); ++ goto out; ++ } ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++static int apfs_check_dstream_refcnt(struct inode *inode); ++static int apfs_put_dstream_rec(struct apfs_dstream_info *dstream); ++ ++/** ++ * apfs_inode_create_exclusive_dstream - Make an inode's dstream not shared ++ * @inode: the vfs inode ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_inode_create_exclusive_dstream(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ u64 new_id; ++ int err; ++ ++ if (!ai->i_has_dstream || !dstream->ds_shared) ++ return 0; ++ ++ /* ++ * The ds_shared field is not updated when the other user of the ++ * dstream puts it, so it could be a false positive. Check it again ++ * before actually putting the dstream. The double query is wasteful, ++ * but I don't know if it makes sense to optimize this (TODO). ++ */ ++ err = apfs_check_dstream_refcnt(inode); ++ if (err) { ++ apfs_err(sb, "failed to check refcnt for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ if (!dstream->ds_shared) ++ return 0; ++ err = apfs_put_dstream_rec(dstream); ++ if (err) { ++ apfs_err(sb, "failed to put dstream for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ new_id = le64_to_cpu(vsb_raw->apfs_next_obj_id); ++ le64_add_cpu(&vsb_raw->apfs_next_obj_id, 1); ++ ++ err = apfs_clone_extents(dstream, new_id); ++ if (err) { ++ apfs_err(sb, "failed clone extents for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ dstream->ds_id = new_id; ++ err = apfs_create_dstream_rec(dstream); ++ if (err) { ++ apfs_err(sb, "failed to create dstream for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ dstream->ds_shared = false; ++ return 0; ++} ++ ++/** ++ * apfs_inode_create_dstream_rec - Create the data stream record for an inode ++ * @inode: the vfs inode ++ * ++ * Does nothing if the record already exists. TODO: support cloned files. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_inode_create_dstream_rec(struct inode *inode) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ int err; ++ ++ if (ai->i_has_dstream) ++ return apfs_inode_create_exclusive_dstream(inode); ++ ++ err = apfs_create_dstream_rec(&ai->i_dstream); ++ if (err) ++ return err; ++ ++ ai->i_has_dstream = true; ++ return 0; ++} ++ ++/** ++ * apfs_dstream_adj_refcnt - Adjust dstream record refcount ++ * @dstream: data stream info ++ * @delta: desired change in reference count ++ * ++ * Deletes the record if the reference count goes to zero. Returns 0 on success ++ * or a negative error code in case of failure. ++ */ ++int apfs_dstream_adj_refcnt(struct apfs_dstream_info *dstream, u32 delta) ++{ ++ struct super_block *sb = dstream->ds_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_dstream_id_val raw_val; ++ void *raw = NULL; ++ u32 refcnt; ++ int ret; ++ ++ ASSERT(APFS_I(dstream->ds_inode)->i_has_dstream); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_dstream_id_key(dstream->ds_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx", dstream->ds_id); ++ if (ret == -ENODATA) ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ if (query->len != sizeof(raw_val)) { ++ apfs_err(sb, "bad value length (%d)", query->len); ++ ret = -EFSCORRUPTED; ++ goto out; ++ } ++ raw = query->node->object.data; ++ raw_val = *(struct apfs_dstream_id_val *)(raw + query->off); ++ refcnt = le32_to_cpu(raw_val.refcnt); ++ ++ refcnt += delta; ++ if (refcnt == 0) { ++ ret = apfs_btree_remove(query); ++ if (ret) ++ apfs_err(sb, "removal failed for id 0x%llx", dstream->ds_id); ++ goto out; ++ } ++ ++ raw_val.refcnt = cpu_to_le32(refcnt); ++ ret = apfs_btree_replace(query, NULL /* key */, 0 /* key_len */, &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "update failed for id 0x%llx", dstream->ds_id); ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_put_dstream_rec - Put a reference for a data stream record ++ * @dstream: data stream info ++ * ++ * Deletes the record if the reference count goes to zero. Returns 0 on success ++ * or a negative error code in case of failure. ++ */ ++static int apfs_put_dstream_rec(struct apfs_dstream_info *dstream) ++{ ++ struct apfs_inode_info *ai = APFS_I(dstream->ds_inode); ++ ++ if (!ai->i_has_dstream) ++ return 0; ++ return apfs_dstream_adj_refcnt(dstream, -1); ++} ++ ++/** ++ * apfs_create_crypto_rec - Create the crypto state record for an inode ++ * @inode: the vfs inode ++ * ++ * Does nothing if the record already exists. TODO: support cloned files. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_crypto_rec(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ struct apfs_query *query; ++ struct apfs_crypto_state_key raw_key; ++ int ret; ++ ++ if (inode->i_size || inode->i_blocks) /* Already has a dstream */ ++ return 0; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_crypto_state_key(dstream->ds_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret != -ENODATA) /* Either an error, or the record already exists */ ++ goto out; ++ ++ apfs_key_set_hdr(APFS_TYPE_CRYPTO_STATE, dstream->ds_id, &raw_key); ++ if (sbi->s_dflt_pfk) { ++ struct apfs_crypto_state_val *raw_val = sbi->s_dflt_pfk; ++ unsigned int key_len = le16_to_cpu(raw_val->state.key_len); ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), raw_val, sizeof(*raw_val) + key_len); ++ if (ret) ++ apfs_err(sb, "insertion failed for id 0x%llx", dstream->ds_id); ++ } else { ++ struct apfs_crypto_state_val raw_val; ++ ++ raw_val.refcnt = cpu_to_le32(1); ++ raw_val.state.major_version = cpu_to_le16(APFS_WMCS_MAJOR_VERSION); ++ raw_val.state.minor_version = cpu_to_le16(APFS_WMCS_MINOR_VERSION); ++ raw_val.state.cpflags = 0; ++ raw_val.state.persistent_class = cpu_to_le32(APFS_PROTECTION_CLASS_F); ++ raw_val.state.key_os_version = 0; ++ raw_val.state.key_revision = cpu_to_le16(1); ++ raw_val.state.key_len = cpu_to_le16(0); ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (ret) ++ apfs_err(sb, "insertion failed for id 0x%llx", dstream->ds_id); ++ } ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_dflt_key_class - Returns default key class for files in volume ++ * @sb: volume superblock ++ */ ++static unsigned int apfs_dflt_key_class(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ ++ if (!sbi->s_dflt_pfk) ++ return APFS_PROTECTION_CLASS_F; ++ ++ return le32_to_cpu(sbi->s_dflt_pfk->state.persistent_class); ++} ++ ++/** ++ * apfs_create_crypto_rec - Adjust crypto state record refcount ++ * @sb: volume superblock ++ * @crypto_id: crypto_id to adjust ++ * @delta: desired change in reference count ++ * ++ * This function is used when adding or removing extents, as each extent holds ++ * a reference to the crypto ID. It should also be used when removing inodes, ++ * and in that case it should also remove the crypto record (TODO). ++ */ ++int apfs_crypto_adj_refcnt(struct super_block *sb, u64 crypto_id, int delta) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_crypto_state_val *raw_val; ++ char *raw; ++ int ret; ++ ++ if (!crypto_id) ++ return 0; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_crypto_state_key(crypto_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx", crypto_id); ++ goto out; ++ } ++ ++ ret = apfs_query_join_transaction(query); ++ if (ret) { ++ apfs_err(sb, "query join failed"); ++ return ret; ++ } ++ raw = query->node->object.data; ++ raw_val = (void *)raw + query->off; ++ ++ le32_add_cpu(&raw_val->refcnt, delta); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_crypto_set_key - Modify content of crypto state record ++ * @sb: volume superblock ++ * @crypto_id: crypto_id to modify ++ * @new_val: new crypto state data; new_val->refcnt is overridden ++ * ++ * This function does not alter the inode's default protection class field. ++ * It needs to be done separately if the class changes. ++ */ ++static int apfs_crypto_set_key(struct super_block *sb, u64 crypto_id, struct apfs_crypto_state_val *new_val) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_crypto_state_val *raw_val; ++ char *raw; ++ int ret; ++ unsigned int pfk_len; ++ ++ if (!crypto_id) ++ return 0; ++ ++ pfk_len = le16_to_cpu(new_val->state.key_len); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_crypto_state_key(crypto_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx", crypto_id); ++ goto out; ++ } ++ raw = query->node->object.data; ++ raw_val = (void *)raw + query->off; ++ ++ new_val->refcnt = raw_val->refcnt; ++ ++ ret = apfs_btree_replace(query, NULL /* key */, 0 /* key_len */, new_val, sizeof(*new_val) + pfk_len); ++ if (ret) ++ apfs_err(sb, "update failed for id 0x%llx", crypto_id); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_crypto_get_key - Retrieve content of crypto state record ++ * @sb: volume superblock ++ * @crypto_id: crypto_id to modify ++ * @val: result crypto state data ++ * @max_len: maximum allowed value of val->state.key_len ++ */ ++static int apfs_crypto_get_key(struct super_block *sb, u64 crypto_id, struct apfs_crypto_state_val *val, ++ unsigned int max_len) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_crypto_state_val *raw_val; ++ char *raw; ++ int ret; ++ unsigned int pfk_len; ++ ++ if (!crypto_id) ++ return -ENOENT; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_crypto_state_key(crypto_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) ++ goto out; ++ raw = query->node->object.data; ++ raw_val = (void *)raw + query->off; ++ ++ pfk_len = le16_to_cpu(raw_val->state.key_len); ++ if (pfk_len > max_len) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ ++ memcpy(val, raw_val, sizeof(*val) + pfk_len); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++int __apfs_write_begin(const struct kiocb *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata) ++#else ++int __apfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata) ++#endif ++{ ++ struct inode *inode = mapping->host; ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ struct super_block *sb = inode->i_sb; ++ struct page *page; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) ++ struct folio *folio; ++#endif ++ struct buffer_head *bh, *head; ++ unsigned int blocksize, block_start, block_end, from, to; ++ pgoff_t index = pos >> PAGE_SHIFT; ++ sector_t iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits); ++ loff_t i_blks_end; ++ int err; ++ ++ apfs_inode_join_transaction(sb, inode); ++ ++ err = apfs_inode_create_dstream_rec(inode); ++ if (err) { ++ apfs_err(sb, "failed to create dstream for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ if (apfs_vol_is_encrypted(sb)) { ++ err = apfs_create_crypto_rec(inode); ++ if (err) { ++ apfs_err(sb, "crypto creation failed for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ flags = memalloc_nofs_save(); ++ page = grab_cache_page_write_begin(mapping, index); ++ memalloc_nofs_restore(flags); ++#else ++ page = grab_cache_page_write_begin(mapping, index, flags | AOP_FLAG_NOFS); ++#endif ++ if (!page) ++ return -ENOMEM; ++ if (!page_has_buffers(page)) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ create_empty_buffers(page, sb->s_blocksize, 0); ++#else ++ folio = page_folio(page); ++ bh = folio_buffers(folio); ++ if (!bh) ++ bh = create_empty_buffers(folio, sb->s_blocksize, 0); ++#endif ++ } ++ ++ /* CoW moves existing blocks, so read them but mark them as unmapped */ ++ head = page_buffers(page); ++ blocksize = head->b_size; ++ i_blks_end = (inode->i_size + sb->s_blocksize - 1) >> inode->i_blkbits; ++ i_blks_end <<= inode->i_blkbits; ++ if (i_blks_end >= pos) { ++ from = pos & (PAGE_SIZE - 1); ++ to = from + min(i_blks_end - pos, (loff_t)len); ++ } else { ++ /* TODO: deal with preallocated tail blocks */ ++ from = UINT_MAX; ++ to = 0; ++ } ++ for (bh = head, block_start = 0; bh != head || !block_start; ++ block_start = block_end, bh = bh->b_this_page, ++iblock) { ++ block_end = block_start + blocksize; ++ if (to > block_start && from < block_end) { ++ if (buffer_trans(bh)) ++ continue; ++ if (!buffer_mapped(bh)) { ++ err = __apfs_get_block(dstream, iblock, bh, ++ false /* create */); ++ if (err) { ++ apfs_err(sb, "failed to map block for ino 0x%llx", apfs_ino(inode)); ++ goto out_put_page; ++ } ++ } ++ if (buffer_mapped(bh) && !buffer_uptodate(bh)) { ++ get_bh(bh); ++ lock_buffer(bh); ++ bh->b_end_io = end_buffer_read_sync; ++ apfs_submit_bh(REQ_OP_READ, 0, bh); ++ wait_on_buffer(bh); ++ if (!buffer_uptodate(bh)) { ++ apfs_err(sb, "failed to read block for ino 0x%llx", apfs_ino(inode)); ++ err = -EIO; ++ goto out_put_page; ++ } ++ } ++ clear_buffer_mapped(bh); ++ } ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++ err = __block_write_begin(page_folio(page), pos, len, apfs_get_new_block); ++#else ++ err = __block_write_begin(page, pos, len, apfs_get_new_block); ++#endif ++ if (err) { ++ apfs_err(sb, "CoW failed in inode 0x%llx", apfs_ino(inode)); ++ goto out_put_page; ++ } ++ ++ *pagep = page; ++ return 0; ++ ++out_put_page: ++ unlock_page(page); ++ put_page(page); ++ return err; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++static int apfs_write_begin(const struct kiocb *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, ++ struct folio **foliop, void **fsdata) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++static int apfs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, ++ struct folio **foliop, void **fsdata) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++static int apfs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, ++ struct page **pagep, void **fsdata) ++#else ++static int apfs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, unsigned int flags, ++ struct page **pagep, void **fsdata) ++#endif ++{ ++ struct inode *inode = mapping->host; ++ struct super_block *sb = inode->i_sb; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++ struct page *page = NULL; ++ struct page **pagep = &page; ++#endif ++ int err; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ unsigned int flags = 0; ++#endif ++ ++ if (unlikely(pos >= APFS_MAX_FILE_SIZE)) ++ return -EFBIG; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ err = __apfs_write_begin(file, mapping, pos, len, flags, pagep, fsdata); ++ if (err) ++ goto fail; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++ *foliop = page_folio(page); ++#endif ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++int __apfs_write_end(const struct kiocb *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata) ++#else ++int __apfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata) ++#endif ++{ ++ struct inode *inode = mapping->host; ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ int ret, err; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++ ret = generic_write_end(file, mapping, pos, len, copied, page_folio(page), fsdata); ++#else ++ ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); ++#endif ++ dstream->ds_size = i_size_read(inode); ++ if (ret < len && pos + len > inode->i_size) { ++ truncate_pagecache(inode, inode->i_size); ++ err = apfs_truncate(dstream, inode->i_size); ++ if (err) { ++ apfs_err(inode->i_sb, "truncation failed for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ } ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++static int apfs_write_end(const struct kiocb *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, unsigned int copied, ++ struct folio *folio, void *fsdata) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++static int apfs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, unsigned int copied, ++ struct folio *folio, void *fsdata) ++#else ++static int apfs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned int len, unsigned int copied, ++ struct page *page, void *fsdata) ++#endif ++{ ++ struct inode *inode = mapping->host; ++ struct super_block *sb = inode->i_sb; ++ struct apfs_nx_transaction *trans = &APFS_NXI(sb)->nx_transaction; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) ++ struct page *page = &folio->page; ++#endif ++ int ret, err; ++ ++ ret = __apfs_write_end(file, mapping, pos, len, copied, page, fsdata); ++ if (ret < 0) { ++ err = ret; ++ goto fail; ++ } ++ ++ if ((pos + ret) & (sb->s_blocksize - 1)) ++ trans->t_state |= APFS_NX_TRANS_INCOMPLETE_BLOCK; ++ else ++ trans->t_state &= ~APFS_NX_TRANS_INCOMPLETE_BLOCK; ++ ++ err = apfs_transaction_commit(sb); ++ if (!err) ++ return ret; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || RHEL_VERSION_GE(9, 3) ++static void apfs_noop_invalidate_folio(struct folio *folio, size_t offset, size_t length) ++#else ++static void apfs_noop_invalidatepage(struct page *page, unsigned int offset, unsigned int length) ++#endif ++{ ++} ++ ++/* bmap is not implemented to avoid issues with CoW on swapfiles */ ++static const struct address_space_operations apfs_aops = { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || RHEL_VERSION_GE(9, 2) ++ .dirty_folio = block_dirty_folio, ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) ++ .set_page_dirty = __set_page_dirty_buffers, ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ .read_folio = apfs_read_folio, ++#else ++ .readpage = apfs_readpage, ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) ++ .readahead = apfs_readahead, ++#else ++ .readpages = apfs_readpages, ++#endif ++ ++ .write_begin = apfs_write_begin, ++ .write_end = apfs_write_end, ++ ++ /* The intention is to keep bhs around until the transaction is over */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || RHEL_VERSION_GE(9, 3) ++ .invalidate_folio = apfs_noop_invalidate_folio, ++#else ++ .invalidatepage = apfs_noop_invalidatepage, ++#endif ++}; ++ ++/** ++ * apfs_inode_set_ops - Set up an inode's operations ++ * @inode: vfs inode to set up ++ * @rdev: device id (0 if not a device file) ++ * @compressed: is this a compressed inode? ++ * ++ * For device files, also sets the device id to @rdev. ++ */ ++static void apfs_inode_set_ops(struct inode *inode, dev_t rdev, bool compressed) ++{ ++ /* A lot of operations still missing, of course */ ++ switch (inode->i_mode & S_IFMT) { ++ case S_IFREG: ++ inode->i_op = &apfs_file_inode_operations; ++ if (compressed) { ++ inode->i_fop = &apfs_compress_file_operations; ++ inode->i_mapping->a_ops = &apfs_compress_aops; ++ } else { ++ inode->i_fop = &apfs_file_operations; ++ inode->i_mapping->a_ops = &apfs_aops; ++ } ++ break; ++ case S_IFDIR: ++ inode->i_op = &apfs_dir_inode_operations; ++ inode->i_fop = &apfs_dir_operations; ++ break; ++ case S_IFLNK: ++ inode->i_op = &apfs_symlink_inode_operations; ++ break; ++ default: ++ inode->i_op = &apfs_special_inode_operations; ++ init_special_inode(inode, inode->i_mode, rdev); ++ break; ++ } ++} ++ ++/** ++ * apfs_inode_from_query - Read the inode found by a successful query ++ * @query: the query that found the record ++ * @inode: vfs inode to be filled with the read data ++ * ++ * Reads the inode record into @inode and performs some basic sanity checks, ++ * mostly as a protection against crafted filesystems. Returns 0 on success ++ * or a negative error code otherwise. ++ */ ++static int apfs_inode_from_query(struct apfs_query *query, struct inode *inode) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ struct apfs_inode_val *inode_val; ++ char *raw = query->node->object.data; ++ char *xval = NULL; ++ int xlen; ++ u32 rdev = 0, bsd_flags; ++ bool compressed = false; ++ ++ if (query->len < sizeof(*inode_val)) ++ goto corrupted; ++ ++ inode_val = (struct apfs_inode_val *)(raw + query->off); ++ ++ ai->i_parent_id = le64_to_cpu(inode_val->parent_id); ++ dstream->ds_id = le64_to_cpu(inode_val->private_id); ++ inode->i_mode = le16_to_cpu(inode_val->mode); ++ ai->i_key_class = le32_to_cpu(inode_val->default_protection_class); ++ ai->i_int_flags = le64_to_cpu(inode_val->internal_flags); ++ ++ ai->i_saved_uid = le32_to_cpu(inode_val->owner); ++ i_uid_write(inode, ai->i_saved_uid); ++ ai->i_saved_gid = le32_to_cpu(inode_val->group); ++ i_gid_write(inode, ai->i_saved_gid); ++ ++ ai->i_bsd_flags = bsd_flags = le32_to_cpu(inode_val->bsd_flags); ++ if (bsd_flags & APFS_INOBSD_IMMUTABLE) ++ inode->i_flags |= S_IMMUTABLE; ++ if (bsd_flags & APFS_INOBSD_APPEND) ++ inode->i_flags |= S_APPEND; ++ ++ if (!S_ISDIR(inode->i_mode)) { ++ /* ++ * Directory inodes don't store their link count, so to provide ++ * it we would have to actually count the subdirectories. The ++ * HFS/HFS+ modules just leave it at 1, and so do we, for now. ++ */ ++ set_nlink(inode, le32_to_cpu(inode_val->nlink)); ++ } else { ++ ai->i_nchildren = le32_to_cpu(inode_val->nchildren); ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_ctime = ns_to_timespec64(le64_to_cpu(inode_val->change_time)); ++#else ++ inode_set_ctime_to_ts(inode, ns_to_timespec64(le64_to_cpu(inode_val->change_time))); ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ inode->i_atime = ns_to_timespec64(le64_to_cpu(inode_val->access_time)); ++ inode->i_mtime = ns_to_timespec64(le64_to_cpu(inode_val->mod_time)); ++#else ++ inode_set_atime_to_ts(inode, ns_to_timespec64(le64_to_cpu(inode_val->access_time))); ++ inode_set_mtime_to_ts(inode, ns_to_timespec64(le64_to_cpu(inode_val->mod_time))); ++#endif ++ ai->i_crtime = ns_to_timespec64(le64_to_cpu(inode_val->create_time)); ++ ++ dstream->ds_size = inode->i_size = inode->i_blocks = 0; ++ ai->i_has_dstream = false; ++ if ((bsd_flags & APFS_INOBSD_COMPRESSED) && !S_ISDIR(inode->i_mode)) { ++ if (!apfs_compress_get_size(inode, &inode->i_size)) { ++ inode->i_blocks = (inode->i_size + 511) >> 9; ++ compressed = true; ++ } ++ } else { ++ xlen = apfs_find_xfield(inode_val->xfields, ++ query->len - sizeof(*inode_val), ++ APFS_INO_EXT_TYPE_DSTREAM, &xval); ++ if (xlen >= sizeof(struct apfs_dstream)) { ++ struct apfs_dstream *dstream_raw = (struct apfs_dstream *)xval; ++ ++ dstream->ds_size = inode->i_size = le64_to_cpu(dstream_raw->size); ++ inode->i_blocks = le64_to_cpu(dstream_raw->alloced_size) >> 9; ++ ai->i_has_dstream = true; ++ } ++ } ++ xval = NULL; ++ ++ /* TODO: move each xfield read to its own function */ ++ dstream->ds_sparse_bytes = 0; ++ xlen = apfs_find_xfield(inode_val->xfields, query->len - sizeof(*inode_val), APFS_INO_EXT_TYPE_SPARSE_BYTES, &xval); ++ if (xlen >= sizeof(__le64)) { ++ __le64 *sparse_bytes_p = (__le64 *)xval; ++ ++ dstream->ds_sparse_bytes = le64_to_cpup(sparse_bytes_p); ++ } ++ xval = NULL; ++ ++ rdev = 0; ++ xlen = apfs_find_xfield(inode_val->xfields, ++ query->len - sizeof(*inode_val), ++ APFS_INO_EXT_TYPE_RDEV, &xval); ++ if (xlen >= sizeof(__le32)) { ++ __le32 *rdev_p = (__le32 *)xval; ++ ++ rdev = le32_to_cpup(rdev_p); ++ } ++ ++ apfs_inode_set_ops(inode, rdev, compressed); ++ return 0; ++ ++corrupted: ++ apfs_err(inode->i_sb, "bad inode record for inode 0x%llx", apfs_ino(inode)); ++ return -EFSCORRUPTED; ++} ++ ++/** ++ * apfs_inode_lookup - Lookup an inode record in the catalog b-tree ++ * @inode: vfs inode to lookup ++ * ++ * Runs a catalog query for the apfs_ino(@inode) inode record; returns a pointer ++ * to the query structure on success, or an error pointer in case of failure. ++ */ ++static struct apfs_query *apfs_inode_lookup(const struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return ERR_PTR(-ENOMEM); ++ apfs_init_inode_key(apfs_ino(inode), &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (!ret) ++ return query; ++ ++ /* Don't complain if an orphan is already gone */ ++ if (!current_work() || ret != -ENODATA) ++ apfs_err(sb, "query failed for id 0x%llx", apfs_ino(inode)); ++ apfs_free_query(query); ++ return ERR_PTR(ret); ++} ++ ++/** ++ * apfs_test_inode - Check if the inode matches a 64-bit inode number ++ * @inode: inode to test ++ * @cnid: pointer to the inode number ++ */ ++static int apfs_test_inode(struct inode *inode, void *cnid) ++{ ++ u64 *ino = cnid; ++ ++ return apfs_ino(inode) == *ino; ++} ++ ++/** ++ * apfs_set_inode - Set a 64-bit inode number on the given inode ++ * @inode: inode to set ++ * @cnid: pointer to the inode number ++ */ ++static int apfs_set_inode(struct inode *inode, void *cnid) ++{ ++ apfs_set_ino(inode, *(u64 *)cnid); ++ return 0; ++} ++ ++/** ++ * apfs_iget_locked - Wrapper for iget5_locked() ++ * @sb: filesystem superblock ++ * @cnid: 64-bit inode number ++ * ++ * Works the same as iget_locked(), but can handle 64-bit inode numbers on ++ * 32-bit architectures. ++ */ ++static struct inode *apfs_iget_locked(struct super_block *sb, u64 cnid) ++{ ++ return iget5_locked(sb, cnid, apfs_test_inode, apfs_set_inode, &cnid); ++} ++ ++/** ++ * apfs_check_dstream_refcnt - Check if an inode's dstream is shared ++ * @inode: the inode to check ++ * ++ * Sets the value of ds_shared for the inode's dstream. Returns 0 on success, ++ * or a negative error code in case of failure. ++ */ ++static int apfs_check_dstream_refcnt(struct inode *inode) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_dstream_id_val raw_val; ++ void *raw = NULL; ++ u32 refcnt; ++ int ret; ++ ++ if (!ai->i_has_dstream) { ++ dstream->ds_shared = false; ++ return 0; ++ } ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_dstream_id_key(dstream->ds_id, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx", dstream->ds_id); ++ if (ret == -ENODATA) ++ ret = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ if (query->len != sizeof(raw_val)) { ++ ret = -EFSCORRUPTED; ++ goto fail; ++ } ++ raw = query->node->object.data; ++ raw_val = *(struct apfs_dstream_id_val *)(raw + query->off); ++ refcnt = le32_to_cpu(raw_val.refcnt); ++ ++ dstream->ds_shared = refcnt > 1; ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_iget - Populate inode structures with metadata from disk ++ * @sb: filesystem superblock ++ * @cnid: inode number ++ * ++ * Populates the vfs inode and the corresponding apfs_inode_info structure. ++ * Returns a pointer to the vfs inode in case of success, or an appropriate ++ * error pointer otherwise. ++ */ ++struct inode *apfs_iget(struct super_block *sb, u64 cnid) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct inode *inode; ++ struct apfs_query *query; ++ int err; ++ ++ inode = apfs_iget_locked(sb, cnid); ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ if (!(inode->i_state & I_NEW)) ++ return inode; ++ ++ down_read(&nxi->nx_big_sem); ++ query = apfs_inode_lookup(inode); ++ if (IS_ERR(query)) { ++ err = PTR_ERR(query); ++ /* Don't complain if an orphan is already gone */ ++ if (!current_work() || err != -ENODATA) ++ apfs_err(sb, "lookup failed for ino 0x%llx", cnid); ++ goto fail; ++ } ++ err = apfs_inode_from_query(query, inode); ++ apfs_free_query(query); ++ if (err) ++ goto fail; ++ err = apfs_check_dstream_refcnt(inode); ++ if (err) { ++ apfs_err(sb, "refcnt check failed for ino 0x%llx", cnid); ++ goto fail; ++ } ++ up_read(&nxi->nx_big_sem); ++ ++ /* Allow the user to override the ownership */ ++ if (uid_valid(sbi->s_uid)) ++ inode->i_uid = sbi->s_uid; ++ if (gid_valid(sbi->s_gid)) ++ inode->i_gid = sbi->s_gid; ++ ++ /* Inode flags are not important for now, leave them at 0 */ ++ unlock_new_inode(inode); ++ return inode; ++ ++fail: ++ up_read(&nxi->nx_big_sem); ++ iget_failed(inode); ++ return ERR_PTR(err); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) /* No statx yet... */ ++ ++int apfs_getattr(struct vfsmount *mnt, struct dentry *dentry, ++ struct kstat *stat) ++{ ++ struct inode *inode = d_inode(dentry); ++ ++ generic_fillattr(inode, stat); ++ stat->dev = APFS_SB(inode->i_sb)->s_anon_dev; ++ stat->ino = apfs_ino(inode); ++ return 0; ++} ++ ++#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++int apfs_getattr(const struct path *path, struct kstat *stat, ++ u32 request_mask, unsigned int query_flags) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++int apfs_getattr(struct user_namespace *mnt_userns, ++ const struct path *path, struct kstat *stat, u32 request_mask, ++ unsigned int query_flags) ++#else ++int apfs_getattr(struct mnt_idmap *idmap, ++ const struct path *path, struct kstat *stat, u32 request_mask, ++ unsigned int query_flags) ++#endif ++{ ++ struct inode *inode = d_inode(path->dentry); ++ struct apfs_inode_info *ai = APFS_I(inode); ++ ++ stat->result_mask |= STATX_BTIME; ++ stat->btime = ai->i_crtime; ++ ++ if (ai->i_bsd_flags & APFS_INOBSD_APPEND) ++ stat->attributes |= STATX_ATTR_APPEND; ++ if (ai->i_bsd_flags & APFS_INOBSD_IMMUTABLE) ++ stat->attributes |= STATX_ATTR_IMMUTABLE; ++ if (ai->i_bsd_flags & APFS_INOBSD_NODUMP) ++ stat->attributes |= STATX_ATTR_NODUMP; ++ if (ai->i_bsd_flags & APFS_INOBSD_COMPRESSED) ++ stat->attributes |= STATX_ATTR_COMPRESSED; ++ ++ stat->attributes_mask |= STATX_ATTR_APPEND; ++ stat->attributes_mask |= STATX_ATTR_IMMUTABLE; ++ stat->attributes_mask |= STATX_ATTR_NODUMP; ++ stat->attributes_mask |= STATX_ATTR_COMPRESSED; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ generic_fillattr(inode, stat); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ generic_fillattr(mnt_userns, inode, stat); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ generic_fillattr(idmap, inode, stat); ++#else ++ generic_fillattr(idmap, request_mask, inode, stat); ++#endif ++ ++ stat->dev = APFS_SB(inode->i_sb)->s_anon_dev; ++ stat->ino = apfs_ino(inode); ++ return 0; ++} ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) */ ++ ++/** ++ * apfs_build_inode_val - Allocate and initialize the value for an inode record ++ * @inode: vfs inode to record ++ * @qname: filename for primary link ++ * @val_p: on return, a pointer to the new on-disk value structure ++ * ++ * Returns the length of the value, or a negative error code in case of failure. ++ */ ++static int apfs_build_inode_val(struct inode *inode, const struct qstr *qname, ++ struct apfs_inode_val **val_p) ++{ ++ struct apfs_inode_val *val; ++ struct apfs_x_field xkey; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) ++ struct timespec64 ts; ++#endif ++ int total_xlen, val_len; ++ bool is_device = S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode); ++ __le32 rdev; ++ ++ /* The only required xfield is the name, and the id if it's a device */ ++ total_xlen = sizeof(struct apfs_xf_blob); ++ total_xlen += sizeof(xkey) + round_up(qname->len + 1, 8); ++ if (is_device) ++ total_xlen += sizeof(xkey) + round_up(sizeof(rdev), 8); ++ ++ val_len = sizeof(*val) + total_xlen; ++ val = kzalloc(val_len, GFP_KERNEL); ++ if (!val) ++ return -ENOMEM; ++ ++ val->parent_id = cpu_to_le64(APFS_I(inode)->i_parent_id); ++ val->private_id = cpu_to_le64(apfs_ino(inode)); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ val->mod_time = cpu_to_le64(timespec64_to_ns(&inode->i_mtime)); ++#else ++ ts = inode_get_mtime(inode); ++ val->mod_time = cpu_to_le64(timespec64_to_ns(&ts)); ++#endif ++ val->create_time = val->change_time = val->access_time = val->mod_time; ++ ++ if (S_ISDIR(inode->i_mode)) ++ val->nchildren = 0; ++ else ++ val->nlink = cpu_to_le32(1); ++ ++ val->owner = cpu_to_le32(i_uid_read(inode)); ++ val->group = cpu_to_le32(i_gid_read(inode)); ++ val->mode = cpu_to_le16(inode->i_mode); ++ ++ /* The buffer was just allocated: none of these functions should fail */ ++ apfs_init_xfields(val->xfields, total_xlen); ++ xkey.x_type = APFS_INO_EXT_TYPE_NAME; ++ xkey.x_flags = APFS_XF_DO_NOT_COPY; ++ xkey.x_size = cpu_to_le16(qname->len + 1); ++ apfs_insert_xfield(val->xfields, total_xlen, &xkey, qname->name); ++ if (is_device) { ++ rdev = cpu_to_le32(inode->i_rdev); ++ xkey.x_type = APFS_INO_EXT_TYPE_RDEV; ++ xkey.x_flags = 0; /* TODO: proper flags here? */ ++ xkey.x_size = cpu_to_le16(sizeof(rdev)); ++ apfs_insert_xfield(val->xfields, total_xlen, &xkey, &rdev); ++ } ++ ++ *val_p = val; ++ return val_len; ++} ++ ++/* ++ * apfs_inode_rename - Update the primary name reported in an inode record ++ * @inode: the in-memory inode ++ * @new_name: name of the new primary link (NULL if unchanged) ++ * @query: the query that found the inode record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_inode_rename(struct inode *inode, char *new_name, ++ struct apfs_query *query) ++{ ++ char *raw = query->node->object.data; ++ struct apfs_inode_val *new_val = NULL; ++ int buflen, namelen; ++ struct apfs_x_field xkey; ++ int xlen; ++ int err; ++ ++ if (!new_name) ++ return 0; ++ ++ namelen = strlen(new_name) + 1; /* Count the null-termination */ ++ buflen = query->len; ++ buflen += sizeof(struct apfs_x_field) + round_up(namelen, 8); ++ new_val = kzalloc(buflen, GFP_KERNEL); ++ if (!new_val) ++ return -ENOMEM; ++ memcpy(new_val, raw + query->off, query->len); ++ ++ /* TODO: can we assume that all inode records have an xfield blob? */ ++ xkey.x_type = APFS_INO_EXT_TYPE_NAME; ++ xkey.x_flags = APFS_XF_DO_NOT_COPY; ++ xkey.x_size = cpu_to_le16(namelen); ++ xlen = apfs_insert_xfield(new_val->xfields, buflen - sizeof(*new_val), ++ &xkey, new_name); ++ if (!xlen) { ++ /* Buffer has enough space, but the metadata claims otherwise */ ++ apfs_err(inode->i_sb, "bad xfields on inode 0x%llx", apfs_ino(inode)); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ /* Just remove the old record and create a new one */ ++ err = apfs_btree_replace(query, NULL /* key */, 0 /* key_len */, new_val, sizeof(*new_val) + xlen); ++ if (err) ++ apfs_err(inode->i_sb, "update failed for ino 0x%llx", apfs_ino(inode)); ++ ++fail: ++ kfree(new_val); ++ return err; ++} ++ ++/** ++ * apfs_create_dstream_xfield - Create the inode xfield for a new data stream ++ * @inode: the in-memory inode ++ * @query: the query that found the inode record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_create_dstream_xfield(struct inode *inode, ++ struct apfs_query *query) ++{ ++ char *raw = query->node->object.data; ++ struct apfs_inode_val *new_val; ++ struct apfs_dstream dstream_raw = {0}; ++ struct apfs_x_field xkey; ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ int xlen; ++ int buflen; ++ int err; ++ ++ buflen = query->len; ++ buflen += sizeof(struct apfs_x_field) + sizeof(dstream_raw); ++ new_val = kzalloc(buflen, GFP_KERNEL); ++ if (!new_val) ++ return -ENOMEM; ++ memcpy(new_val, raw + query->off, query->len); ++ ++ dstream_raw.size = cpu_to_le64(inode->i_size); ++ dstream_raw.alloced_size = cpu_to_le64(apfs_alloced_size(dstream)); ++ if (apfs_vol_is_encrypted(inode->i_sb)) ++ dstream_raw.default_crypto_id = cpu_to_le64(dstream->ds_id); ++ ++ /* TODO: can we assume that all inode records have an xfield blob? */ ++ xkey.x_type = APFS_INO_EXT_TYPE_DSTREAM; ++ xkey.x_flags = APFS_XF_SYSTEM_FIELD; ++ xkey.x_size = cpu_to_le16(sizeof(dstream_raw)); ++ xlen = apfs_insert_xfield(new_val->xfields, buflen - sizeof(*new_val), ++ &xkey, &dstream_raw); ++ if (!xlen) { ++ /* Buffer has enough space, but the metadata claims otherwise */ ++ apfs_err(inode->i_sb, "bad xfields on inode 0x%llx", apfs_ino(inode)); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ /* Just remove the old record and create a new one */ ++ err = apfs_btree_replace(query, NULL /* key */, 0 /* key_len */, new_val, sizeof(*new_val) + xlen); ++ if (err) ++ apfs_err(inode->i_sb, "update failed for ino 0x%llx", apfs_ino(inode)); ++ ++fail: ++ kfree(new_val); ++ return err; ++} ++ ++/** ++ * apfs_inode_resize - Update the sizes reported in an inode record ++ * @inode: the in-memory inode ++ * @query: the query that found the inode record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_inode_resize(struct inode *inode, struct apfs_query *query) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ char *raw; ++ struct apfs_inode_val *inode_raw; ++ char *xval; ++ int xlen; ++ int err; ++ ++ /* All dstream records must have a matching xfield, even if empty */ ++ if (!ai->i_has_dstream) ++ return 0; ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(inode->i_sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ inode_raw = (void *)raw + query->off; ++ ++ xlen = apfs_find_xfield(inode_raw->xfields, ++ query->len - sizeof(*inode_raw), ++ APFS_INO_EXT_TYPE_DSTREAM, &xval); ++ ++ if (xlen) { ++ struct apfs_dstream *dstream; ++ ++ if (xlen != sizeof(*dstream)) { ++ apfs_err(inode->i_sb, "bad xlen (%d) on inode 0x%llx", xlen, apfs_ino(inode)); ++ return -EFSCORRUPTED; ++ } ++ dstream = (struct apfs_dstream *)xval; ++ ++ /* TODO: count bytes read and written */ ++ dstream->size = cpu_to_le64(inode->i_size); ++ dstream->alloced_size = cpu_to_le64(apfs_alloced_size(&ai->i_dstream)); ++ return 0; ++ } ++ /* This inode has no dstream xfield, so we need to create it */ ++ return apfs_create_dstream_xfield(inode, query); ++} ++ ++/** ++ * apfs_create_sparse_xfield - Create an inode xfield to count sparse bytes ++ * @inode: the in-memory inode ++ * @query: the query that found the inode record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_create_sparse_xfield(struct inode *inode, struct apfs_query *query) ++{ ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ char *raw = query->node->object.data; ++ struct apfs_inode_val *new_val; ++ __le64 sparse_bytes; ++ struct apfs_x_field xkey; ++ int xlen; ++ int buflen; ++ int err; ++ ++ buflen = query->len; ++ buflen += sizeof(struct apfs_x_field) + sizeof(sparse_bytes); ++ new_val = kzalloc(buflen, GFP_KERNEL); ++ if (!new_val) ++ return -ENOMEM; ++ memcpy(new_val, raw + query->off, query->len); ++ ++ sparse_bytes = cpu_to_le64(dstream->ds_sparse_bytes); ++ ++ /* TODO: can we assume that all inode records have an xfield blob? */ ++ xkey.x_type = APFS_INO_EXT_TYPE_SPARSE_BYTES; ++ xkey.x_flags = APFS_XF_SYSTEM_FIELD | APFS_XF_CHILDREN_INHERIT; ++ xkey.x_size = cpu_to_le16(sizeof(sparse_bytes)); ++ xlen = apfs_insert_xfield(new_val->xfields, buflen - sizeof(*new_val), &xkey, &sparse_bytes); ++ if (!xlen) { ++ /* Buffer has enough space, but the metadata claims otherwise */ ++ apfs_err(inode->i_sb, "bad xfields on inode 0x%llx", apfs_ino(inode)); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ /* Just remove the old record and create a new one */ ++ err = apfs_btree_replace(query, NULL /* key */, 0 /* key_len */, new_val, sizeof(*new_val) + xlen); ++ if (err) ++ apfs_err(inode->i_sb, "update failed for ino 0x%llx", apfs_ino(inode)); ++ ++fail: ++ kfree(new_val); ++ return err; ++} ++ ++/** ++ * apfs_inode_resize_sparse - Update sparse byte count reported in inode record ++ * @inode: the in-memory inode ++ * @query: the query that found the inode record ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ * ++ * TODO: should the xfield be removed if the count reaches 0? Should the inode ++ * flag change? ++ */ ++static int apfs_inode_resize_sparse(struct inode *inode, struct apfs_query *query) ++{ ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ char *raw; ++ struct apfs_inode_val *inode_raw; ++ char *xval; ++ int xlen; ++ int err; ++ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(inode->i_sb, "query join failed"); ++ return err; ++ } ++ raw = query->node->object.data; ++ inode_raw = (void *)raw + query->off; ++ ++ xlen = apfs_find_xfield(inode_raw->xfields, ++ query->len - sizeof(*inode_raw), ++ APFS_INO_EXT_TYPE_SPARSE_BYTES, &xval); ++ if (!xlen && !dstream->ds_sparse_bytes) ++ return 0; ++ ++ if (xlen) { ++ __le64 *sparse_bytes_p; ++ ++ if (xlen != sizeof(*sparse_bytes_p)) { ++ apfs_err(inode->i_sb, "bad xlen (%d) on inode 0x%llx", xlen, apfs_ino(inode)); ++ return -EFSCORRUPTED; ++ } ++ sparse_bytes_p = (__le64 *)xval; ++ ++ *sparse_bytes_p = cpu_to_le64(dstream->ds_sparse_bytes); ++ return 0; ++ } ++ return apfs_create_sparse_xfield(inode, query); ++} ++ ++/** ++ * apfs_update_inode - Update an existing inode record ++ * @inode: the modified in-memory inode ++ * @new_name: name of the new primary link (NULL if unchanged) ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_update_inode(struct inode *inode, char *new_name) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ struct apfs_query *query; ++ struct apfs_btree_node_phys *node_raw; ++ struct apfs_inode_val *inode_raw; ++ int err; ++ ++ err = apfs_flush_extent_cache(dstream); ++ if (err) { ++ apfs_err(sb, "extent cache flush failed for inode 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ query = apfs_inode_lookup(inode); ++ if (IS_ERR(query)) { ++ apfs_err(sb, "lookup failed for ino 0x%llx", apfs_ino(inode)); ++ return PTR_ERR(query); ++ } ++ ++ /* TODO: copy the record to memory and make all xfield changes there */ ++ err = apfs_inode_rename(inode, new_name, query); ++ if (err) { ++ apfs_err(sb, "rename failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ ++ err = apfs_inode_resize(inode, query); ++ if (err) { ++ apfs_err(sb, "resize failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ ++ err = apfs_inode_resize_sparse(inode, query); ++ if (err) { ++ apfs_err(sb, "sparse resize failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ if (dstream->ds_sparse_bytes) ++ ai->i_int_flags |= APFS_INODE_IS_SPARSE; ++ ++ /* TODO: just use apfs_btree_replace()? */ ++ err = apfs_query_join_transaction(query); ++ if (err) { ++ apfs_err(sb, "query join failed"); ++ goto fail; ++ } ++ node_raw = (void *)query->node->object.data; ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ inode_raw = (void *)node_raw + query->off; ++ ++ inode_raw->parent_id = cpu_to_le64(ai->i_parent_id); ++ inode_raw->private_id = cpu_to_le64(dstream->ds_id); ++ inode_raw->mode = cpu_to_le16(inode->i_mode); ++ inode_raw->owner = cpu_to_le32(i_uid_read(inode)); ++ inode_raw->group = cpu_to_le32(i_gid_read(inode)); ++ inode_raw->default_protection_class = cpu_to_le32(ai->i_key_class); ++ inode_raw->internal_flags = cpu_to_le64(ai->i_int_flags); ++ inode_raw->bsd_flags = cpu_to_le32(ai->i_bsd_flags); ++ ++ /* Don't persist the uid/gid provided by the user on mount */ ++ if (uid_valid(sbi->s_uid)) ++ inode_raw->owner = cpu_to_le32(ai->i_saved_uid); ++ if (gid_valid(sbi->s_gid)) ++ inode_raw->group = cpu_to_le32(ai->i_saved_gid); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode_raw->change_time = cpu_to_le64(timespec64_to_ns(&inode->i_ctime)); ++#else ++ struct timespec64 ictime = inode_get_ctime(inode); ++ inode_raw->change_time = cpu_to_le64(timespec64_to_ns(&ictime)); ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ inode_raw->access_time = cpu_to_le64(timespec64_to_ns(&inode->i_atime)); ++ inode_raw->mod_time = cpu_to_le64(timespec64_to_ns(&inode->i_mtime)); ++#else ++ struct timespec64 ts = inode_get_mtime(inode); ++ inode_raw->mod_time = cpu_to_le64(timespec64_to_ns(&ts)); ++ ts = inode_get_atime(inode); ++ inode_raw->access_time = cpu_to_le64(timespec64_to_ns(&ts)); ++#endif ++ inode_raw->create_time = cpu_to_le64(timespec64_to_ns(&ai->i_crtime)); ++ ++ if (S_ISDIR(inode->i_mode)) { ++ inode_raw->nchildren = cpu_to_le32(ai->i_nchildren); ++ } else { ++ /* The remaining link for orphan inodes is not counted */ ++ inode_raw->nlink = cpu_to_le32(inode->i_nlink); ++ } ++ ++fail: ++ apfs_free_query(query); ++ return err; ++} ++ ++/** ++ * apfs_delete_inode - Delete an inode record ++ * @inode: the vfs inode to delete ++ * ++ * Returns 0 on success or a negative error code in case of failure, which may ++ * be -EAGAIN if the inode was not deleted in full. ++ */ ++static int apfs_delete_inode(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = NULL; ++ struct apfs_query *query; ++ u64 old_dstream_id; ++ int ret; ++ ++ ret = apfs_delete_all_xattrs(inode); ++ if (ret) { ++ apfs_err(sb, "xattr deletion failed for ino 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ ++ dstream = &ai->i_dstream; ++ old_dstream_id = dstream->ds_id; ++ ++ /* ++ * This is very wasteful since all the new extents and references will ++ * get deleted right away, but it only affects clones, so I don't see a ++ * big reason to improve it (TODO) ++ */ ++ ret = apfs_inode_create_exclusive_dstream(inode); ++ if (ret) { ++ apfs_err(sb, "dstream creation failed for ino 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ ++ /* TODO: what about partial deletion of xattrs? Is that allowed? */ ++ ret = apfs_inode_delete_front(inode); ++ if (ret) { ++ /* ++ * If the inode had too many extents, only the first few get ++ * deleted and the inode remains in the orphan list for now. ++ * I don't know why the deletion starts at the front, but it ++ * seems to be what the official driver does. ++ */ ++ if (ret != -EAGAIN) { ++ apfs_err(sb, "head deletion failed for ino 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ if (dstream->ds_id != old_dstream_id) { ++ ret = apfs_update_inode(inode, NULL /* new_name */); ++ if (ret) { ++ apfs_err(sb, "dstream id update failed for orphan 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ } ++ return -EAGAIN; ++ } ++ ++ ret = apfs_put_dstream_rec(dstream); ++ if (ret) { ++ apfs_err(sb, "failed to put dstream for ino 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ dstream = NULL; ++ ai->i_has_dstream = false; ++ ++ query = apfs_inode_lookup(inode); ++ if (IS_ERR(query)) { ++ apfs_err(sb, "lookup failed for ino 0x%llx", apfs_ino(inode)); ++ return PTR_ERR(query); ++ } ++ ret = apfs_btree_remove(query); ++ apfs_free_query(query); ++ if (ret) { ++ apfs_err(sb, "removal failed for ino 0x%llx", apfs_ino(inode)); ++ return ret; ++ } ++ ++ ai->i_cleaned = true; ++ return ret; ++} ++ ++/** ++ * apfs_clean_single_orphan - Clean the given orphan file ++ * @inode: inode for the file to clean ++ * ++ * Returns 0 on success or a negative error code in case of failure, which may ++ * be -EAGAIN if the file could not be deleted in full. ++ */ ++static int apfs_clean_single_orphan(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ u64 ino = apfs_ino(inode); ++ bool eagain = false; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_DEL); ++ if (err) ++ return err; ++ err = apfs_delete_inode(inode); ++ if (err) { ++ if (err != -EAGAIN) { ++ apfs_err(sb, "failed to delete orphan 0x%llx", ino); ++ goto fail; ++ } ++ eagain = true; ++ } else { ++ err = apfs_delete_orphan_link(inode); ++ if (err) { ++ apfs_err(sb, "failed to unlink orphan 0x%llx", ino); ++ goto fail; ++ } ++ } ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return eagain ? -EAGAIN : 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_clean_any_orphan - Pick an orphan and delete as much as reasonable ++ * @sb: filesystem superblock ++ * ++ * Returns 0 on success, or a negative error code in case of failure, which may ++ * be -ENODATA if there are no more orphan files or -EAGAIN if a file could not ++ * be deleted in full. ++ */ ++static int apfs_clean_any_orphan(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct inode *inode = NULL; ++ int err; ++ u64 ino; ++ ++ down_read(&nxi->nx_big_sem); ++ err = apfs_any_orphan_ino(sb, &ino); ++ up_read(&nxi->nx_big_sem); ++ if (err) { ++ if (err == -ENODATA) ++ return -ENODATA; ++ apfs_err(sb, "failed to find orphan inode numbers"); ++ return err; ++ } ++ ++ inode = apfs_iget(sb, ino); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ if (err != -ENODATA) { ++ apfs_err(sb, "iget failed for orphan 0x%llx", ino); ++ return err; ++ } ++ /* ++ * This happens rarely for files with no extents, if we hit a ++ * race with ->evict_inode(). Not a problem: the file is gone. ++ */ ++ apfs_notice(sb, "orphan 0x%llx not found", ino); ++ return 0; ++ } ++ ++ if (atomic_read(&inode->i_count) > 1) ++ goto out; ++ err = apfs_clean_single_orphan(inode); ++ if (err && err != -EAGAIN) { ++ apfs_err(sb, "failed to clean orphan 0x%llx", ino); ++ goto out; ++ } ++out: ++ iput(inode); ++ return err; ++} ++ ++/** ++ * apfs_schedule_orphan_cleanup - Schedule cleanup for orphan inodes ++ * @sb: filesystem superblock ++ */ ++void apfs_schedule_orphan_cleanup(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ ++ /* ++ * Don't schedule cleanups during unmount: completing all of it could ++ * take a while so just leave future mounts to handle the orphans. ++ */ ++ if (atomic_read(&sb->s_active) == 0) ++ return; ++ ++ /* ++ * Don't keep retrying orphan cleanups nonstop when they run into an ++ * unexpected error: it won't do any good and it will flood dmesg. We ++ * will retry eventually for ENOSPC, but that's handled elsewhere. ++ */ ++ if (atomic_read(&sbi->s_orphan_cleanup_err)) ++ return; ++ ++ schedule_work(&sbi->s_orphan_cleanup_work); ++} ++ ++/** ++ * apfs_clean_orphans - Delete as many orphan files as is reasonable ++ * @sb: filesystem superblock ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_clean_orphans(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ int ret, i; ++ ++ for (i = 0; i < 100; ++i) { ++ ret = apfs_clean_any_orphan(sb); ++ if (ret == 0) ++ continue; ++ if (ret == -ENODATA) ++ return 0; ++ if (ret == -EAGAIN) ++ break; ++ apfs_err(sb, "failed to delete an orphan file"); ++ atomic_set(&sbi->s_orphan_cleanup_err, ret); ++ return ret; ++ } ++ ++ /* ++ * If a file is too big, or if there are too many files, take a break ++ * and continue later. ++ */ ++ apfs_schedule_orphan_cleanup(sb); ++ return 0; ++} ++ ++void apfs_evict_inode(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ int err; ++ ++ if (is_bad_inode(inode) || inode->i_nlink || ai->i_cleaned) ++ goto out; ++ ++ if (!ai->i_has_dstream || ai->i_dstream.ds_size == 0) { ++ /* For files with no extents, scheduled cleanup wastes time */ ++ err = apfs_clean_single_orphan(inode); ++ if (err) { ++ apfs_err(sb, "failed to clean orphan 0x%llx (err:%d)", apfs_ino(inode), err); ++ atomic_set(&APFS_SB(sb)->s_orphan_cleanup_err, err); ++ } ++ goto out; ++ } ++ ++ /* If the inode still has extents then schedule cleanup for the rest */ ++ apfs_schedule_orphan_cleanup(sb); ++out: ++ truncate_inode_pages_final(&inode->i_data); ++ clear_inode(inode); ++} ++ ++void apfs_orphan_cleanup_work(struct work_struct *work) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_sb_info *sbi = NULL; ++ struct inode *priv = NULL; ++ int err; ++ ++ sbi = container_of(work, struct apfs_sb_info, s_orphan_cleanup_work); ++ priv = sbi->s_private_dir; ++ sb = priv->i_sb; ++ ++ if (sb->s_flags & SB_RDONLY) { ++ apfs_alert(sb, "attempt to flush orphans in read-only mount"); ++ return; ++ } ++ ++ err = apfs_clean_orphans(sb); ++ if (err) ++ apfs_err(sb, "orphan cleanup failed (err:%d)", err); ++} ++ ++/** ++ * apfs_insert_inode_locked - Wrapper for insert_inode_locked4() ++ * @inode: vfs inode to insert in cache ++ * ++ * Works the same as insert_inode_locked(), but can handle 64-bit inode numbers ++ * on 32-bit architectures. ++ */ ++static int apfs_insert_inode_locked(struct inode *inode) ++{ ++ u64 cnid = apfs_ino(inode); ++ ++ return insert_inode_locked4(inode, cnid, apfs_test_inode, &cnid); ++} ++ ++/** ++ * apfs_new_inode - Create a new in-memory inode ++ * @dir: parent inode ++ * @mode: mode bits for the new inode ++ * @rdev: device id (0 if not a device file) ++ * ++ * Returns a pointer to the new vfs inode on success, or an error pointer in ++ * case of failure. ++ */ ++struct inode *apfs_new_inode(struct inode *dir, umode_t mode, dev_t rdev) ++{ ++ struct super_block *sb = dir->i_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct inode *inode; ++ struct apfs_inode_info *ai; ++ struct apfs_dstream_info *dstream; ++ u64 cnid; ++ struct timespec64 now; ++ ++ /* Updating on-disk structures here is odd, but it works for now */ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ ++ inode = new_inode(sb); ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ ai = APFS_I(inode); ++ dstream = &ai->i_dstream; ++ ++ cnid = le64_to_cpu(vsb_raw->apfs_next_obj_id); ++ le64_add_cpu(&vsb_raw->apfs_next_obj_id, 1); ++ apfs_set_ino(inode, cnid); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ inode_init_owner(inode, dir, mode); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ inode_init_owner(&init_user_ns, inode, dir, mode); ++#else ++ inode_init_owner(&nop_mnt_idmap, inode, dir, mode); ++#endif ++ ++ ai->i_saved_uid = i_uid_read(inode); ++ ai->i_saved_gid = i_gid_read(inode); ++ ai->i_parent_id = apfs_ino(dir); ++ set_nlink(inode, 1); ++ ai->i_nchildren = 0; ++ if (apfs_vol_is_encrypted(sb) && S_ISREG(mode)) ++ ai->i_key_class = apfs_dflt_key_class(sb); ++ else ++ ai->i_key_class = 0; ++ ai->i_int_flags = APFS_INODE_NO_RSRC_FORK; ++ ai->i_bsd_flags = 0; ++ ++ ai->i_has_dstream = false; ++ dstream->ds_id = cnid; ++ dstream->ds_size = 0; ++ dstream->ds_sparse_bytes = 0; ++ dstream->ds_shared = false; ++ ++ now = current_time(inode); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_atime = inode->i_mtime = inode->i_ctime = ai->i_crtime = now; ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ inode_set_ctime_to_ts(inode, now); ++ inode->i_atime = inode->i_mtime = ai->i_crtime = now; ++#else ++ ai->i_crtime = simple_inode_init_ts(inode); ++#endif ++ vsb_raw->apfs_last_mod_time = cpu_to_le64(timespec64_to_ns(&now)); ++ ++ if (S_ISREG(mode)) ++ le64_add_cpu(&vsb_raw->apfs_num_files, 1); ++ else if (S_ISDIR(mode)) ++ le64_add_cpu(&vsb_raw->apfs_num_directories, 1); ++ else if (S_ISLNK(mode)) ++ le64_add_cpu(&vsb_raw->apfs_num_symlinks, 1); ++ else ++ le64_add_cpu(&vsb_raw->apfs_num_other_fsobjects, 1); ++ ++ if (apfs_insert_inode_locked(inode)) { ++ /* The inode number should have been free, but wasn't */ ++ apfs_err(sb, "next obj_id (0x%llx) not free", cnid); ++ make_bad_inode(inode); ++ iput(inode); ++ return ERR_PTR(-EFSCORRUPTED); ++ } ++ ++ /* No need to dirty the inode, we'll write it to disk right away */ ++ apfs_inode_set_ops(inode, rdev, false /* compressed */); ++ return inode; ++} ++ ++/** ++ * apfs_create_inode_rec - Create an inode record in the catalog b-tree ++ * @sb: filesystem superblock ++ * @inode: vfs inode to record ++ * @dentry: dentry for primary link ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_create_inode_rec(struct super_block *sb, struct inode *inode, ++ struct dentry *dentry) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_inode_key raw_key; ++ struct apfs_inode_val *raw_val; ++ int val_len; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_inode_key(apfs_ino(inode), &query->key); ++ query->flags |= APFS_QUERY_CAT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret && ret != -ENODATA) { ++ apfs_err(sb, "query failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ ++ apfs_key_set_hdr(APFS_TYPE_INODE, apfs_ino(inode), &raw_key); ++ ++ val_len = apfs_build_inode_val(inode, &dentry->d_name, &raw_val); ++ if (val_len < 0) { ++ ret = val_len; ++ goto fail; ++ } ++ ++ ret = apfs_btree_insert(query, &raw_key, sizeof(raw_key), raw_val, val_len); ++ if (ret) ++ apfs_err(sb, "insertion failed for ino 0x%llx", apfs_ino(inode)); ++ kfree(raw_val); ++ ++fail: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_setsize - Change the size of a regular file ++ * @inode: the vfs inode ++ * @new_size: the new size ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_setsize(struct inode *inode, loff_t new_size) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ int err; ++ ++ if (new_size == inode->i_size) ++ return 0; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_mtime = inode->i_ctime = current_time(inode); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) ++ inode->i_mtime = inode_set_ctime_current(inode); ++#else ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); ++#endif ++ ++ err = apfs_inode_create_dstream_rec(inode); ++ if (err) { ++ apfs_err(sb, "failed to create dstream for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ /* Must be called before i_size is changed */ ++ err = apfs_truncate(dstream, new_size); ++ if (err) { ++ apfs_err(sb, "truncation failed for ino 0x%llx", apfs_ino(inode)); ++ return err; ++ } ++ ++ truncate_setsize(inode, new_size); ++ dstream->ds_size = i_size_read(inode); ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++int apfs_setattr(struct dentry *dentry, struct iattr *iattr) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++int apfs_setattr(struct user_namespace *mnt_userns, ++ struct dentry *dentry, struct iattr *iattr) ++#else ++int apfs_setattr(struct mnt_idmap *idmap, ++ struct dentry *dentry, struct iattr *iattr) ++#endif ++{ ++ struct inode *inode = d_inode(dentry); ++ struct super_block *sb = inode->i_sb; ++ bool resizing = S_ISREG(inode->i_mode) && (iattr->ia_valid & ATTR_SIZE); ++ bool shrinking = false; ++ int err; ++ ++ if (resizing && iattr->ia_size > APFS_MAX_FILE_SIZE) ++ return -EFBIG; ++ if (resizing && iattr->ia_size < inode->i_size) ++ shrinking = true; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ err = setattr_prepare(dentry, iattr); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ err = setattr_prepare(&init_user_ns, dentry, iattr); ++#else ++ err = setattr_prepare(&nop_mnt_idmap, dentry, iattr); ++#endif ++ if (err) ++ return err; ++ ++ /* TODO: figure out why ->write_inode() isn't firing */ ++ err = apfs_transaction_start(sb, shrinking ? APFS_TRANS_DEL : APFS_TRANS_REG); ++ if (err) ++ return err; ++ apfs_inode_join_transaction(sb, inode); ++ ++ if (resizing) { ++ err = apfs_setsize(inode, iattr->ia_size); ++ if (err) { ++ apfs_err(sb, "setsize failed for ino 0x%llx", apfs_ino(inode)); ++ goto fail; ++ } ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ setattr_copy(inode, iattr); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ setattr_copy(&init_user_ns, inode, iattr); ++#else ++ setattr_copy(&nop_mnt_idmap, inode, iattr); ++#endif ++ ++ mark_inode_dirty(inode); ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/* TODO: this only seems to be necessary because ->write_inode() isn't firing */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++int apfs_update_time(struct inode *inode, struct timespec64 *time, int flags) ++#else ++int apfs_update_time(struct inode *inode, int flags) ++#endif ++{ ++ struct super_block *sb = inode->i_sb; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ apfs_inode_join_transaction(sb, inode); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && !RHEL_VERSION_GE(9, 6) ++ generic_update_time(inode, time, flags); ++#else ++ generic_update_time(inode, flags); ++#endif ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++static int apfs_ioc_set_dflt_pfk(struct file *file, void __user *user_pfk) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_wrapped_crypto_state pfk_hdr; ++ struct apfs_crypto_state_val *pfk; ++ unsigned int key_len; ++ ++ if (__copy_from_user(&pfk_hdr, user_pfk, sizeof(pfk_hdr))) ++ return -EFAULT; ++ key_len = le16_to_cpu(pfk_hdr.key_len); ++ if (key_len > MAX_PFK_LEN) ++ return -EFBIG; ++ pfk = kmalloc(sizeof(*pfk) + key_len, GFP_KERNEL); ++ if (!pfk) ++ return -ENOMEM; ++ if (__copy_from_user(&pfk->state, user_pfk, sizeof(pfk_hdr) + key_len)) { ++ kfree(pfk); ++ return -EFAULT; ++ } ++ pfk->refcnt = cpu_to_le32(1); ++ ++ down_write(&nxi->nx_big_sem); ++ ++ if (sbi->s_dflt_pfk) ++ kfree(sbi->s_dflt_pfk); ++ sbi->s_dflt_pfk = pfk; ++ ++ up_write(&nxi->nx_big_sem); ++ ++ return 0; ++} ++ ++static int apfs_ioc_set_dir_class(struct file *file, u32 __user *user_class) ++{ ++ struct inode *inode = file_inode(file); ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct super_block *sb = inode->i_sb; ++ u32 class; ++ int err; ++ ++ if (get_user(class, user_class)) ++ return -EFAULT; ++ ++ ai->i_key_class = class; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ apfs_inode_join_transaction(sb, inode); ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++static int apfs_ioc_set_pfk(struct file *file, void __user *user_pfk) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_wrapped_crypto_state pfk_hdr; ++ struct apfs_crypto_state_val *pfk; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ unsigned int key_len, key_class; ++ int err; ++ ++ if (__copy_from_user(&pfk_hdr, user_pfk, sizeof(pfk_hdr))) ++ return -EFAULT; ++ key_len = le16_to_cpu(pfk_hdr.key_len); ++ if (key_len > MAX_PFK_LEN) ++ return -EFBIG; ++ pfk = kmalloc(sizeof(*pfk) + key_len, GFP_KERNEL); ++ if (!pfk) ++ return -ENOMEM; ++ if (__copy_from_user(&pfk->state, user_pfk, sizeof(pfk_hdr) + key_len)) { ++ kfree(pfk); ++ return -EFAULT; ++ } ++ pfk->refcnt = cpu_to_le32(1); ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) { ++ kfree(pfk); ++ return err; ++ } ++ ++ err = apfs_crypto_set_key(sb, dstream->ds_id, pfk); ++ if (err) ++ goto fail; ++ ++ key_class = le32_to_cpu(pfk_hdr.persistent_class); ++ if (ai->i_key_class != key_class) { ++ ai->i_key_class = key_class; ++ apfs_inode_join_transaction(sb, inode); ++ } ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ kfree(pfk); ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ kfree(pfk); ++ return err; ++} ++ ++static int apfs_ioc_get_class(struct file *file, u32 __user *user_class) ++{ ++ struct inode *inode = file_inode(file); ++ struct apfs_inode_info *ai = APFS_I(inode); ++ u32 class; ++ ++ class = ai->i_key_class; ++ if (put_user(class, user_class)) ++ return -EFAULT; ++ return 0; ++} ++ ++static int apfs_ioc_get_pfk(struct file *file, void __user *user_pfk) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_wrapped_crypto_state pfk_hdr; ++ struct apfs_crypto_state_val *pfk; ++ unsigned int max_len, key_len; ++ struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream; ++ int err; ++ ++ if (__copy_from_user(&pfk_hdr, user_pfk, sizeof(pfk_hdr))) ++ return -EFAULT; ++ max_len = le16_to_cpu(pfk_hdr.key_len); ++ if (max_len > MAX_PFK_LEN) ++ return -EFBIG; ++ pfk = kmalloc(sizeof(*pfk) + max_len, GFP_KERNEL); ++ if (!pfk) ++ return -ENOMEM; ++ ++ down_read(&nxi->nx_big_sem); ++ ++ err = apfs_crypto_get_key(sb, dstream->ds_id, pfk, max_len); ++ if (err) ++ goto fail; ++ ++ up_read(&nxi->nx_big_sem); ++ ++ key_len = le16_to_cpu(pfk->state.key_len); ++ if (__copy_to_user(user_pfk, &pfk->state, sizeof(pfk_hdr) + key_len)) { ++ kfree(pfk); ++ return -EFAULT; ++ } ++ ++ kfree(pfk); ++ return 0; ++ ++fail: ++ up_read(&nxi->nx_big_sem); ++ kfree(pfk); ++ return err; ++} ++ ++/* ++ * Older kernels have no vfs_ioc_setflags_prepare(), so don't implement the ++ * SETFLAGS/GETFLAGS ioctls there. It should be easy to fix, but it's not ++ * really needed at all. Be careful with this macro check, because it nests ++ * over a few others. ++ */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) ++ ++/** ++ * apfs_getflags - Read an inode's bsd flags in FS_IOC_GETFLAGS format ++ * @inode: the vfs inode ++ */ ++static unsigned int apfs_getflags(struct inode *inode) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ unsigned int flags = 0; ++ ++ if (ai->i_bsd_flags & APFS_INOBSD_APPEND) ++ flags |= FS_APPEND_FL; ++ if (ai->i_bsd_flags & APFS_INOBSD_IMMUTABLE) ++ flags |= FS_IMMUTABLE_FL; ++ if (ai->i_bsd_flags & APFS_INOBSD_NODUMP) ++ flags |= FS_NODUMP_FL; ++ return flags; ++} ++ ++/** ++ * apfs_setflags - Set an inode's bsd flags ++ * @inode: the vfs inode ++ * @flags: flags to set, in FS_IOC_SETFLAGS format ++ */ ++static void apfs_setflags(struct inode *inode, unsigned int flags) ++{ ++ struct apfs_inode_info *ai = APFS_I(inode); ++ unsigned int i_flags = 0; ++ ++ if (flags & FS_APPEND_FL) { ++ ai->i_bsd_flags |= APFS_INOBSD_APPEND; ++ i_flags |= S_APPEND; ++ } else { ++ ai->i_bsd_flags &= ~APFS_INOBSD_APPEND; ++ } ++ ++ if (flags & FS_IMMUTABLE_FL) { ++ ai->i_bsd_flags |= APFS_INOBSD_IMMUTABLE; ++ i_flags |= S_IMMUTABLE; ++ } else { ++ ai->i_bsd_flags &= ~APFS_INOBSD_IMMUTABLE; ++ } ++ ++ if (flags & FS_NODUMP_FL) ++ ai->i_bsd_flags |= APFS_INOBSD_NODUMP; ++ else ++ ai->i_bsd_flags &= ~APFS_INOBSD_NODUMP; ++ ++ inode_set_flags(inode, i_flags, S_IMMUTABLE | S_APPEND); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) ++ ++/** ++ * apfs_ioc_getflags - Ioctl handler for FS_IOC_GETFLAGS ++ * @file: affected file ++ * @arg: ioctl argument ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_ioc_getflags(struct file *file, int __user *arg) ++{ ++ unsigned int flags = apfs_getflags(file_inode(file)); ++ ++ return put_user(flags, arg); ++} ++ ++/** ++ * apfs_do_ioc_setflags - Actual work for apfs_ioc_setflags(), after preparation ++ * @inode: affected vfs inode ++ * @newflags: inode flags to set, in FS_IOC_SETFLAGS format ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_do_ioc_setflags(struct inode *inode, unsigned int newflags) ++{ ++ struct super_block *sb = inode->i_sb; ++ unsigned int oldflags; ++ int err; ++ ++ lockdep_assert_held_write(&inode->i_rwsem); ++ ++ oldflags = apfs_getflags(inode); ++ err = vfs_ioc_setflags_prepare(inode, oldflags, newflags); ++ if (err) ++ return err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ apfs_inode_join_transaction(sb, inode); ++ apfs_setflags(inode, newflags); ++ inode->i_ctime = current_time(inode); ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_ioc_setflags - Ioctl handler for FS_IOC_SETFLAGS ++ * @file: affected file ++ * @arg: ioctl argument ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_ioc_setflags(struct file *file, int __user *arg) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ unsigned int newflags; ++ int err; ++ ++ if (sb->s_flags & SB_RDONLY) ++ return -EROFS; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ if (!inode_owner_or_capable(inode)) ++#else ++ if (!inode_owner_or_capable(&init_user_ns, inode)) ++#endif ++ return -EPERM; ++ ++ if (get_user(newflags, arg)) ++ return -EFAULT; ++ ++ if (newflags & ~(FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL)) ++ return -EOPNOTSUPP; ++ ++ err = mnt_want_write_file(file); ++ if (err) ++ return err; ++ ++ inode_lock(inode); ++ err = apfs_do_ioc_setflags(inode, newflags); ++ inode_unlock(inode); ++ ++ mnt_drop_write_file(file); ++ return err; ++} ++ ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ ++int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa) ++{ ++ unsigned int flags = apfs_getflags(d_inode(dentry)); ++ ++ fileattr_fill_flags(fa, flags); ++ return 0; ++} ++ ++int apfs_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa) ++{ ++ struct inode *inode = d_inode(dentry); ++ struct super_block *sb = inode->i_sb; ++ int err; ++ ++ if (sb->s_flags & SB_RDONLY) ++ return -EROFS; ++ ++ if (fa->flags & ~(FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL)) ++ return -EOPNOTSUPP; ++ if (fileattr_has_fsx(fa)) ++ return -EOPNOTSUPP; ++ ++ lockdep_assert_held_write(&inode->i_rwsem); ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ apfs_inode_join_transaction(sb, inode); ++ apfs_setflags(inode, fa->flags); ++ inode->i_ctime = current_time(inode); ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) */ ++ ++int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa) ++{ ++ unsigned int flags = apfs_getflags(d_inode(dentry)); ++ ++ fileattr_fill_flags(fa, flags); ++ return 0; ++} ++ ++int apfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa) ++{ ++ struct inode *inode = d_inode(dentry); ++ struct super_block *sb = inode->i_sb; ++ int err; ++ ++ if (sb->s_flags & SB_RDONLY) ++ return -EROFS; ++ ++ if (fa->flags & ~(FS_APPEND_FL | FS_IMMUTABLE_FL | FS_NODUMP_FL)) ++ return -EOPNOTSUPP; ++ if (fileattr_has_fsx(fa)) ++ return -EOPNOTSUPP; ++ ++ lockdep_assert_held_write(&inode->i_rwsem); ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ apfs_inode_join_transaction(sb, inode); ++ apfs_setflags(inode, fa->flags); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) ++ inode->i_ctime = current_time(inode); ++#else ++ inode_set_ctime_current(inode); ++#endif ++ ++ err = apfs_transaction_commit(sb); ++ if (err) ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) */ ++ ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) */ ++ ++long apfs_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ void __user *argp = (void __user *)arg; ++ ++ switch (cmd) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) ++ case FS_IOC_GETFLAGS: ++ return apfs_ioc_getflags(file, argp); ++ case FS_IOC_SETFLAGS: ++ return apfs_ioc_setflags(file, argp); ++#endif ++ case APFS_IOC_SET_DFLT_PFK: ++ return apfs_ioc_set_dflt_pfk(file, argp); ++ case APFS_IOC_SET_DIR_CLASS: ++ return apfs_ioc_set_dir_class(file, argp); ++ case APFS_IOC_GET_CLASS: ++ return apfs_ioc_get_class(file, argp); ++ case APFS_IOC_TAKE_SNAPSHOT: ++ return apfs_ioc_take_snapshot(file, argp); ++ default: ++ return -ENOTTY; ++ } ++} ++ ++long apfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ void __user *argp = (void __user *)arg; ++ ++ switch (cmd) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) ++ case FS_IOC_GETFLAGS: ++ return apfs_ioc_getflags(file, argp); ++ case FS_IOC_SETFLAGS: ++ return apfs_ioc_setflags(file, argp); ++#endif ++ case APFS_IOC_SET_PFK: ++ return apfs_ioc_set_pfk(file, argp); ++ case APFS_IOC_GET_CLASS: ++ return apfs_ioc_get_class(file, argp); ++ case APFS_IOC_GET_PFK: ++ return apfs_ioc_get_pfk(file, argp); ++ default: ++ return -ENOTTY; ++ } ++} +diff --git a/fs/apfs/key.c b/fs/apfs/key.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/key.c +@@ -0,0 +1,337 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include "apfs.h" ++#include "unicode.h" ++ ++/** ++ * apfs_filename_cmp - Normalize and compare two APFS filenames ++ * @sb: filesystem superblock ++ * @name1: first name to compare ++ * @len1: length of @name1 ++ * @name2: second name to compare ++ * @len2: length of the @name2 ++ * ++ * Returns 0 if @name1 and @name2 are equal, or non-zero otherwise. ++ */ ++int apfs_filename_cmp(struct super_block *sb, ++ const char *name1, unsigned int len1, ++ const char *name2, unsigned int len2) ++{ ++ struct apfs_unicursor cursor1, cursor2; ++ bool case_fold = apfs_is_case_insensitive(sb); ++ ++ if (!apfs_is_normalization_insensitive(sb)) { ++ if (len1 != len2) ++ return -1; ++ return memcmp(name1, name2, len1); ++ } ++ ++ apfs_init_unicursor(&cursor1, name1, len1); ++ apfs_init_unicursor(&cursor2, name2, len2); ++ ++ while (1) { ++ unicode_t uni1, uni2; ++ ++ uni1 = apfs_normalize_next(&cursor1, case_fold); ++ uni2 = apfs_normalize_next(&cursor2, case_fold); ++ ++ if (uni1 != uni2) ++ return uni1 < uni2 ? -1 : 1; ++ if (!uni1) ++ return 0; ++ } ++} ++ ++/** ++ * apfs_keycmp - Compare two keys ++ * @k1: first key to compare ++ * @k2: second key to compare ++ * ++ * returns 0 if @k1 and @k2 are equal ++ * < 0 if @k1 comes before @k2 in the btree ++ * > 0 if @k1 comes after @k2 in the btree ++ */ ++int apfs_keycmp(struct apfs_key *k1, struct apfs_key *k2) ++{ ++ if (k1->id != k2->id) ++ return k1->id < k2->id ? -1 : 1; ++ if (k1->type != k2->type) ++ return k1->type < k2->type ? -1 : 1; ++ if (k1->number != k2->number) ++ return k1->number < k2->number ? -1 : 1; ++ if (!k1->name || !k2->name) ++ return 0; ++ ++ /* Normalization seems to be ignored here, even for directory records */ ++ return strcmp(k1->name, k2->name); ++} ++ ++/** ++ * apfs_read_cat_key - Parse an on-disk catalog key ++ * @raw: pointer to the raw key ++ * @size: size of the raw key ++ * @key: apfs_key structure to store the result ++ * @hashed: are the directory records hashed? ++ * ++ * Returns 0 on success, or a negative error code otherwise. ++ */ ++int apfs_read_cat_key(void *raw, int size, struct apfs_key *key, bool hashed) ++{ ++ if (size < sizeof(struct apfs_key_header)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->id = apfs_cat_cnid((struct apfs_key_header *)raw); ++ key->type = apfs_cat_type((struct apfs_key_header *)raw); ++ ++ switch (key->type) { ++ case APFS_TYPE_DIR_REC: ++ if (hashed) { ++ if (size < sizeof(struct apfs_drec_hashed_key) + 1 || ++ *((char *)raw + size - 1) != 0) { ++ /* Filename must have NULL-termination */ ++ apfs_err(NULL, "invalid drec key (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ /* Name length is not used in key comparisons, only the hash */ ++ key->number = le32_to_cpu( ++ ((struct apfs_drec_hashed_key *)raw)->name_len_and_hash) & ++ APFS_DREC_HASH_MASK; ++ key->name = ((struct apfs_drec_hashed_key *)raw)->name; ++ } else { ++ if (size < sizeof(struct apfs_drec_key) + 1 || ++ *((char *)raw + size - 1) != 0) { ++ /* Filename must have NULL-termination */ ++ apfs_err(NULL, "invalid drec key (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ /* There's no hash */ ++ key->number = 0; ++ key->name = ((struct apfs_drec_key *)raw)->name; ++ } ++ break; ++ case APFS_TYPE_XATTR: ++ if (size < sizeof(struct apfs_xattr_key) + 1 || ++ *((char *)raw + size - 1) != 0) { ++ /* xattr name must have NULL-termination */ ++ apfs_err(NULL, "invalid xattr key (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->number = 0; ++ key->name = ((struct apfs_xattr_key *)raw)->name; ++ break; ++ case APFS_TYPE_FILE_EXTENT: ++ if (size != sizeof(struct apfs_file_extent_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->number = le64_to_cpu( ++ ((struct apfs_file_extent_key *)raw)->logical_addr); ++ key->name = NULL; ++ break; ++ case APFS_TYPE_SIBLING_LINK: ++ if (size != sizeof(struct apfs_sibling_link_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->number = le64_to_cpu( ++ ((struct apfs_sibling_link_key *)raw)->sibling_id); ++ key->name = NULL; ++ break; ++ default: ++ key->number = 0; ++ key->name = NULL; ++ break; ++ } ++ ++ return 0; ++} ++ ++int apfs_read_fext_key(void *raw, int size, struct apfs_key *key) ++{ ++ struct apfs_fext_tree_key *raw_key; ++ ++ if (size != sizeof(*raw_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ raw_key = raw; ++ ++ key->id = le64_to_cpu(raw_key->private_id); ++ key->type = 0; ++ key->number = le64_to_cpu(raw_key->logical_addr); ++ key->name = NULL; ++ return 0; ++} ++ ++/** ++ * apfs_read_free_queue_key - Parse an on-disk free queue key ++ * @raw: pointer to the raw key ++ * @size: size of the raw key ++ * @key: apfs_key structure to store the result ++ * ++ * Returns 0 on success, or a negative error code otherwise. ++ */ ++int apfs_read_free_queue_key(void *raw, int size, struct apfs_key *key) ++{ ++ struct apfs_spaceman_free_queue_key *raw_key; ++ ++ if (size != sizeof(*raw_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ raw_key = raw; ++ ++ key->id = le64_to_cpu(raw_key->sfqk_xid); ++ key->type = 0; ++ key->number = le64_to_cpu(raw_key->sfqk_paddr); ++ key->name = NULL; ++ ++ return 0; ++} ++ ++/** ++ * apfs_read_omap_key - Parse an on-disk object map key ++ * @raw: pointer to the raw key ++ * @size: size of the raw key ++ * @key: apfs_key structure to store the result ++ * ++ * Returns 0 on success, or a negative error code otherwise. ++ */ ++int apfs_read_omap_key(void *raw, int size, struct apfs_key *key) ++{ ++ struct apfs_omap_key *raw_key; ++ ++ if (size != sizeof(*raw_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ raw_key = raw; ++ ++ key->id = le64_to_cpu(raw_key->ok_oid); ++ key->type = 0; ++ key->number = le64_to_cpu(raw_key->ok_xid); ++ key->name = NULL; ++ ++ return 0; ++} ++ ++/** ++ * apfs_read_extentref_key - Parse an on-disk extent reference tree key ++ * @raw: pointer to the raw key ++ * @size: size of the raw key ++ * @key: apfs_key structure to store the result ++ * ++ * Returns 0 on success, or a negative error code otherwise. ++ */ ++int apfs_read_extentref_key(void *raw, int size, struct apfs_key *key) ++{ ++ if (size != sizeof(struct apfs_phys_ext_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->id = apfs_cat_cnid((struct apfs_key_header *)raw); ++ key->type = apfs_cat_type((struct apfs_key_header *)raw); ++ key->number = 0; ++ key->name = NULL; ++ return 0; ++} ++ ++int apfs_read_snap_meta_key(void *raw, int size, struct apfs_key *key) ++{ ++ if (size < sizeof(struct apfs_key_header)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->id = apfs_cat_cnid((struct apfs_key_header *)raw); ++ key->type = apfs_cat_type((struct apfs_key_header *)raw); ++ key->number = 0; ++ ++ switch (key->type) { ++ case APFS_TYPE_SNAP_METADATA: ++ if (size != sizeof(struct apfs_snap_metadata_key)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->name = NULL; ++ return 0; ++ case APFS_TYPE_SNAP_NAME: ++ if (size < sizeof(struct apfs_snap_name_key) + 1 || *((char *)raw + size - 1) != 0) { ++ /* snapshot name must have NULL-termination */ ++ apfs_err(NULL, "invalid snap name key (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ key->name = ((struct apfs_snap_name_key *)raw)->name; ++ return 0; ++ default: ++ return -EFSCORRUPTED; ++ } ++} ++ ++int apfs_read_omap_snap_key(void *raw, int size, struct apfs_key *key) ++{ ++ __le64 *xid = NULL; ++ ++ if (size != sizeof(*xid)) { ++ apfs_err(NULL, "bad key length (%d)", size); ++ return -EFSCORRUPTED; ++ } ++ xid = raw; ++ ++ key->id = le64_to_cpup(xid); ++ key->number = 0; ++ key->name = NULL; ++ key->type = 0; ++ return 0; ++} ++ ++/** ++ * apfs_init_drec_key - Initialize an in-memory key for a dentry query ++ * @sb: filesystem superblock ++ * @ino: inode number of the parent directory ++ * @name: filename (NULL for a multiple query) ++ * @name_len: filename length (0 if NULL) ++ * @key: apfs_key structure to initialize ++ */ ++void apfs_init_drec_key(struct super_block *sb, u64 ino, const char *name, ++ unsigned int name_len, struct apfs_key *key) ++{ ++ struct apfs_unicursor cursor; ++ bool case_fold = apfs_is_case_insensitive(sb); ++ u32 hash = 0xFFFFFFFF; ++ ++ key->id = ino; ++ key->type = APFS_TYPE_DIR_REC; ++ if (!apfs_is_normalization_insensitive(sb)) { ++ key->name = name; ++ key->number = 0; ++ return; ++ } ++ ++ /* To respect normalization, queries can only consider the hash */ ++ key->name = NULL; ++ ++ if (!name) { ++ key->number = 0; ++ return; ++ } ++ ++ apfs_init_unicursor(&cursor, name, name_len); ++ ++ while (1) { ++ unicode_t utf32; ++ ++ utf32 = apfs_normalize_next(&cursor, case_fold); ++ if (!utf32) ++ break; ++ ++ hash = crc32c(hash, &utf32, sizeof(utf32)); ++ } ++ ++ /* The filename length doesn't matter, so it's left as zero */ ++ key->number = hash << APFS_DREC_HASH_SHIFT; ++} +diff --git a/fs/apfs/libzbitmap.c b/fs/apfs/libzbitmap.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/libzbitmap.c +@@ -0,0 +1,442 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR MIT ++/* ++ * Copyright (C) 2022 Corellium LLC ++ * ++ * Author: Ernesto A. Fernández ++ * ++ * Ported from libzbitmap (https://github.com/eafer/libzbitmap). Only the ++ * decompression code is included. ++ */ ++ ++#include ++#include ++#include "libzbitmap.h" ++ ++#define ZBM_MAGIC "ZBM\x09" ++#define ZBM_MAGIC_SZ 4 ++ ++#define ZBM_MAX_DECMP_CHUNK_SIZE 0x8000 ++#define ZBM_MAX_DECMP_CHUNK_SIZE_BITS 15 ++ ++struct uint24 { ++ uint8_t low; ++ uint8_t mid; ++ uint8_t hig; ++}; ++ ++/* This header is shared by both compressed and decompressed chunks */ ++struct zbm_chunk_hdr { ++ struct uint24 len; /* Length of the chunk */ ++ struct uint24 decmp_len; /* Length of the chunk after decompression */ ++}; ++ ++/* The full header for compressed chunks */ ++struct zbm_cmp_chunk_hdr { ++ /* Shared with decompressed chunks */ ++ struct zbm_chunk_hdr hdr; ++ ++ /* Offset for each of the three metadata areas */ ++ struct uint24 meta_off_1; ++ struct uint24 meta_off_2; ++ struct uint24 meta_off_3; ++}; ++ ++/* Pointer to a half-byte */ ++struct nybl_ptr { ++ uint8_t *addr; /* Address of the byte */ ++ int nibble; /* Which of the two nibbles? */ ++}; ++ ++/* 0-2 and 0xf are not real bitmap indexes */ ++#define ZBM_BITMAP_COUNT (16 - 1 - 3) ++#define ZBM_BITMAP_BASE 3 ++#define ZBM_BITMAP_BYTECNT 17 ++#define ZBM_MAX_PERIOD_BYTECNT 2 ++ ++struct zbm_bmap { ++ uint8_t bitmap; /* The bitmap */ ++ uint8_t period_bytecnt; /* Read this many bytes to get the new period */ ++}; ++ ++struct zbm_state { ++ /* Updated during a chunk read */ ++ uint8_t *dest; /* Write the next byte here */ ++ size_t dest_left; /* Room left in destination buffer */ ++ uint32_t written; /* Bytes written so far for current chunk */ ++ uint16_t period; /* Repetition period for decompression, in bytes */ ++ ++ /* Updated right before a chunk read */ ++ const uint8_t *src_end; /* End of current chunk */ ++ uint32_t len; /* Length of the chunk */ ++ uint32_t decmp_len; /* Expected chunk length after decompression */ ++ ++ /* Updated after a chunk read */ ++ const uint8_t *src; /* Start of buffer, or current chunk if any */ ++ size_t src_left; /* Room left in the source buffer */ ++ size_t prewritten; /* Bytes written for previous chunks */ ++ ++ /* Current position in data and metadata areas for this chunk */ ++ const uint8_t *data; ++ const uint8_t *meta_1; ++ const uint8_t *meta_2; ++ struct nybl_ptr meta_3; ++ ++ /* Array of bitmaps for the current chunk */ ++ struct zbm_bmap bitmaps[ZBM_BITMAP_COUNT]; ++}; ++ ++static int zbm_check_magic(struct zbm_state *state) ++{ ++ if(state->src_left < ZBM_MAGIC_SZ) ++ return -EINVAL; ++ ++ if(memcmp(state->src, ZBM_MAGIC, ZBM_MAGIC_SZ)) ++ return -EINVAL; ++ ++ state->src += ZBM_MAGIC_SZ; ++ state->src_left -= ZBM_MAGIC_SZ; ++ return 0; ++} ++ ++static uint32_t zbm_u24_to_u32(struct uint24 n) ++{ ++ uint32_t res; ++ ++ res = n.hig; ++ res <<= 8; ++ res += n.mid; ++ res <<= 8; ++ res += n.low; ++ return res; ++} ++ ++/* Some chunks just have regular uncompressed data, but with a header */ ++static int zbm_chunk_is_uncompressed(struct zbm_state *state) ++{ ++ return state->len == state->decmp_len + sizeof(struct zbm_chunk_hdr); ++} ++ ++static int zbm_handle_uncompressed_chunk(struct zbm_state *state) ++{ ++ state->meta_1 = state->meta_2 = NULL; ++ state->meta_3.addr = NULL; ++ state->meta_3.nibble = 0; ++ state->data = state->src + sizeof(struct zbm_chunk_hdr); ++ memcpy(state->dest, state->data, state->decmp_len); ++ ++ state->dest += state->decmp_len; ++ state->dest_left -= state->decmp_len; ++ state->written = state->decmp_len; ++ return 0; ++} ++ ++static int zbm_read_nibble(struct nybl_ptr *nybl, const uint8_t *limit, uint8_t *result) ++{ ++ if(nybl->addr >= limit) ++ return -EINVAL; ++ ++ if(nybl->nibble == 0) { ++ *result = *nybl->addr & 0xf; ++ nybl->nibble = 1; ++ } else { ++ *result = (*nybl->addr >> 4) & 0xf; ++ nybl->nibble = 0; ++ ++nybl->addr; ++ } ++ return 0; ++} ++ ++static void zbm_rewind_nibble(struct nybl_ptr *nybl) ++{ ++ if(nybl->nibble == 0) { ++ nybl->nibble = 1; ++ --nybl->addr; ++ } else { ++ nybl->nibble = 0; ++ } ++} ++ ++static int zbm_apply_bitmap(struct zbm_state *state, struct zbm_bmap *bitmap) ++{ ++ int i; ++ ++ /* The periods are stored in the first metadata area */ ++ if(bitmap->period_bytecnt) { ++ state->period = 0; ++ for(i = 0; i < bitmap->period_bytecnt; ++i) { ++ if(state->meta_1 >= state->src_end) ++ return -EINVAL; ++ state->period |= *state->meta_1 << i * 8; ++ ++state->meta_1; ++ } ++ } ++ if(state->period == 0) ++ return -EINVAL; ++ ++ for(i = 0; i < 8; ++i) { ++ if(state->written == state->decmp_len) ++ break; ++ if(bitmap->bitmap & 1 << i) { ++ if(state->data >= state->src_end) ++ return -EINVAL; ++ *state->dest = *state->data; ++ ++state->data; ++ } else { ++ if(state->prewritten + state->written < state->period) ++ return -EINVAL; ++ *state->dest = *(state->dest - state->period); ++ } ++ ++state->dest; ++ --state->dest_left; ++ ++state->written; ++ } ++ ++ return 0; ++} ++ ++static int zbm_apply_bitmap_number(struct zbm_state *state, uint8_t bmp_num) ++{ ++ struct zbm_bmap next = {0}; ++ ++ /* Not a valid bitmap number (it signals a repetition) */ ++ if(bmp_num == 0xf) ++ return -EINVAL; ++ ++ /* An actual index in the bitmap array */ ++ if(bmp_num > ZBM_MAX_PERIOD_BYTECNT) ++ return zbm_apply_bitmap(state, &state->bitmaps[bmp_num - ZBM_BITMAP_BASE]); ++ ++ /* For < 2, use the next bitmap in the second metadata area */ ++ if(state->meta_2 >= state->src_end) ++ return -EINVAL; ++ next.bitmap = *state->meta_2; ++ next.period_bytecnt = bmp_num; ++ ++state->meta_2; ++ return zbm_apply_bitmap(state, &next); ++} ++ ++/* Find out how many times we need to repeat the current bitmap operation */ ++static int zbm_read_repetition_count(struct zbm_state *state, uint16_t *repeat) ++{ ++ uint8_t nibble; ++ uint16_t total; ++ int err; ++ ++ /* Don't confuse the trailing bitmaps with a repetition count */ ++ if(state->decmp_len - state->written <= 8) { ++ *repeat = 1; ++ return 0; ++ } ++ ++ err = zbm_read_nibble(&state->meta_3, state->src_end, &nibble); ++ if(err) ++ return err; ++ ++ if(nibble != 0xf) { ++ /* No repetition count: the previous bitmap number gets applied once */ ++ zbm_rewind_nibble(&state->meta_3); ++ *repeat = 1; ++ return 0; ++ } ++ ++ /* ++ * Under this scheme, repeating a bitmap number 3 times wouldn't save any ++ * space, so the repetition count starts from 4. ++ */ ++ total = 4; ++ while(nibble == 0xf) { ++ err = zbm_read_nibble(&state->meta_3, state->src_end, &nibble); ++ if(err) ++ return err; ++ total += nibble; ++ if(total < nibble) ++ return -EINVAL; ++ } ++ ++ *repeat = total; ++ return 0; ++} ++ ++static int zbm_decompress_single_bitmap(struct zbm_state *state) ++{ ++ uint8_t bmp_num; ++ uint16_t repeat; ++ int i; ++ int err; ++ ++ /* The current nibble is the offset of the next bitmap to apply */ ++ err = zbm_read_nibble(&state->meta_3, state->src_end, &bmp_num); ++ if(err) ++ return err; ++ ++ err = zbm_read_repetition_count(state, &repeat); ++ if(err) ++ return err; ++ ++ for(i = 0; i < repeat; ++i) { ++ err = zbm_apply_bitmap_number(state, bmp_num); ++ if(err) ++ return err; ++ } ++ return 0; ++} ++ ++/* Pointer to a bit */ ++struct bit_ptr { ++ uint8_t *addr; /* Address of the byte */ ++ int offset; /* Bit number */ ++}; ++ ++/* This function does not perform boundary checks, the caller must do it */ ++static int zbm_read_single_bit(struct bit_ptr *bit) ++{ ++ int res = *bit->addr >> bit->offset & 1; ++ ++ ++bit->offset; ++ if(bit->offset != 8) ++ return res; ++ bit->offset = 0; ++ ++bit->addr; ++ return res; ++} ++ ++static int zbm_read_single_bitmap(struct bit_ptr *bit, const uint8_t *limit, struct zbm_bmap *result) ++{ ++ int i; ++ ++ result->bitmap = 0; ++ result->period_bytecnt = 0; ++ ++ /* The bitmap itself */ ++ for(i = 0; i < 8; ++i) { ++ if(bit->addr >= limit) ++ return -EINVAL; ++ result->bitmap |= zbm_read_single_bit(bit) << i; ++ } ++ ++ /* ++ * The two trailing bits tell us how many bytes to read for the next ++ * repetition period ++ */ ++ for(i = 0; i < 2; ++i) { ++ if(bit->addr >= limit) ++ return -EINVAL; ++ result->period_bytecnt |= zbm_read_single_bit(bit) << i; ++ } ++ ++ return 0; ++} ++ ++static int zbm_read_bitmaps(struct zbm_state *state) ++{ ++ struct bit_ptr bmap = {0}; ++ int err, i; ++ ++ if(state->len < ZBM_BITMAP_BYTECNT) ++ return -EINVAL; ++ ++ bmap.addr = (uint8_t *)state->src_end - ZBM_BITMAP_BYTECNT; ++ bmap.offset = 0; ++ ++ for(i = 0; i < ZBM_BITMAP_COUNT; ++i) { ++ err = zbm_read_single_bitmap(&bmap, state->src_end, &state->bitmaps[i]); ++ if(err) ++ return err; ++ if(state->bitmaps[i].period_bytecnt > ZBM_MAX_PERIOD_BYTECNT) ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int zbm_handle_compressed_chunk(struct zbm_state *state) ++{ ++ const struct zbm_cmp_chunk_hdr *hdr = NULL; ++ uint32_t meta_off_1, meta_off_2, meta_off_3; ++ int err; ++ ++ state->written = 0; ++ state->period = 8; ++ ++ if(state->len < sizeof(*hdr)) ++ return -EINVAL; ++ hdr = (struct zbm_cmp_chunk_hdr *)state->src; ++ state->data = state->src + sizeof(*hdr); ++ ++ meta_off_1 = zbm_u24_to_u32(hdr->meta_off_1); ++ meta_off_2 = zbm_u24_to_u32(hdr->meta_off_2); ++ meta_off_3 = zbm_u24_to_u32(hdr->meta_off_3); ++ if(meta_off_1 >= state->len || meta_off_2 >= state->len || meta_off_3 >= state->len) ++ return -EINVAL; ++ state->meta_1 = state->src + meta_off_1; ++ state->meta_2 = state->src + meta_off_2; ++ state->meta_3.addr = (uint8_t *)state->src + meta_off_3; ++ state->meta_3.nibble = 0; ++ ++ err = zbm_read_bitmaps(state); ++ if(err) ++ return err; ++ ++ while(state->written < state->decmp_len) { ++ err = zbm_decompress_single_bitmap(state); ++ if(err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static int zbm_handle_chunk(struct zbm_state *state) ++{ ++ const struct zbm_chunk_hdr *decmp_hdr = NULL; ++ ++ if(state->src_left < sizeof(*decmp_hdr)) ++ return -EINVAL; ++ decmp_hdr = (struct zbm_chunk_hdr *)state->src; ++ ++ state->len = zbm_u24_to_u32(decmp_hdr->len); ++ if(state->len > state->src_left) ++ return -EINVAL; ++ state->src_end = state->src + state->len; ++ ++ state->decmp_len = zbm_u24_to_u32(decmp_hdr->decmp_len); ++ if(state->decmp_len > ZBM_MAX_DECMP_CHUNK_SIZE) ++ return -EINVAL; ++ if(!state->dest) /* We just wanted the length, so we are done */ ++ return 0; ++ if(state->decmp_len > state->dest_left) ++ return -ERANGE; ++ ++ if(zbm_chunk_is_uncompressed(state)) ++ return zbm_handle_uncompressed_chunk(state); ++ ++ return zbm_handle_compressed_chunk(state); ++} ++ ++int zbm_decompress(void *dest, size_t dest_size, const void *src, size_t src_size, size_t *out_len) ++{ ++ struct zbm_state state = {0}; ++ int err; ++ ++ state.src = src; ++ state.src_left = src_size; ++ state.dest = dest; ++ state.dest_left = dest_size; ++ state.prewritten = 0; ++ ++ err = zbm_check_magic(&state); ++ if(err) ++ return err; ++ ++ /* The final chunk has zero decompressed length */ ++ do { ++ err = zbm_handle_chunk(&state); ++ if(err) ++ return err; ++ state.src += state.len; ++ state.src_left -= state.len; ++ state.prewritten += state.decmp_len; ++ } while(state.decmp_len != 0); ++ ++ *out_len = state.prewritten; ++ return 0; ++} +diff --git a/fs/apfs/libzbitmap.h b/fs/apfs/libzbitmap.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/libzbitmap.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR MIT */ ++/* ++ * Copyright (c) 2022 Corellium LLC ++ * ++ * Author: Ernesto A. Fernández ++ * ++ * Ported from libzbitmap (https://github.com/eafer/libzbitmap). Only the ++ * decompression code is included. ++ */ ++ ++#ifndef _LIBZBITMAP_H ++#define _LIBZBITMAP_H ++ ++#include ++#include ++ ++/** ++ * zbm_decompress - Decompress an LZBITMAP buffer ++ * @dest: destination buffer (may be NULL) ++ * @dest_size: size of the destination buffer ++ * @src: source buffer ++ * @src_size: size of the source buffer ++ * @out_len: on return, the length of the decompressed output ++ * ++ * May be called with a NULL destination buffer to retrieve the expected length ++ * of the decompressed data. Returns 0 on success, or a negative error code in ++ * case of failure. ++ */ ++int zbm_decompress(void *dest, size_t dest_size, const void *src, size_t src_size, size_t *out_len); ++ ++#endif /* _LIBZBITMAP_H */ +diff --git a/fs/apfs/lzfse/lzfse.h b/fs/apfs/lzfse/lzfse.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse.h +@@ -0,0 +1,67 @@ ++/* SPDX-License-Identifier: BSD-3-Clause */ ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef LZFSE_H ++#define LZFSE_H ++ ++#include ++#include ++ ++/*! @abstract Get the required scratch buffer size to decompress using LZFSE. */ ++size_t lzfse_decode_scratch_size(void); ++ ++/*! @abstract Decompress a buffer using LZFSE. ++ * ++ * @param dst_buffer ++ * Pointer to the first byte of the destination buffer. ++ * ++ * @param dst_size ++ * Size of the destination buffer in bytes. ++ * ++ * @param src_buffer ++ * Pointer to the first byte of the source buffer. ++ * ++ * @param src_size ++ * Size of the source buffer in bytes. ++ * ++ * @param scratch_buffer ++ * If non-NULL, a pointer to scratch space for the routine to use as workspace; ++ * the routine may use up to lzfse_decode_scratch_size( ) bytes of workspace ++ * during its operation, and will not perform any internal allocations. If ++ * NULL, the routine may allocate its own memory to use during operation via ++ * a single call to malloc( ), and will release it by calling free( ) prior ++ * to returning. For most use, passing NULL is perfectly satisfactory, but if ++ * you require strict control over allocation, you will want to pass an ++ * explicit scratch buffer. ++ * ++ * @return ++ * The number of bytes written to the destination buffer if the input is ++ * successfully decompressed. If there is not enough space in the destination ++ * buffer to hold the entire expanded output, only the first dst_size bytes ++ * will be written to the buffer and dst_size is returned. Note that this ++ * behavior differs from that of lzfse_encode_buffer. ++ */ ++size_t lzfse_decode_buffer(uint8_t *__restrict dst_buffer, size_t dst_size, ++ const uint8_t *__restrict src_buffer, size_t src_size, ++ void *__restrict scratch_buffer); ++ ++#endif /* LZFSE_H */ +diff --git a/fs/apfs/lzfse/lzfse_decode.c b/fs/apfs/lzfse/lzfse_decode.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse_decode.c +@@ -0,0 +1,80 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* LZFSE decode API */ ++ ++#include ++#include "lzfse.h" ++#include "lzfse_internal.h" ++ ++size_t lzfse_decode_scratch_size(void) ++{ ++ return sizeof(lzfse_decoder_state); ++} ++ ++static size_t lzfse_decode_buffer_with_scratch(uint8_t *__restrict dst_buffer, size_t dst_size, ++ const uint8_t *__restrict src_buffer, ++ size_t src_size, void *__restrict scratch_buffer) ++{ ++ int status; ++ lzfse_decoder_state *s = (lzfse_decoder_state *)scratch_buffer; ++ ++ memset(s, 0x00, sizeof(*s)); ++ ++ /* Initialize state */ ++ s->src = src_buffer; ++ s->src_begin = src_buffer; ++ s->src_end = s->src + src_size; ++ s->dst = dst_buffer; ++ s->dst_begin = dst_buffer; ++ s->dst_end = dst_buffer + dst_size; ++ ++ /* Decode */ ++ status = lzfse_decode(s); ++ if (status == LZFSE_STATUS_DST_FULL) ++ return dst_size; ++ if (status != LZFSE_STATUS_OK) ++ return 0; /* failed */ ++ return (size_t)(s->dst - dst_buffer); /* bytes written */ ++} ++ ++size_t lzfse_decode_buffer(uint8_t *__restrict dst_buffer, size_t dst_size, ++ const uint8_t *__restrict src_buffer, size_t src_size, ++ void *__restrict scratch_buffer) ++{ ++ int has_malloc = 0; ++ size_t ret = 0; ++ ++ /* Deal with the possible NULL pointer */ ++ if (scratch_buffer == NULL) { ++ /* +1 in case scratch size could be zero */ ++ scratch_buffer = kmalloc(lzfse_decode_scratch_size() + 1, GFP_KERNEL); ++ has_malloc = 1; ++ } ++ if (scratch_buffer == NULL) ++ return 0; ++ ret = lzfse_decode_buffer_with_scratch(dst_buffer, dst_size, src_buffer, src_size, ++ scratch_buffer); ++ if (has_malloc) ++ kfree(scratch_buffer); ++ return ret; ++} +diff --git a/fs/apfs/lzfse/lzfse_decode_base.c b/fs/apfs/lzfse/lzfse_decode_base.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse_decode_base.c +@@ -0,0 +1,743 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "lzfse_internal.h" ++#include "lzvn_decode_base.h" ++ ++/*! @abstract Decode an entry value from next bits of stream. ++ * Return \p value, and set \p *nbits to the number of bits to consume ++ * (starting with LSB). ++ */ ++static inline int lzfse_decode_v1_freq_value(uint32_t bits, int *nbits) ++{ ++ static const int8_t lzfse_freq_nbits_table[32] = { 2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, ++ 5, 2, 3, 2, 14, 2, 3, 2, 5, 2, 3, ++ 2, 8, 2, 3, 2, 5, 2, 3, 2, 14 }; ++ static const int8_t lzfse_freq_value_table[32] = { 0, 2, 1, 4, 0, 3, 1, -1, 0, 2, 1, ++ 5, 0, 3, 1, -1, 0, 2, 1, 6, 0, 3, ++ 1, -1, 0, 2, 1, 7, 0, 3, 1, -1 }; ++ ++ uint32_t b = bits & 31; /* lower 5 bits */ ++ int n = lzfse_freq_nbits_table[b]; ++ *nbits = n; ++ ++ /* Special cases for > 5 bits encoding */ ++ if (n == 8) ++ return 8 + ((bits >> 4) & 0xf); ++ if (n == 14) ++ return 24 + ((bits >> 4) & 0x3ff); ++ ++ // <= 5 bits encoding from table ++ return lzfse_freq_value_table[b]; ++} ++ ++/*! @abstract Extracts up to 32 bits from a 64-bit field beginning at ++ * \p offset, and zero-extends them to a \p uint32_t. ++ * ++ * If we number the bits of \p v from 0 (least significant) to 63 (most ++ * significant), the result is bits \p offset to \p offset+nbits-1. ++ */ ++static inline uint32_t get_field(uint64_t v, int offset, int nbits) ++{ ++ if (nbits == 32) ++ return (uint32_t)(v >> offset); ++ return (uint32_t)((v >> offset) & ((1 << nbits) - 1)); ++} ++ ++/*! @abstract Return \c header_size field from a \c lzfse_compressed_block_header_v2. */ ++static inline uint32_t lzfse_decode_v2_header_size(const lzfse_compressed_block_header_v2 *in) ++{ ++ return get_field(in->packed_fields[2], 0, 32); ++} ++ ++/*! @abstract Decode all fields from a \c lzfse_compressed_block_header_v2 to a ++ * \c lzfse_compressed_block_header_v1. ++ * @return 0 on success. ++ * @return -1 on failure. ++ */ ++static inline int lzfse_decode_v1(lzfse_compressed_block_header_v1 *out, ++ const lzfse_compressed_block_header_v2 *in) ++{ ++ uint64_t v0; ++ uint64_t v1; ++ uint64_t v2; ++ uint16_t *dst = NULL; ++ const uint8_t *src = NULL; ++ const uint8_t *src_end = NULL; ++ uint32_t accum = 0; ++ int accum_nbits = 0; ++ int nbits = 0; ++ int i; ++ ++ /* Clear all fields */ ++ memset(out, 0x00, sizeof(lzfse_compressed_block_header_v1)); ++ ++ v0 = in->packed_fields[0]; ++ v1 = in->packed_fields[1]; ++ v2 = in->packed_fields[2]; ++ ++ out->magic = LZFSE_COMPRESSEDV1_BLOCK_MAGIC; ++ out->n_raw_bytes = in->n_raw_bytes; ++ ++ /* Literal state */ ++ out->n_literals = get_field(v0, 0, 20); ++ out->n_literal_payload_bytes = get_field(v0, 20, 20); ++ out->literal_bits = (int)get_field(v0, 60, 3) - 7; ++ out->literal_state[0] = get_field(v1, 0, 10); ++ out->literal_state[1] = get_field(v1, 10, 10); ++ out->literal_state[2] = get_field(v1, 20, 10); ++ out->literal_state[3] = get_field(v1, 30, 10); ++ ++ /* L,M,D state */ ++ out->n_matches = get_field(v0, 40, 20); ++ out->n_lmd_payload_bytes = get_field(v1, 40, 20); ++ out->lmd_bits = (int)get_field(v1, 60, 3) - 7; ++ out->l_state = get_field(v2, 32, 10); ++ out->m_state = get_field(v2, 42, 10); ++ out->d_state = get_field(v2, 52, 10); ++ ++ /* Total payload size */ ++ out->n_payload_bytes = out->n_literal_payload_bytes + out->n_lmd_payload_bytes; ++ ++ /* Freq tables */ ++ dst = &(out->l_freq[0]); ++ src = &(in->freq[0]); ++ src_end = (const uint8_t *)in + get_field(v2, 0, 32); /* first byte after header */ ++ accum = 0; ++ accum_nbits = 0; ++ ++ /* No freq tables? */ ++ if (src_end == src) ++ return 0; /* OK, freq tables were omitted */ ++ ++ for (i = 0; i < LZFSE_ENCODE_L_SYMBOLS + LZFSE_ENCODE_M_SYMBOLS + LZFSE_ENCODE_D_SYMBOLS + ++ LZFSE_ENCODE_LITERAL_SYMBOLS; ++ i++) { ++ /* ++ * Refill accum, one byte at a time, until we reach end of ++ * header, or accum is full ++ */ ++ while (src < src_end && accum_nbits + 8 <= 32) { ++ accum |= (uint32_t)(*src) << accum_nbits; ++ accum_nbits += 8; ++ src++; ++ } ++ ++ /* Decode and store value */ ++ nbits = 0; ++ dst[i] = lzfse_decode_v1_freq_value(accum, &nbits); ++ ++ if (nbits > accum_nbits) ++ return -1; /* failed */ ++ ++ /* Consume nbits bits */ ++ accum >>= nbits; ++ accum_nbits -= nbits; ++ } ++ ++ if (accum_nbits >= 8 || src != src_end) ++ return -1; /* we need to end up exactly at the end of header, with less than 8 bits in accumulator */ ++ ++ return 0; ++} ++ ++static inline void copy(uint8_t *dst, const uint8_t *src, size_t length) ++{ ++ const uint8_t *dst_end = dst + length; ++ ++ do { ++ copy8(dst, src); ++ dst += 8; ++ src += 8; ++ } while (dst < dst_end); ++} ++ ++static int lzfse_decode_lmd(lzfse_decoder_state *s) ++{ ++ lzfse_compressed_block_decoder_state *bs = &(s->compressed_lzfse_block_state); ++ fse_state l_state = bs->l_state; ++ fse_state m_state = bs->m_state; ++ fse_state d_state = bs->d_state; ++ fse_in_stream in = bs->lmd_in_stream; ++ const uint8_t *src_start = s->src_begin; ++ const uint8_t *src = s->src + bs->lmd_in_buf; ++ const uint8_t *lit = bs->current_literal; ++ uint8_t *dst = s->dst; ++ uint32_t symbols = bs->n_matches; ++ int32_t L = bs->l_value; ++ int32_t M = bs->m_value; ++ int32_t D = bs->d_value; ++ int32_t new_d; ++ ++ /* ++ * Number of bytes remaining in the destination buffer, minus 32 to ++ * provide a margin of safety for using overlarge copies on the fast ++ * path. This is a signed quantity, and may go negative when we are ++ * close to the end of the buffer. That's OK; we're careful about how ++ * we handle it in the slow-and-careful match execution path. ++ */ ++ ptrdiff_t remaining_bytes = s->dst_end - dst - 32; ++ ++ /* ++ * If L or M is non-zero, that means that we have already started ++ * decoding this block, and that we needed to interrupt decoding to get ++ * more space from the caller. There's a pending L, M, D triplet that ++ * we weren't able to completely process. Jump ahead to finish executing ++ * that symbol before decoding new values. ++ */ ++ if (L || M) ++ goto ExecuteMatch; ++ ++ while (symbols > 0) { ++ int res; ++ /* Decode the next L, M, D symbol from the input stream. */ ++ res = fse_in_flush(&in, &src, src_start); ++ if (res) ++ return LZFSE_STATUS_ERROR; ++ L = fse_value_decode(&l_state, bs->l_decoder, &in); ++ if ((lit + L) >= (bs->literals + LZFSE_LITERALS_PER_BLOCK + 64)) ++ return LZFSE_STATUS_ERROR; ++ res = fse_in_flush2(&in, &src, src_start); ++ if (res) ++ return LZFSE_STATUS_ERROR; ++ M = fse_value_decode(&m_state, bs->m_decoder, &in); ++ res = fse_in_flush2(&in, &src, src_start); ++ if (res) ++ return LZFSE_STATUS_ERROR; ++ new_d = fse_value_decode(&d_state, bs->d_decoder, &in); ++ D = new_d ? new_d : D; ++ symbols--; ++ ++ExecuteMatch: ++ /* ++ * Error if D is out of range, so that we avoid passing through ++ * uninitialized data or accesssing memory out of the ++ * destination buffer. ++ */ ++ if ((uint32_t)D > dst + L - s->dst_begin) ++ return LZFSE_STATUS_ERROR; ++ ++ if (L + M <= remaining_bytes) { ++ size_t i; ++ /* ++ * If we have plenty of space remaining, we can copy the ++ * literal and match with 16- and 32-byte operations, ++ * without worrying about writing off the end of the ++ * buffer. ++ */ ++ remaining_bytes -= L + M; ++ copy(dst, lit, L); ++ dst += L; ++ lit += L; ++ /* ++ * For the match, we have two paths; a fast copy by ++ * 16-bytes if the match distance is large enough to ++ * allow it, and a more careful path that applies a ++ * permutation to account for the possible overlap ++ * between source and destination if the distance is ++ * small. ++ */ ++ if (D >= 8 || D >= M) ++ copy(dst, dst - D, M); ++ else ++ for (i = 0; i < M; i++) ++ dst[i] = dst[i - D]; ++ dst += M; ++ } ++ ++ else { ++ /* ++ * Otherwise, we are very close to the end of the ++ * destination buffer, so we cannot use wide copies that ++ * slop off the end of the region that we are copying ++ * to. First, we restore the true length remaining, ++ * rather than the sham value we've been using so far. ++ */ ++ remaining_bytes += 32; ++ /* ++ * Now, we process the literal. Either there's space for ++ * it or there isn't; if there is, we copy the whole ++ * thing and update all the pointers and lengths to ++ * reflect the copy. ++ */ ++ if (L <= remaining_bytes) { ++ size_t i; ++ ++ for (i = 0; i < L; i++) ++ dst[i] = lit[i]; ++ dst += L; ++ lit += L; ++ remaining_bytes -= L; ++ L = 0; ++ } ++ /* ++ * There isn't enough space to fit the whole literal. ++ * Copy as much of it as we can, update the pointers and ++ * the value of L, and report that the destination ++ * buffer is full. Note that we always write right up to ++ * the end of the destination buffer. ++ */ ++ else { ++ size_t i; ++ ++ for (i = 0; i < remaining_bytes; i++) ++ dst[i] = lit[i]; ++ dst += remaining_bytes; ++ lit += remaining_bytes; ++ L -= remaining_bytes; ++ goto DestinationBufferIsFull; ++ } ++ /* ++ * The match goes just like the literal does. We copy as ++ * much as we can byte-by-byte, and if we reach the end ++ * of the buffer before finishing, we return to the ++ * caller indicating that the buffer is full. ++ */ ++ if (M <= remaining_bytes) { ++ size_t i; ++ ++ for (i = 0; i < M; i++) ++ dst[i] = dst[i - D]; ++ dst += M; ++ remaining_bytes -= M; ++ M = 0; ++ (void)M; /* no dead store warning */ ++ /* ++ * We don't need to update M = 0, because ++ * there's no partial symbol to continue ++ * executing. Either we're at the end of the ++ * block, in which case we will never need to ++ * resume with this state, or we're going to ++ * decode another L, M, D set, which will ++ * overwrite M anyway. ++ * ++ * But we still set M = 0, to maintain the ++ * post-condition. ++ */ ++ } else { ++ size_t i; ++ ++ for (i = 0; i < remaining_bytes; i++) ++ dst[i] = dst[i - D]; ++ dst += remaining_bytes; ++ M -= remaining_bytes; ++DestinationBufferIsFull: ++ /* ++ * Because we want to be able to resume decoding ++ * where we've left off (even in the middle of a ++ * literal or match), we need to update all of ++ * the block state fields with the current ++ * values so that we can resume execution from ++ * this point once the caller has given us more ++ * space to write into. ++ */ ++ bs->l_value = L; ++ bs->m_value = M; ++ bs->d_value = D; ++ bs->l_state = l_state; ++ bs->m_state = m_state; ++ bs->d_state = d_state; ++ bs->lmd_in_stream = in; ++ bs->n_matches = symbols; ++ bs->lmd_in_buf = (uint32_t)(src - s->src); ++ bs->current_literal = lit; ++ s->dst = dst; ++ return LZFSE_STATUS_DST_FULL; ++ } ++ /* ++ * Restore the "sham" decremented value of ++ * remaining_bytes and continue to the next L, M, D ++ * triple. We'll just be back in the careful path again, ++ * but this only happens at the very end of the buffer, ++ * so a little minor inefficiency here is a good ++ * tradeoff for simpler code. ++ */ ++ remaining_bytes -= 32; ++ } ++ } ++ /* ++ * Because we've finished with the whole block, we don't need to update ++ * any of the blockstate fields; they will not be used again. We just ++ * update the destination pointer in the state object and return. ++ */ ++ s->dst = dst; ++ return LZFSE_STATUS_OK; ++} ++ ++int lzfse_decode(lzfse_decoder_state *s) ++{ ++ while (1) { ++ /* Are we inside a block? */ ++ switch (s->block_magic) { ++ case LZFSE_NO_BLOCK_MAGIC: { ++ uint32_t magic; ++ /* We need at least 4 bytes of magic number to identify next block */ ++ if (s->src + 4 > s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ magic = load4(s->src); ++ ++ if (magic == LZFSE_ENDOFSTREAM_BLOCK_MAGIC) { ++ s->src += 4; ++ s->end_of_stream = 1; ++ return LZFSE_STATUS_OK; /* done */ ++ } ++ ++ if (magic == LZFSE_UNCOMPRESSED_BLOCK_MAGIC) { ++ uncompressed_block_decoder_state *bs = NULL; ++ ++ if (s->src + sizeof(uncompressed_block_header) > s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ /* Setup state for uncompressed block */ ++ bs = &(s->uncompressed_block_state); ++ bs->n_raw_bytes = load4( ++ s->src + offsetof(uncompressed_block_header, n_raw_bytes)); ++ s->src += sizeof(uncompressed_block_header); ++ s->block_magic = magic; ++ break; ++ } ++ ++ if (magic == LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC) { ++ lzvn_compressed_block_decoder_state *bs = NULL; ++ ++ if (s->src + sizeof(lzvn_compressed_block_header) > s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ /* Setup state for compressed LZVN block */ ++ bs = &(s->compressed_lzvn_block_state); ++ bs->n_raw_bytes = ++ load4(s->src + ++ offsetof(lzvn_compressed_block_header, n_raw_bytes)); ++ bs->n_payload_bytes = ++ load4(s->src + offsetof(lzvn_compressed_block_header, ++ n_payload_bytes)); ++ bs->d_prev = 0; ++ s->src += sizeof(lzvn_compressed_block_header); ++ s->block_magic = magic; ++ break; ++ } ++ ++ if (magic == LZFSE_COMPRESSEDV1_BLOCK_MAGIC || ++ magic == LZFSE_COMPRESSEDV2_BLOCK_MAGIC) { ++ lzfse_compressed_block_header_v1 header1; ++ size_t header_size = 0; ++ lzfse_compressed_block_decoder_state *bs = NULL; ++ ++ /* Decode compressed headers */ ++ if (magic == LZFSE_COMPRESSEDV2_BLOCK_MAGIC) { ++ const lzfse_compressed_block_header_v2 *header2; ++ int decodeStatus; ++ /* Check we have the fixed part of the structure */ ++ if (s->src + offsetof(lzfse_compressed_block_header_v2, ++ freq) > ++ s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ ++ /* Get size, and check we have the entire structure */ ++ header2 = (const lzfse_compressed_block_header_v2 *) ++ s->src; /* not aligned, OK */ ++ header_size = lzfse_decode_v2_header_size(header2); ++ if (s->src + header_size > s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ decodeStatus = lzfse_decode_v1(&header1, header2); ++ if (decodeStatus != 0) ++ return LZFSE_STATUS_ERROR; /* failed */ ++ } else { ++ if (s->src + sizeof(lzfse_compressed_block_header_v1) > ++ s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* SRC truncated */ ++ memcpy(&header1, s->src, ++ sizeof(lzfse_compressed_block_header_v1)); ++ header_size = sizeof(lzfse_compressed_block_header_v1); ++ } ++ ++ /* ++ * We require the header + entire encoded block ++ * to be present in SRC during the entire block ++ * decoding. This can be relaxed somehow, if it ++ * becomes a limiting factor, at the price of a ++ * more complex state maintenance. For DST, we ++ * can't easily require space for the entire ++ * decoded block, because it may expand to ++ * something very very large. ++ */ ++ if (s->src + header_size + header1.n_literal_payload_bytes + ++ header1.n_lmd_payload_bytes > ++ s->src_end) ++ return LZFSE_STATUS_SRC_EMPTY; /* need all encoded block */ ++ ++ /* Sanity checks */ ++ if (lzfse_check_block_header_v1(&header1) != 0) ++ return LZFSE_STATUS_ERROR; ++ ++ /* Skip header */ ++ s->src += header_size; ++ ++ /* Setup state for compressed V1 block from header */ ++ bs = &(s->compressed_lzfse_block_state); ++ bs->n_lmd_payload_bytes = header1.n_lmd_payload_bytes; ++ bs->n_matches = header1.n_matches; ++ fse_init_decoder_table(LZFSE_ENCODE_LITERAL_STATES, ++ LZFSE_ENCODE_LITERAL_SYMBOLS, ++ header1.literal_freq, bs->literal_decoder); ++ fse_init_value_decoder_table(LZFSE_ENCODE_L_STATES, ++ LZFSE_ENCODE_L_SYMBOLS, header1.l_freq, ++ l_extra_bits, l_base_value, ++ bs->l_decoder); ++ fse_init_value_decoder_table(LZFSE_ENCODE_M_STATES, ++ LZFSE_ENCODE_M_SYMBOLS, header1.m_freq, ++ m_extra_bits, m_base_value, ++ bs->m_decoder); ++ fse_init_value_decoder_table(LZFSE_ENCODE_D_STATES, ++ LZFSE_ENCODE_D_SYMBOLS, header1.d_freq, ++ d_extra_bits, d_base_value, ++ bs->d_decoder); ++ ++ /* Decode literals */ ++ { ++ fse_in_stream in; ++ const uint8_t *buf_start = s->src_begin; ++ const uint8_t *buf; ++ fse_state state0; ++ fse_state state1; ++ fse_state state2; ++ fse_state state3; ++ uint32_t i; ++ ++ s->src += ++ header1.n_literal_payload_bytes; /* skip literal payload */ ++ buf = s->src; /* read bits backwards from the end */ ++ if (fse_in_init(&in, header1.literal_bits, &buf, ++ buf_start) != 0) ++ return LZFSE_STATUS_ERROR; ++ ++ state0 = header1.literal_state[0]; ++ state1 = header1.literal_state[1]; ++ state2 = header1.literal_state[2]; ++ state3 = header1.literal_state[3]; ++ ++ for (i = 0; i < header1.n_literals; ++ i += 4 /* n_literals is multiple of 4 */) { ++#if FSE_IOSTREAM_64 ++ if (fse_in_flush(&in, &buf, buf_start) != 0) ++ return LZFSE_STATUS_ERROR; /* [57, 64] bits */ ++ bs->literals[i + 0] = ++ fse_decode(&state0, bs->literal_decoder, ++ &in); /* 10b max */ ++ bs->literals[i + 1] = ++ fse_decode(&state1, bs->literal_decoder, ++ &in); /* 10b max */ ++ bs->literals[i + 2] = ++ fse_decode(&state2, bs->literal_decoder, ++ &in); /* 10b max */ ++ bs->literals[i + 3] = ++ fse_decode(&state3, bs->literal_decoder, ++ &in); /* 10b max */ ++#else ++ if (fse_in_flush(&in, &buf, buf_start) != 0) ++ return LZFSE_STATUS_ERROR; /* [25, 23] bits */ ++ bs->literals[i + 0] = ++ fse_decode(&state0, bs->literal_decoder, ++ &in); /* 10b max */ ++ bs->literals[i + 1] = ++ fse_decode(&state1, bs->literal_decoder, ++ &in); /* 10b max */ ++ if (fse_in_flush(&in, &buf, buf_start) != 0) ++ return LZFSE_STATUS_ERROR; /* [25, 23] bits */ ++ bs->literals[i + 2] = ++ fse_decode(&state2, bs->literal_decoder, ++ &in); /* 10b max */ ++ bs->literals[i + 3] = ++ fse_decode(&state3, bs->literal_decoder, ++ &in); /* 10b max */ ++#endif ++ } ++ ++ bs->current_literal = bs->literals; ++ } /* literals */ ++ ++ /* ++ * SRC is not incremented to skip the LMD ++ * payload, since we need it during block ++ * decode. We will increment SRC at the end of ++ * the block only after this point. ++ */ ++ ++ /* ++ * Initialize the L,M,D decode stream, do not ++ * start decoding matches yet, and store decoder ++ * state ++ */ ++ { ++ fse_in_stream in; ++ /* read bits backwards from the end */ ++ const uint8_t *buf = s->src + header1.n_lmd_payload_bytes; ++ ++ if (fse_in_init(&in, header1.lmd_bits, &buf, s->src) != 0) ++ return LZFSE_STATUS_ERROR; ++ ++ bs->l_state = header1.l_state; ++ bs->m_state = header1.m_state; ++ bs->d_state = header1.d_state; ++ bs->lmd_in_buf = (uint32_t)(buf - s->src); ++ bs->l_value = bs->m_value = 0; ++ /* ++ * Initialize D to an illegal value so ++ * we can't erroneously use an ++ * uninitialized "previous" value. ++ */ ++ bs->d_value = -1; ++ bs->lmd_in_stream = in; ++ } ++ ++ s->block_magic = magic; ++ break; ++ } ++ ++ /* Here we have an invalid magic number */ ++ return LZFSE_STATUS_ERROR; ++ } /* LZFSE_NO_BLOCK_MAGIC */ ++ ++ case LZFSE_UNCOMPRESSED_BLOCK_MAGIC: { ++ uncompressed_block_decoder_state *bs = &(s->uncompressed_block_state); ++ ++ /* ++ * Compute the size (in bytes) of the data that we will ++ * actually copy. This size is ++ * minimum(bs->n_raw_bytes, space in src, space in dst). ++ */ ++ ++ uint32_t copy_size = bs->n_raw_bytes; /* bytes left to copy */ ++ size_t src_space, dst_space; ++ ++ if (copy_size == 0) { ++ s->block_magic = 0; ++ break; ++ } /* end of block */ ++ ++ if (s->src_end <= s->src) ++ return LZFSE_STATUS_SRC_EMPTY; /* need more SRC data */ ++ src_space = s->src_end - s->src; ++ if (copy_size > src_space) ++ copy_size = (uint32_t)src_space; /* limit to SRC data (> 0) */ ++ ++ if (s->dst_end <= s->dst) ++ return LZFSE_STATUS_DST_FULL; /* need more DST capacity */ ++ dst_space = s->dst_end - s->dst; ++ if (copy_size > dst_space) ++ copy_size = (uint32_t)dst_space; /* limit to DST capacity (> 0) */ ++ ++ /* ++ * Now that we know that the copy size is bounded to the ++ * source and dest buffers, go ahead and copy the data. ++ * We always have copy_size > 0 here ++ */ ++ memcpy(s->dst, s->src, copy_size); ++ s->src += copy_size; ++ s->dst += copy_size; ++ bs->n_raw_bytes -= copy_size; ++ ++ break; ++ } /* LZFSE_UNCOMPRESSED_BLOCK_MAGIC */ ++ ++ case LZFSE_COMPRESSEDV1_BLOCK_MAGIC: ++ case LZFSE_COMPRESSEDV2_BLOCK_MAGIC: { ++ int status; ++ lzfse_compressed_block_decoder_state *bs = ++ &(s->compressed_lzfse_block_state); ++ /* Require the entire LMD payload to be in SRC */ ++ if (s->src_end <= s->src || ++ bs->n_lmd_payload_bytes > (size_t)(s->src_end - s->src)) ++ return LZFSE_STATUS_SRC_EMPTY; ++ ++ status = lzfse_decode_lmd(s); ++ if (status != LZFSE_STATUS_OK) ++ return status; ++ ++ s->block_magic = LZFSE_NO_BLOCK_MAGIC; ++ s->src += bs->n_lmd_payload_bytes; // to next block ++ break; ++ } /* LZFSE_COMPRESSEDV1_BLOCK_MAGIC || LZFSE_COMPRESSEDV2_BLOCK_MAGIC */ ++ ++ case LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC: { ++ lzvn_compressed_block_decoder_state *bs = &(s->compressed_lzvn_block_state); ++ lzvn_decoder_state dstate; ++ size_t src_used, dst_used; ++ ++ if (bs->n_payload_bytes > 0 && s->src_end <= s->src) ++ return LZFSE_STATUS_SRC_EMPTY; /* need more SRC data */ ++ ++ /* Init LZVN decoder state */ ++ memset(&dstate, 0x00, sizeof(dstate)); ++ dstate.src = s->src; ++ dstate.src_end = s->src_end; ++ if (dstate.src_end - s->src > bs->n_payload_bytes) ++ dstate.src_end = ++ s->src + bs->n_payload_bytes; /* limit to payload bytes */ ++ dstate.dst_begin = s->dst_begin; ++ dstate.dst = s->dst; ++ dstate.dst_end = s->dst_end; ++ if (dstate.dst_end - s->dst > bs->n_raw_bytes) ++ dstate.dst_end = s->dst + bs->n_raw_bytes; /* limit to raw bytes */ ++ dstate.d_prev = bs->d_prev; ++ dstate.end_of_stream = 0; ++ ++ /* Run LZVN decoder */ ++ lzvn_decode(&dstate); ++ ++ /* Update our state */ ++ src_used = dstate.src - s->src; ++ dst_used = dstate.dst - s->dst; ++ if (src_used > bs->n_payload_bytes || dst_used > bs->n_raw_bytes) ++ return LZFSE_STATUS_ERROR; /* sanity check */ ++ s->src = dstate.src; ++ s->dst = dstate.dst; ++ bs->n_payload_bytes -= (uint32_t)src_used; ++ bs->n_raw_bytes -= (uint32_t)dst_used; ++ bs->d_prev = (uint32_t)dstate.d_prev; ++ ++ /* Test end of block */ ++ if (bs->n_payload_bytes == 0 && bs->n_raw_bytes == 0 && ++ dstate.end_of_stream) { ++ s->block_magic = 0; ++ break; ++ } /* block done */ ++ ++ /* Check for invalid state */ ++ if (bs->n_payload_bytes == 0 || bs->n_raw_bytes == 0 || ++ dstate.end_of_stream) ++ return LZFSE_STATUS_ERROR; ++ ++ /* ++ * Here, block is not done and state is valid, so we ++ * need more space in dst. ++ */ ++ return LZFSE_STATUS_DST_FULL; ++ } ++ ++ default: ++ return LZFSE_STATUS_ERROR; /* invalid magic */ ++ ++ } /* switch magic */ ++ ++ } /* block loop */ ++ ++ return LZFSE_STATUS_OK; ++} +diff --git a/fs/apfs/lzfse/lzfse_fse.c b/fs/apfs/lzfse/lzfse_fse.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse_fse.c +@@ -0,0 +1,126 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "lzfse_internal.h" ++ ++/* ++ * Initialize decoder table T[NSTATES]. ++ * NSTATES = sum FREQ[i] is the number of states (a power of 2) ++ * NSYMBOLS is the number of symbols. ++ * FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i] ++ * >= 0. ++ * Some symbols may have a 0 frequency. In that case, they should not be ++ * present in the data. ++ */ ++int fse_init_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq, ++ int32_t *__restrict t) ++{ ++ int n_clz = __builtin_clz(nstates); ++ int sum_of_freq = 0; ++ int i, j0, j; ++ ++ for (i = 0; i < nsymbols; i++) { ++ int f = (int)freq[i]; ++ int k; ++ ++ if (f == 0) ++ continue; /* skip this symbol, no occurrences */ ++ ++ sum_of_freq += f; ++ ++ if (sum_of_freq > nstates) ++ return -1; ++ ++ k = __builtin_clz(f) - n_clz; /* shift needed to ensure N <= (F<> k) - f; ++ ++ /* Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F */ ++ for (j = 0; j < f; j++) { ++ fse_decoder_entry e; ++ ++ e.symbol = (uint8_t)i; ++ if (j < j0) { ++ e.k = (int8_t)k; ++ e.delta = (int16_t)(((f + j) << k) - nstates); ++ } else { ++ e.k = (int8_t)(k - 1); ++ e.delta = (int16_t)((j - j0) << (k - 1)); ++ } ++ ++ memcpy(t, &e, sizeof(e)); ++ t++; ++ } ++ } ++ ++ return 0; /* OK */ ++} ++ ++/* ++ * Initialize value decoder table T[NSTATES]. ++ * NSTATES = sum FREQ[i] is the number of states (a power of 2) ++ * NSYMBOLS is the number of symbols. ++ * FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i] ++ * >= 0. ++ * SYMBOL_VBITS[NSYMBOLS] and SYMBOLS_VBASE[NSYMBOLS] are the number of value ++ * bits to read and the base value for each symbol. ++ * Some symbols may have a 0 frequency. In that case, they should not be ++ * present in the data. ++ */ ++void fse_init_value_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq, ++ const uint8_t *__restrict symbol_vbits, ++ const int32_t *__restrict symbol_vbase, ++ struct fse_value_decoder_entry *__restrict t) ++{ ++ int n_clz = __builtin_clz(nstates); ++ int i; ++ ++ for (i = 0; i < nsymbols; i++) { ++ struct fse_value_decoder_entry ei = { 0 }; ++ int f = (int)freq[i]; ++ int k, j0, j; ++ ++ if (f == 0) ++ continue; /* skip this symbol, no occurrences */ ++ ++ k = __builtin_clz(f) - n_clz; /* shift needed to ensure N <= (F<> k) - f; ++ ++ ei.value_bits = symbol_vbits[i]; ++ ei.vbase = symbol_vbase[i]; ++ ++ /* Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F */ ++ for (j = 0; j < f; j++) { ++ struct fse_value_decoder_entry e = ei; ++ ++ if (j < j0) { ++ e.total_bits = (uint8_t)k + e.value_bits; ++ e.delta = (int16_t)(((f + j) << k) - nstates); ++ } else { ++ e.total_bits = (uint8_t)(k - 1) + e.value_bits; ++ e.delta = (int16_t)((j - j0) << (k - 1)); ++ } ++ ++ memcpy(t, &e, 8); ++ t++; ++ } ++ } ++} +diff --git a/fs/apfs/lzfse/lzfse_fse.h b/fs/apfs/lzfse/lzfse_fse.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse_fse.h +@@ -0,0 +1,573 @@ ++/* SPDX-License-Identifier: BSD-3-Clause */ ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Finite state entropy coding (FSE) ++ * This is an implementation of the tANS algorithm described by Jarek Duda, ++ * we use the more descriptive name "Finite State Entropy". ++ */ ++ ++#ifndef LZFSE_FSE_H ++#define LZFSE_FSE_H ++ ++#include ++#include ++ ++/* ++ * Select between 32/64-bit I/O streams for FSE. Note that the FSE stream ++ * size need not match the word size of the machine, but in practice you ++ * want to use 64b streams on 64b systems for better performance. ++ */ ++#if defined(_M_AMD64) || defined(__x86_64__) || defined(__arm64__) ++#define FSE_IOSTREAM_64 1 ++#else ++#define FSE_IOSTREAM_64 0 ++#endif ++ ++/* MARK: - Bit utils */ ++ ++/*! @abstract Signed type used to represent bit count. */ ++typedef int32_t fse_bit_count; ++ ++/*! @abstract Unsigned type used to represent FSE state. */ ++typedef uint16_t fse_state; ++ ++/* Mask the NBITS lsb of X. 0 <= NBITS < 64 */ ++static inline uint64_t fse_mask_lsb64(uint64_t x, fse_bit_count nbits) ++{ ++ static const uint64_t mtable[65] = { ++ 0x0000000000000000LLU, 0x0000000000000001LLU, 0x0000000000000003LLU, ++ 0x0000000000000007LLU, 0x000000000000000fLLU, 0x000000000000001fLLU, ++ 0x000000000000003fLLU, 0x000000000000007fLLU, 0x00000000000000ffLLU, ++ 0x00000000000001ffLLU, 0x00000000000003ffLLU, 0x00000000000007ffLLU, ++ 0x0000000000000fffLLU, 0x0000000000001fffLLU, 0x0000000000003fffLLU, ++ 0x0000000000007fffLLU, 0x000000000000ffffLLU, 0x000000000001ffffLLU, ++ 0x000000000003ffffLLU, 0x000000000007ffffLLU, 0x00000000000fffffLLU, ++ 0x00000000001fffffLLU, 0x00000000003fffffLLU, 0x00000000007fffffLLU, ++ 0x0000000000ffffffLLU, 0x0000000001ffffffLLU, 0x0000000003ffffffLLU, ++ 0x0000000007ffffffLLU, 0x000000000fffffffLLU, 0x000000001fffffffLLU, ++ 0x000000003fffffffLLU, 0x000000007fffffffLLU, 0x00000000ffffffffLLU, ++ 0x00000001ffffffffLLU, 0x00000003ffffffffLLU, 0x00000007ffffffffLLU, ++ 0x0000000fffffffffLLU, 0x0000001fffffffffLLU, 0x0000003fffffffffLLU, ++ 0x0000007fffffffffLLU, 0x000000ffffffffffLLU, 0x000001ffffffffffLLU, ++ 0x000003ffffffffffLLU, 0x000007ffffffffffLLU, 0x00000fffffffffffLLU, ++ 0x00001fffffffffffLLU, 0x00003fffffffffffLLU, 0x00007fffffffffffLLU, ++ 0x0000ffffffffffffLLU, 0x0001ffffffffffffLLU, 0x0003ffffffffffffLLU, ++ 0x0007ffffffffffffLLU, 0x000fffffffffffffLLU, 0x001fffffffffffffLLU, ++ 0x003fffffffffffffLLU, 0x007fffffffffffffLLU, 0x00ffffffffffffffLLU, ++ 0x01ffffffffffffffLLU, 0x03ffffffffffffffLLU, 0x07ffffffffffffffLLU, ++ 0x0fffffffffffffffLLU, 0x1fffffffffffffffLLU, 0x3fffffffffffffffLLU, ++ 0x7fffffffffffffffLLU, 0xffffffffffffffffLLU, ++ }; ++ return x & mtable[nbits]; ++} ++ ++/* Mask the NBITS lsb of X. 0 <= NBITS < 32 */ ++static inline uint32_t fse_mask_lsb32(uint32_t x, fse_bit_count nbits) ++{ ++ static const uint32_t mtable[33] = { ++ 0x0000000000000000U, 0x0000000000000001U, 0x0000000000000003U, 0x0000000000000007U, ++ 0x000000000000000fU, 0x000000000000001fU, 0x000000000000003fU, 0x000000000000007fU, ++ 0x00000000000000ffU, 0x00000000000001ffU, 0x00000000000003ffU, 0x00000000000007ffU, ++ 0x0000000000000fffU, 0x0000000000001fffU, 0x0000000000003fffU, 0x0000000000007fffU, ++ 0x000000000000ffffU, 0x000000000001ffffU, 0x000000000003ffffU, 0x000000000007ffffU, ++ 0x00000000000fffffU, 0x00000000001fffffU, 0x00000000003fffffU, 0x00000000007fffffU, ++ 0x0000000000ffffffU, 0x0000000001ffffffU, 0x0000000003ffffffU, 0x0000000007ffffffU, ++ 0x000000000fffffffU, 0x000000001fffffffU, 0x000000003fffffffU, 0x000000007fffffffU, ++ 0x00000000ffffffffU, ++ }; ++ return x & mtable[nbits]; ++} ++ ++/*! @abstract Select \c nbits at index \c start from \c x. ++ * 0 <= start <= start+nbits <= 64 ++ */ ++static __always_inline uint64_t fse_extract_bits64(uint64_t x, fse_bit_count start, ++ fse_bit_count nbits) ++{ ++ /* If START and NBITS are constants, map to bit-field extraction instructions */ ++ if (__builtin_constant_p(start) && __builtin_constant_p(nbits)) ++ return (x >> start) & ((1LLU << nbits) - 1LLU); ++ ++ /* Otherwise, shift and mask */ ++ return fse_mask_lsb64(x >> start, nbits); ++} ++ ++/*! @abstract Select \c nbits at index \c start from \c x. ++ * 0 <= start <= start+nbits <= 32 ++ */ ++static __always_inline uint32_t fse_extract_bits32(uint32_t x, fse_bit_count start, ++ fse_bit_count nbits) ++{ ++ /* If START and NBITS are constants, map to bit-field extraction instructions */ ++ if (__builtin_constant_p(start) && __builtin_constant_p(nbits)) ++ return (x >> start) & ((1U << nbits) - 1U); ++ ++ /* Otherwise, shift and mask */ ++ return fse_mask_lsb32(x >> start, nbits); ++} ++ ++/* MARK: - Bit stream */ ++ ++/* ++ * I/O streams ++ * The streams can be shared between several FSE encoders/decoders, which is why ++ * they are not in the state struct ++ */ ++ ++/*! @abstract Output stream, 64-bit accum. */ ++typedef struct { ++ uint64_t accum; /* Output bits */ ++ fse_bit_count accum_nbits; /* Number of valid bits in ACCUM, other bits are 0 */ ++} fse_out_stream64; ++ ++/*! @abstract Output stream, 32-bit accum. */ ++typedef struct { ++ uint32_t accum; /* Output bits */ ++ fse_bit_count accum_nbits; /* Number of valid bits in ACCUM, other bits are 0 */ ++} fse_out_stream32; ++ ++/*! @abstract Object representing an input stream. */ ++typedef struct { ++ uint64_t accum; /* Input bits */ ++ fse_bit_count accum_nbits; /* Number of valid bits in ACCUM, other bits are 0 */ ++} fse_in_stream64; ++ ++/*! @abstract Object representing an input stream. */ ++typedef struct { ++ uint32_t accum; /* Input bits */ ++ fse_bit_count accum_nbits; /* Number of valid bits in ACCUM, other bits are 0 */ ++} fse_in_stream32; ++ ++/*! @abstract Initialize an output stream object. */ ++static __always_inline void fse_out_init64(fse_out_stream64 *s) ++{ ++ s->accum = 0; ++ s->accum_nbits = 0; ++} ++ ++/*! @abstract Initialize an output stream object. */ ++static __always_inline void fse_out_init32(fse_out_stream32 *s) ++{ ++ s->accum = 0; ++ s->accum_nbits = 0; ++} ++ ++/*! @abstract Write full bytes from the accumulator to output buffer, ensuring ++ * accum_nbits is in [0, 7]. ++ * We assume we can write 8 bytes to the output buffer \c (*pbuf[0..7]) in all ++ * cases. ++ * @note *pbuf is incremented by the number of written bytes. ++ */ ++static __always_inline void fse_out_flush64(fse_out_stream64 *s, uint8_t **pbuf) ++{ ++ fse_bit_count nbits = s->accum_nbits & -8; /* number of bits written, multiple of 8 */ ++ ++ /* Write 8 bytes of current accumulator */ ++ memcpy(*pbuf, &(s->accum), 8); ++ *pbuf += (nbits >> 3); /* bytes */ ++ ++ /* Update state */ ++ s->accum >>= nbits; /* remove nbits */ ++ s->accum_nbits -= nbits; ++} ++ ++/*! @abstract Write full bytes from the accumulator to output buffer, ensuring ++ * accum_nbits is in [0, 7]. ++ * We assume we can write 4 bytes to the output buffer \c (*pbuf[0..3]) in all ++ * cases. ++ * @note *pbuf is incremented by the number of written bytes. ++ */ ++static __always_inline void fse_out_flush32(fse_out_stream32 *s, uint8_t **pbuf) ++{ ++ fse_bit_count nbits = s->accum_nbits & -8; /* number of bits written, multiple of 8 */ ++ ++ /* Write 4 bytes of current accumulator */ ++ memcpy(*pbuf, &(s->accum), 4); ++ *pbuf += (nbits >> 3); /* bytes */ ++ ++ /* Update state */ ++ s->accum >>= nbits; /* remove nbits */ ++ s->accum_nbits -= nbits; ++} ++ ++/*! @abstract Write the last bytes from the accumulator to output buffer, ++ * ensuring accum_nbits is in [-7, 0]. Bits are padded with 0 if needed. ++ * We assume we can write 8 bytes to the output buffer \c (*pbuf[0..7]) in all ++ * cases. ++ * @note *pbuf is incremented by the number of written bytes. ++ */ ++static __always_inline void fse_out_finish64(fse_out_stream64 *s, uint8_t **pbuf) ++{ ++ fse_bit_count nbits = (s->accum_nbits + 7) & -8; /* number of bits written, multiple of 8 */ ++ ++ /* Write 8 bytes of current accumulator */ ++ memcpy(*pbuf, &(s->accum), 8); ++ *pbuf += (nbits >> 3); /* bytes */ ++ ++ /* Update state */ ++ s->accum = 0; /* remove nbits */ ++ s->accum_nbits -= nbits; ++} ++ ++/*! @abstract Write the last bytes from the accumulator to output buffer, ++ * ensuring accum_nbits is in [-7, 0]. Bits are padded with 0 if needed. ++ * We assume we can write 4 bytes to the output buffer \c (*pbuf[0..3]) in all ++ * cases. ++ * @note *pbuf is incremented by the number of written bytes. ++ */ ++static __always_inline void fse_out_finish32(fse_out_stream32 *s, uint8_t **pbuf) ++{ ++ fse_bit_count nbits = (s->accum_nbits + 7) & -8; /* number of bits written, multiple of 8 */ ++ ++ /* Write 8 bytes of current accumulator */ ++ memcpy(*pbuf, &(s->accum), 4); ++ *pbuf += (nbits >> 3); /* bytes */ ++ ++ /* Update state */ ++ s->accum = 0; /* remove nbits */ ++ s->accum_nbits -= nbits; ++} ++ ++/*! @abstract Accumulate \c n bits \c b to output stream \c s. We \b must have: ++ * 0 <= b < 2^n, and N + s->accum_nbits <= 64. ++ * @note The caller must ensure out_flush is called \b before the accumulator ++ * overflows to more than 64 bits. ++ */ ++static __always_inline void fse_out_push64(fse_out_stream64 *s, fse_bit_count n, uint64_t b) ++{ ++ s->accum |= b << s->accum_nbits; ++ s->accum_nbits += n; ++} ++ ++/*! @abstract Accumulate \c n bits \c b to output stream \c s. We \b must have: ++ * 0 <= n < 2^n, and n + s->accum_nbits <= 32. ++ * @note The caller must ensure out_flush is called \b before the accumulator ++ * overflows to more than 32 bits. ++ */ ++static __always_inline void fse_out_push32(fse_out_stream32 *s, fse_bit_count n, uint32_t b) ++{ ++ s->accum |= b << s->accum_nbits; ++ s->accum_nbits += n; ++} ++ ++#define DEBUG_CHECK_INPUT_STREAM_PARAMETERS ++ ++/*! @abstract Initialize the fse input stream so that accum holds between 56 ++ * and 63 bits. We never want to have 64 bits in the stream, because that allows ++ * us to avoid a special case in the fse_in_pull function (eliminating an ++ * unpredictable branch), while not requiring any additional fse_flush ++ * operations. This is why we have the special case for n == 0 (in which case ++ * we want to load only 7 bytes instead of 8). ++ */ ++static __always_inline int fse_in_checked_init64(fse_in_stream64 *s, fse_bit_count n, ++ const uint8_t **pbuf, const uint8_t *buf_start) ++{ ++ if (n) { ++ if (*pbuf < buf_start + 8) ++ return -1; /* out of range */ ++ *pbuf -= 8; ++ memcpy(&(s->accum), *pbuf, 8); ++ s->accum_nbits = n + 64; ++ } else { ++ if (*pbuf < buf_start + 7) ++ return -1; /* out of range */ ++ *pbuf -= 7; ++ memcpy(&(s->accum), *pbuf, 7); ++ s->accum &= 0xffffffffffffff; ++ s->accum_nbits = n + 56; ++ } ++ ++ if ((s->accum_nbits < 56 || s->accum_nbits >= 64) || ((s->accum >> s->accum_nbits) != 0)) { ++ /* ++ * the incoming input is wrong (encoder should have zeroed the ++ * upper bits) ++ */ ++ return -1; ++ } ++ ++ return 0; /* OK */ ++} ++ ++/*! @abstract Identical to previous function, but for 32-bit operation ++ * (resulting bit count is between 24 and 31 bits). ++ */ ++static __always_inline int fse_in_checked_init32(fse_in_stream32 *s, fse_bit_count n, ++ const uint8_t **pbuf, const uint8_t *buf_start) ++{ ++ if (n) { ++ if (*pbuf < buf_start + 4) ++ return -1; /* out of range */ ++ *pbuf -= 4; ++ memcpy(&(s->accum), *pbuf, 4); ++ s->accum_nbits = n + 32; ++ } else { ++ if (*pbuf < buf_start + 3) ++ return -1; /* out of range */ ++ *pbuf -= 3; ++ memcpy(&(s->accum), *pbuf, 3); ++ s->accum &= 0xffffff; ++ s->accum_nbits = n + 24; ++ } ++ ++ if ((s->accum_nbits < 24 || s->accum_nbits >= 32) || ((s->accum >> s->accum_nbits) != 0)) { ++ /* ++ * the incoming input is wrong (encoder should have zeroed the ++ * upper bits) ++ */ ++ return -1; ++ } ++ ++ return 0; /* OK */ ++} ++ ++/*! @abstract Read in new bytes from buffer to ensure that we have a full ++ * complement of bits in the stream object (again, between 56 and 63 bits). ++ * checking the new value of \c *pbuf remains >= \c buf_start. ++ * @return 0 if OK. ++ * @return -1 on failure. ++ */ ++static __always_inline int fse_in_checked_flush64(fse_in_stream64 *s, const uint8_t **pbuf, ++ const uint8_t *buf_start) ++{ ++ /* Get number of bits to add to bring us into the desired range. */ ++ fse_bit_count nbits = (63 - s->accum_nbits) & -8; ++ /* Convert bits to bytes and decrement buffer address, then load new data. */ ++ const uint8_t *buf = (*pbuf) - (nbits >> 3); ++ uint64_t incoming; ++ ++ if (buf < buf_start) ++ return -1; /* out of range */ ++ *pbuf = buf; ++ memcpy(&incoming, buf, 8); ++ /* Update the state object and verify its validity (in DEBUG). */ ++ s->accum = (s->accum << nbits) | fse_mask_lsb64(incoming, nbits); ++ s->accum_nbits += nbits; ++ DEBUG_CHECK_INPUT_STREAM_PARAMETERS ++ return 0; // OK ++} ++ ++/*! @abstract Identical to previous function (but again, we're only filling ++ * a 32-bit field with between 24 and 31 bits). ++ */ ++static __always_inline int fse_in_checked_flush32(fse_in_stream32 *s, const uint8_t **pbuf, ++ const uint8_t *buf_start) ++{ ++ /* Get number of bits to add to bring us into the desired range. */ ++ fse_bit_count nbits = (31 - s->accum_nbits) & -8; ++ ++ if (nbits > 0) { ++ /* Convert bits to bytes and decrement buffer address, then load new data. */ ++ const uint8_t *buf = (*pbuf) - (nbits >> 3); ++ uint32_t incoming; ++ ++ if (buf < buf_start) ++ return -1; /* out of range */ ++ ++ *pbuf = buf; ++ ++ incoming = *((uint32_t *)buf); ++ ++ /* Update the state object and verify its validity (in DEBUG). */ ++ s->accum = (s->accum << nbits) | fse_mask_lsb32(incoming, nbits); ++ s->accum_nbits += nbits; ++ } ++ DEBUG_CHECK_INPUT_STREAM_PARAMETERS ++ return 0; /* OK */ ++} ++ ++/*! @abstract Pull n bits out of the fse stream object. */ ++static __always_inline uint64_t fse_in_pull64(fse_in_stream64 *s, fse_bit_count n) ++{ ++ uint64_t result; ++ ++ s->accum_nbits -= n; ++ result = s->accum >> s->accum_nbits; ++ s->accum = fse_mask_lsb64(s->accum, s->accum_nbits); ++ return result; ++} ++ ++/*! @abstract Pull n bits out of the fse stream object. */ ++static __always_inline uint32_t fse_in_pull32(fse_in_stream32 *s, fse_bit_count n) ++{ ++ uint32_t result; ++ ++ s->accum_nbits -= n; ++ result = s->accum >> s->accum_nbits; ++ s->accum = fse_mask_lsb32(s->accum, s->accum_nbits); ++ return result; ++} ++ ++/* MARK: - Encode/Decode */ ++ ++/* Map to 32/64-bit implementations and types for I/O */ ++#if FSE_IOSTREAM_64 ++ ++typedef uint64_t fse_bits; ++typedef fse_out_stream64 fse_out_stream; ++typedef fse_in_stream64 fse_in_stream; ++#define fse_mask_lsb fse_mask_lsb64 ++#define fse_extract_bits fse_extract_bits64 ++#define fse_out_init fse_out_init64 ++#define fse_out_flush fse_out_flush64 ++#define fse_out_finish fse_out_finish64 ++#define fse_out_push fse_out_push64 ++#define fse_in_init fse_in_checked_init64 ++#define fse_in_checked_init fse_in_checked_init64 ++#define fse_in_flush fse_in_checked_flush64 ++#define fse_in_checked_flush fse_in_checked_flush64 ++#define fse_in_flush2(_unused, _parameters, _unused2) 0 /* nothing */ ++#define fse_in_checked_flush2(_unused, _parameters) /* nothing */ ++#define fse_in_pull fse_in_pull64 ++ ++#else ++ ++typedef uint32_t fse_bits; ++typedef fse_out_stream32 fse_out_stream; ++typedef fse_in_stream32 fse_in_stream; ++#define fse_mask_lsb fse_mask_lsb32 ++#define fse_extract_bits fse_extract_bits32 ++#define fse_out_init fse_out_init32 ++#define fse_out_flush fse_out_flush32 ++#define fse_out_finish fse_out_finish32 ++#define fse_out_push fse_out_push32 ++#define fse_in_init fse_in_checked_init32 ++#define fse_in_checked_init fse_in_checked_init32 ++#define fse_in_flush fse_in_checked_flush32 ++#define fse_in_checked_flush fse_in_checked_flush32 ++#define fse_in_flush2 fse_in_checked_flush32 ++#define fse_in_checked_flush2 fse_in_checked_flush32 ++#define fse_in_pull fse_in_pull32 ++ ++#endif ++ ++/*! @abstract Entry for one state in the decoder table (32b). */ ++typedef struct { /* DO NOT REORDER THE FIELDS */ ++ int8_t k; /* Number of bits to read */ ++ uint8_t symbol; /* Emitted symbol */ ++ int16_t delta; /* Signed increment used to compute next state (+bias) */ ++} fse_decoder_entry; ++ ++/*! @abstract Entry for one state in the value decoder table (64b). */ ++struct fse_value_decoder_entry { /* DO NOT REORDER THE FIELDS */ ++ uint8_t total_bits; /* state bits + extra value bits = shift for next decode */ ++ uint8_t value_bits; /* extra value bits */ ++ int16_t delta; /* state base (delta) */ ++ int32_t vbase; /* value base */ ++}; ++ ++/*! @abstract Decode and return symbol using the decoder table, and update ++ * \c *pstate, \c in. ++ * @note The caller must ensure we have enough bits available in the input ++ * stream accumulator. ++ */ ++static __always_inline uint8_t fse_decode(fse_state *__restrict pstate, ++ const int32_t *__restrict decoder_table, ++ fse_in_stream *__restrict in) ++{ ++ int32_t e = decoder_table[*pstate]; ++ ++ /* Update state from K bits of input + DELTA */ ++ *pstate = (fse_state)(e >> 16) + (fse_state)fse_in_pull(in, e & 0xff); ++ ++ /* Return the symbol for this state */ ++ return fse_extract_bits(e, 8, 8); /* symbol */ ++} ++ ++/*! @abstract Decode and return value using the decoder table, and update \c ++ * *pstate, \c in. ++ * \c value_decoder_table[nstates] ++ * @note The caller must ensure we have enough bits available in the input ++ * stream accumulator. ++ */ ++static __always_inline int32_t fse_value_decode(fse_state *__restrict pstate, ++ const struct fse_value_decoder_entry *value_decoder_table, ++ fse_in_stream *__restrict in) ++{ ++ struct fse_value_decoder_entry entry = value_decoder_table[*pstate]; ++ uint32_t state_and_value_bits = (uint32_t)fse_in_pull(in, entry.total_bits); ++ *pstate = (fse_state)(entry.delta + (state_and_value_bits >> entry.value_bits)); ++ return (int32_t)(entry.vbase + fse_mask_lsb(state_and_value_bits, entry.value_bits)); ++} ++ ++/* MARK: - Tables */ ++ ++/* ++ * IMPORTANT: To properly decode an FSE encoded stream, both encoder/decoder ++ * tables shall be initialized with the same parameters, including the ++ * FREQ[NSYMBOL] array. ++ */ ++ ++/*! @abstract Sanity check on frequency table, verify sum of \c freq ++ * is <= \c number_of_states. ++ */ ++static __always_inline int fse_check_freq(const uint16_t *freq_table, const size_t table_size, ++ const size_t number_of_states) ++{ ++ size_t sum_of_freq = 0; ++ int i; ++ ++ for (i = 0; i < table_size; i++) ++ sum_of_freq += freq_table[i]; ++ return (sum_of_freq > number_of_states) ? -1 : 0; ++} ++ ++/*! @abstract Initialize decoder table \c t[nstates]. ++ * ++ * @param nstates ++ * sum \c freq[i]; the number of states (a power of 2). ++ * ++ * @param nsymbols ++ * the number of symbols. ++ * ++ * @param feq[nsymbols] ++ * a normalized histogram of symbol frequencies, with \c freq[i] >= 0. ++ * Some symbols may have a 0 frequency. In that case they should not be ++ * present in the data. ++ * ++ * @return 0 if OK. ++ * @return -1 on failure. ++ */ ++int fse_init_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq, ++ int32_t *__restrict t); ++ ++/*! @abstract Initialize value decoder table \c t[nstates]. ++ * ++ * @param nstates ++ * sum \cfreq[i]; the number of states (a power of 2). ++ * ++ * @param nsymbols ++ * the number of symbols. ++ * ++ * @param freq[nsymbols] ++ * a normalized histogram of symbol frequencies, with \c freq[i] >= 0. ++ * \c symbol_vbits[nsymbols] and \c symbol_vbase[nsymbols] are the number of ++ * value bits to read and the base value for each symbol. ++ * Some symbols may have a 0 frequency. In that case they should not be ++ * present in the data. ++ */ ++void fse_init_value_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq, ++ const uint8_t *__restrict symbol_vbits, ++ const int32_t *__restrict symbol_vbase, ++ struct fse_value_decoder_entry *__restrict t); ++ ++#endif /* LZFSE_FSE_H */ +diff --git a/fs/apfs/lzfse/lzfse_internal.h b/fs/apfs/lzfse/lzfse_internal.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzfse_internal.h +@@ -0,0 +1,482 @@ ++/* SPDX-License-Identifier: BSD-3-Clause */ ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef LZFSE_INTERNAL_H ++#define LZFSE_INTERNAL_H ++ ++#include "lzfse_fse.h" ++#include ++#include ++ ++/* ++ * Throughout LZFSE we refer to "L", "M" and "D"; these will always appear as ++ * a triplet, and represent a "usual" LZ-style literal and match pair. "L" ++ * is the number of literal bytes, "M" is the number of match bytes, and "D" ++ * is the match "distance"; the distance in bytes between the current pointer ++ * and the start of the match. ++ */ ++#define LZFSE_ENCODE_HASH_VALUES (1 << LZFSE_ENCODE_HASH_BITS) ++#define LZFSE_ENCODE_L_SYMBOLS 20 ++#define LZFSE_ENCODE_M_SYMBOLS 20 ++#define LZFSE_ENCODE_D_SYMBOLS 64 ++#define LZFSE_ENCODE_LITERAL_SYMBOLS 256 ++#define LZFSE_ENCODE_L_STATES 64 ++#define LZFSE_ENCODE_M_STATES 64 ++#define LZFSE_ENCODE_D_STATES 256 ++#define LZFSE_ENCODE_LITERAL_STATES 1024 ++#define LZFSE_MATCHES_PER_BLOCK 10000 ++#define LZFSE_LITERALS_PER_BLOCK (4 * LZFSE_MATCHES_PER_BLOCK) ++#define LZFSE_DECODE_LITERALS_PER_BLOCK (4 * LZFSE_DECODE_MATCHES_PER_BLOCK) ++ ++/* ++ * LZFSE internal status. These values are used by internal LZFSE routines ++ * as return codes. There should not be any good reason to change their ++ * values; it is plausible that additional codes might be added in the ++ * future. ++ */ ++#define LZFSE_STATUS_OK 0 ++#define LZFSE_STATUS_SRC_EMPTY -1 ++#define LZFSE_STATUS_DST_FULL -2 ++#define LZFSE_STATUS_ERROR -3 ++ ++/* ++ * Type representing an offset between elements in a buffer. On 64-bit ++ * systems, this is stored in a 64-bit container to avoid extra sign- ++ * extension operations in addressing arithmetic, but the value is always ++ * representable as a 32-bit signed value in LZFSE's usage. ++ */ ++#if defined(_M_AMD64) || defined(__x86_64__) || defined(__arm64__) ++typedef int64_t lzfse_offset; ++#else ++typedef int32_t lzfse_offset; ++#endif ++ ++typedef uint64_t uintmax_t; ++ ++/*! @abstract Decoder state object for lzfse compressed blocks. */ ++typedef struct { ++ /* Number of matches remaining in the block. */ ++ uint32_t n_matches; ++ /* Number of bytes used to encode L, M, D triplets for the block. */ ++ uint32_t n_lmd_payload_bytes; ++ /* Pointer to the next literal to emit. */ ++ const uint8_t *current_literal; ++ /* ++ * L, M, D triplet for the match currently being emitted. This is used ++ * only if we need to restart after reaching the end of the destination ++ * buffer in the middle of a literal or match. ++ */ ++ int32_t l_value, m_value, d_value; ++ /* FSE stream object. */ ++ fse_in_stream lmd_in_stream; ++ /* ++ * Offset of L,M,D encoding in the input buffer. Because we read through ++ * an FSE stream *backwards* while decoding, this is decremented as we ++ * move through a block. ++ */ ++ uint32_t lmd_in_buf; ++ /* The current state of the L, M, and D FSE decoders. */ ++ uint16_t l_state, m_state, d_state; ++ /* ++ * Internal FSE decoder tables for the current block. These have ++ * alignment forced to 8 bytes to guarantee that a single state's ++ * entry cannot span two cachelines. ++ */ ++ struct fse_value_decoder_entry l_decoder[LZFSE_ENCODE_L_STATES] __aligned(8); ++ struct fse_value_decoder_entry m_decoder[LZFSE_ENCODE_M_STATES] __aligned(8); ++ struct fse_value_decoder_entry d_decoder[LZFSE_ENCODE_D_STATES] __aligned(8); ++ int32_t literal_decoder[LZFSE_ENCODE_LITERAL_STATES]; ++ /* ++ * The literal stream for the block, plus padding to allow for faster ++ * copy operations. ++ */ ++ uint8_t literals[LZFSE_LITERALS_PER_BLOCK + 64]; ++} lzfse_compressed_block_decoder_state; ++ ++/* Decoder state object for uncompressed blocks. */ ++typedef struct { ++ uint32_t n_raw_bytes; ++} uncompressed_block_decoder_state; ++ ++/*! @abstract Decoder state object for lzvn-compressed blocks. */ ++typedef struct { ++ uint32_t n_raw_bytes; ++ uint32_t n_payload_bytes; ++ uint32_t d_prev; ++} lzvn_compressed_block_decoder_state; ++ ++/*! @abstract Decoder state object. */ ++typedef struct { ++ /* ++ * Pointer to next byte to read from source buffer (this is advanced as ++ * we decode; src_begin describe the buffer and do not change). ++ */ ++ const uint8_t *src; ++ /* Pointer to first byte of source buffer. */ ++ const uint8_t *src_begin; ++ /* Pointer to one byte past the end of the source buffer. */ ++ const uint8_t *src_end; ++ /* ++ * Pointer to the next byte to write to destination buffer (this is ++ * advanced as we decode; dst_begin and dst_end describe the buffer and ++ * do not change). ++ */ ++ uint8_t *dst; ++ /* Pointer to first byte of destination buffer. */ ++ uint8_t *dst_begin; ++ /* Pointer to one byte past the end of the destination buffer. */ ++ uint8_t *dst_end; ++ /* 1 if we have reached the end of the stream, 0 otherwise. */ ++ int end_of_stream; ++ /* ++ * magic number of the current block if we are within a block, ++ * LZFSE_NO_BLOCK_MAGIC otherwise. ++ */ ++ uint32_t block_magic; ++ lzfse_compressed_block_decoder_state compressed_lzfse_block_state; ++ lzvn_compressed_block_decoder_state compressed_lzvn_block_state; ++ uncompressed_block_decoder_state uncompressed_block_state; ++} lzfse_decoder_state; ++ ++/* MARK: - Block header objects */ ++ ++#define LZFSE_NO_BLOCK_MAGIC 0x00000000 /* 0 (invalid) */ ++#define LZFSE_ENDOFSTREAM_BLOCK_MAGIC 0x24787662 /* bvx$ (end of stream) */ ++#define LZFSE_UNCOMPRESSED_BLOCK_MAGIC 0x2d787662 /* bvx- (raw data) */ ++#define LZFSE_COMPRESSEDV1_BLOCK_MAGIC 0x31787662 /* bvx1 (lzfse compressed, uncompressed tables) */ ++#define LZFSE_COMPRESSEDV2_BLOCK_MAGIC 0x32787662 /* bvx2 (lzfse compressed, compressed tables) */ ++#define LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC 0x6e787662 /* bvxn (lzvn compressed) */ ++ ++/*! @abstract Uncompressed block header in encoder stream. */ ++typedef struct { ++ /* Magic number, always LZFSE_UNCOMPRESSED_BLOCK_MAGIC. */ ++ uint32_t magic; ++ /* Number of raw bytes in block. */ ++ uint32_t n_raw_bytes; ++} uncompressed_block_header; ++ ++/*! @abstract Compressed block header with uncompressed tables. */ ++typedef struct { ++ /* Magic number, always LZFSE_COMPRESSEDV1_BLOCK_MAGIC. */ ++ uint32_t magic; ++ /* Number of decoded (output) bytes in block. */ ++ uint32_t n_raw_bytes; ++ /* Number of encoded (source) bytes in block. */ ++ uint32_t n_payload_bytes; ++ /* Number of literal bytes output by block (*not* the number of literals). */ ++ uint32_t n_literals; ++ /* Number of matches in block (which is also the number of literals). */ ++ uint32_t n_matches; ++ /* Number of bytes used to encode literals. */ ++ uint32_t n_literal_payload_bytes; ++ /* Number of bytes used to encode matches. */ ++ uint32_t n_lmd_payload_bytes; ++ ++ /* ++ * Final encoder states for the block, which will be the initial states ++ * for the decoder: ++ */ ++ /* Final accum_nbits for literals stream. */ ++ int32_t literal_bits; ++ /* ++ * There are four interleaved streams of literals, so there are four ++ * final states. ++ */ ++ uint16_t literal_state[4]; ++ /* accum_nbits for the l, m, d stream. */ ++ int32_t lmd_bits; ++ /* Final L (literal length) state. */ ++ uint16_t l_state; ++ /* Final M (match length) state. */ ++ uint16_t m_state; ++ /* Final D (match distance) state. */ ++ uint16_t d_state; ++ ++ /* ++ * Normalized frequency tables for each stream. Sum of values in each ++ * array is the number of states. ++ */ ++ uint16_t l_freq[LZFSE_ENCODE_L_SYMBOLS]; ++ uint16_t m_freq[LZFSE_ENCODE_M_SYMBOLS]; ++ uint16_t d_freq[LZFSE_ENCODE_D_SYMBOLS]; ++ uint16_t literal_freq[LZFSE_ENCODE_LITERAL_SYMBOLS]; ++} lzfse_compressed_block_header_v1; ++ ++/*! @abstract Compressed block header with compressed tables. Note that because ++ * freq[] is compressed, the structure-as-stored-in-the-stream is *truncated*; ++ * we only store the used bytes of freq[]. This means that some extra care must ++ * be taken when reading one of these headers from the stream. ++ */ ++typedef struct { ++ /* Magic number, always LZFSE_COMPRESSEDV2_BLOCK_MAGIC. */ ++ uint32_t magic; ++ /* Number of decoded (output) bytes in block. */ ++ uint32_t n_raw_bytes; ++ /* ++ * The fields n_payload_bytes ... d_state from the ++ * lzfse_compressed_block_header_v1 object are packed into three 64-bit ++ * fields in the compressed header, as follows: ++ * ++ * offset bits value ++ * 0 20 n_literals ++ * 20 20 n_literal_payload_bytes ++ * 40 20 n_matches ++ * 60 3 literal_bits ++ * 63 1 --- unused --- ++ * ++ * 0 10 literal_state[0] ++ * 10 10 literal_state[1] ++ * 20 10 literal_state[2] ++ * 30 10 literal_state[3] ++ * 40 20 n_lmd_payload_bytes ++ * 60 3 lmd_bits ++ * 63 1 --- unused --- ++ * ++ * 0 32 header_size (total header size in bytes; this does not ++ * correspond to a field in the uncompressed header version, ++ * but is required; we wouldn't know the size of the ++ * compresssed header otherwise. ++ * 32 10 l_state ++ * 42 10 m_state ++ * 52 10 d_state ++ * 62 2 --- unused --- ++ */ ++ uint64_t packed_fields[3]; ++ /* ++ * Variable size freq tables, using a Huffman-style fixed encoding. ++ * Size allocated here is an upper bound (all values stored on 16 bits). ++ */ ++ uint8_t freq[2 * (LZFSE_ENCODE_L_SYMBOLS + LZFSE_ENCODE_M_SYMBOLS + LZFSE_ENCODE_D_SYMBOLS + ++ LZFSE_ENCODE_LITERAL_SYMBOLS)]; ++} __packed __aligned(1) lzfse_compressed_block_header_v2; ++ ++/*! @abstract LZVN compressed block header. */ ++typedef struct { ++ /* Magic number, always LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC. */ ++ uint32_t magic; ++ /* Number of decoded (output) bytes. */ ++ uint32_t n_raw_bytes; ++ /* Number of encoded (source) bytes. */ ++ uint32_t n_payload_bytes; ++} lzvn_compressed_block_header; ++ ++int lzfse_decode(lzfse_decoder_state *s); ++size_t lzvn_decode_scratch_size(void); ++size_t lzvn_decode_buffer(void *__restrict dst, size_t dst_size, const void *__restrict src, ++ size_t src_size); ++ ++/*! @abstract Signed offset in buffers, stored on either 32 or 64 bits. */ ++#if defined(_M_AMD64) || defined(__x86_64__) || defined(__arm64__) ++typedef int64_t lzvn_offset; ++#else ++typedef int32_t lzvn_offset; ++#endif ++ ++/* MARK: - LZFSE utility functions */ ++ ++/*! @abstract Load bytes from memory location SRC. */ ++static __always_inline uint16_t load2(const void *ptr) ++{ ++ uint16_t data; ++ ++ memcpy(&data, ptr, sizeof(data)); ++ return data; ++} ++ ++static __always_inline uint32_t load4(const void *ptr) ++{ ++ uint32_t data; ++ ++ memcpy(&data, ptr, sizeof(data)); ++ return data; ++} ++ ++static __always_inline uint64_t load8(const void *ptr) ++{ ++ uint64_t data; ++ ++ memcpy(&data, ptr, sizeof(data)); ++ return data; ++} ++ ++/*! @abstract Store bytes to memory location DST. */ ++static __always_inline void store2(void *ptr, uint16_t data) ++{ ++ memcpy(ptr, &data, sizeof(data)); ++} ++ ++static __always_inline void store4(void *ptr, uint32_t data) ++{ ++ memcpy(ptr, &data, sizeof(data)); ++} ++ ++static __always_inline void store8(void *ptr, uint64_t data) ++{ ++ memcpy(ptr, &data, sizeof(data)); ++} ++ ++/*! @abstract Load+store bytes from locations SRC to DST. Not intended for use ++ * with overlapping buffers. Note that for LZ-style compression, you need ++ * copies to behave like naive memcpy( ) implementations do, splatting the ++ * leading sequence if the buffers overlap. This copy does not do that, so ++ * should not be used with overlapping buffers. ++ */ ++static __always_inline void copy8(void *dst, const void *src) ++{ ++ store8(dst, load8(src)); ++} ++static __always_inline void copy16(void *dst, const void *src) ++{ ++ uint64_t m0 = load8(src); ++ uint64_t m1 = load8((const unsigned char *)src + 8); ++ ++ store8(dst, m0); ++ store8((unsigned char *)dst + 8, m1); ++} ++ ++/* ++ * =============================================================== ++ * Bitfield Operations ++ */ ++ ++/*! @abstract Extracts \p width bits from \p container, starting with \p lsb; if ++ * we view \p container as a bit array, we extract \c container[lsb:lsb+width]. ++ */ ++static __always_inline uintmax_t extract(uintmax_t container, unsigned int lsb, unsigned int width) ++{ ++ static const size_t container_width = sizeof(container) * 8; ++ ++ if (width == container_width) ++ return container; ++ return (container >> lsb) & (((uintmax_t)1 << width) - 1); ++} ++ ++/*! @abstract Inserts \p width bits from \p data into \p container, starting with \p lsb. ++ * Viewed as bit arrays, the operations is: ++ * @code ++ * container[:lsb] is unchanged ++ * container[lsb:lsb+width] <-- data[0:width] ++ * container[lsb+width:] is unchanged ++ * @endcode ++ */ ++static __always_inline uintmax_t insert(uintmax_t container, uintmax_t data, unsigned int lsb, ++ unsigned int width) ++{ ++ static const size_t container_width = sizeof(container) * 8; ++ uintmax_t mask; ++ ++ if (width == container_width) ++ return container; ++ mask = ((uintmax_t)1 << width) - 1; ++ return (container & ~(mask << lsb)) | (data & mask) << lsb; ++} ++ ++/*! @abstract Perform sanity checks on the values of lzfse_compressed_block_header_v1. ++ * Test that the field values are in the allowed limits, verify that the ++ * frequency tables sum to value less than total number of states. ++ * @return 0 if all tests passed. ++ * @return negative error code with 1 bit set for each failed test. ++ */ ++static __always_inline int ++lzfse_check_block_header_v1(const lzfse_compressed_block_header_v1 *header) ++{ ++ int tests_results = 0; ++ uint16_t literal_state[4]; ++ int res; ++ ++ tests_results = tests_results | ++ ((header->magic == LZFSE_COMPRESSEDV1_BLOCK_MAGIC) ? 0 : (1 << 0)); ++ tests_results = tests_results | ++ ((header->n_literals <= LZFSE_LITERALS_PER_BLOCK) ? 0 : (1 << 1)); ++ tests_results = tests_results | ++ ((header->n_matches <= LZFSE_MATCHES_PER_BLOCK) ? 0 : (1 << 2)); ++ ++ memcpy(literal_state, header->literal_state, sizeof(uint16_t) * 4); ++ ++ tests_results = tests_results | ++ ((literal_state[0] < LZFSE_ENCODE_LITERAL_STATES) ? 0 : (1 << 3)); ++ tests_results = tests_results | ++ ((literal_state[1] < LZFSE_ENCODE_LITERAL_STATES) ? 0 : (1 << 4)); ++ tests_results = tests_results | ++ ((literal_state[2] < LZFSE_ENCODE_LITERAL_STATES) ? 0 : (1 << 5)); ++ tests_results = tests_results | ++ ((literal_state[3] < LZFSE_ENCODE_LITERAL_STATES) ? 0 : (1 << 6)); ++ ++ tests_results = tests_results | ((header->l_state < LZFSE_ENCODE_L_STATES) ? 0 : (1 << 7)); ++ tests_results = tests_results | ((header->m_state < LZFSE_ENCODE_M_STATES) ? 0 : (1 << 8)); ++ tests_results = tests_results | ((header->d_state < LZFSE_ENCODE_D_STATES) ? 0 : (1 << 9)); ++ ++ res = fse_check_freq(header->l_freq, LZFSE_ENCODE_L_SYMBOLS, LZFSE_ENCODE_L_STATES); ++ tests_results = tests_results | ((res == 0) ? 0 : (1 << 10)); ++ res = fse_check_freq(header->m_freq, LZFSE_ENCODE_M_SYMBOLS, LZFSE_ENCODE_M_STATES); ++ tests_results = tests_results | ((res == 0) ? 0 : (1 << 11)); ++ res = fse_check_freq(header->d_freq, LZFSE_ENCODE_D_SYMBOLS, LZFSE_ENCODE_D_STATES); ++ tests_results = tests_results | ((res == 0) ? 0 : (1 << 12)); ++ res = fse_check_freq(header->literal_freq, LZFSE_ENCODE_LITERAL_SYMBOLS, ++ LZFSE_ENCODE_LITERAL_STATES); ++ tests_results = tests_results | ((res == 0) ? 0 : (1 << 13)); ++ ++ if (tests_results) { ++ /* each 1 bit is a test that failed (except for the sign bit) */ ++ return tests_results | 0x80000000; ++ } ++ ++ return 0; /* OK */ ++} ++ ++/*! @abstract The L, M, D data streams are all encoded as a "base" value, which is ++ * FSE-encoded, and an "extra bits" value, which is the difference between ++ * value and base, and is simply represented as a raw bit value (because it ++ * is the low-order bits of a larger number, not much entropy can be ++ * extracted from these bits by more complex encoding schemes). The following ++ * tables represent the number of low-order bits to encode separately and the ++ * base values for each of L, M, and D. ++ * ++ * @note The inverse tables for mapping the other way are significantly larger. ++ * Those tables have been split out to lzfse_encode_tables.h in order to keep ++ * this file relatively small. ++ */ ++static const uint8_t l_extra_bits[LZFSE_ENCODE_L_SYMBOLS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 2, 3, 5, 8 }; ++static const int32_t l_base_value[LZFSE_ENCODE_L_SYMBOLS] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 28, 60 ++}; ++static const uint8_t m_extra_bits[LZFSE_ENCODE_M_SYMBOLS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 3, 5, 8, 11 }; ++static const int32_t m_base_value[LZFSE_ENCODE_M_SYMBOLS] = { 0, 1, 2, 3, 4, 5, 6, ++ 7, 8, 9, 10, 11, 12, 13, ++ 14, 15, 16, 24, 56, 312 }; ++static const uint8_t d_extra_bits[LZFSE_ENCODE_D_SYMBOLS] = { ++ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, ++ 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, ++ 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15 ++}; ++static const int32_t d_base_value[LZFSE_ENCODE_D_SYMBOLS] = { ++ 0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, ++ 24, 28, 36, 44, 52, 60, 76, 92, 108, 124, 156, ++ 188, 220, 252, 316, 380, 444, 508, 636, 764, 892, 1020, ++ 1276, 1532, 1788, 2044, 2556, 3068, 3580, 4092, 5116, 6140, 7164, ++ 8188, 10236, 12284, 14332, 16380, 20476, 24572, 28668, 32764, 40956, 49148, ++ 57340, 65532, 81916, 98300, 114684, 131068, 163836, 196604, 229372 ++}; ++ ++#endif /* LZFSE_INTERNAL_H */ +diff --git a/fs/apfs/lzfse/lzvn_decode_base.c b/fs/apfs/lzfse/lzvn_decode_base.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzvn_decode_base.c +@@ -0,0 +1,487 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* LZVN low-level decoder */ ++ ++#include ++#include ++#include "lzvn_decode_base.h" ++ ++/* Older kernel versions will still get an objtool warning here */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0) ++#define __annotate_jump_table ++#endif ++ ++/* ++ * Both the source and destination buffers are represented by a pointer and ++ * a length; they are *always* updated in concert using this macro; however ++ * many bytes the pointer is advanced, the length is decremented by the same ++ * amount. Thus, pointer + length always points to the byte one past the end ++ * of the buffer. ++ */ ++#define PTR_LEN_INC(_pointer, _length, _increment) (_pointer += _increment, _length -= _increment) ++ ++/* ++ * Update state with current positions and distance, corresponding to the ++ * beginning of an instruction in both streams ++ */ ++#define UPDATE_GOOD (state->src = src_ptr, state->dst = dst_ptr, state->d_prev = D) ++ ++void lzvn_decode(lzvn_decoder_state *state) ++{ ++ /* Jump table for all instructions */ ++ static const void *opc_tbl[256] __annotate_jump_table = { ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&eos, &&lrg_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&nop, &&lrg_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&nop, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&udef, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, ++ &&sml_d, &&udef, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, ++ &&udef, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, ++ &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, ++ &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&udef, &&udef, &&udef, &&udef, &&udef, ++ &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, ++ &&udef, &&udef, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, ++ &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&sml_d, ++ &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, &&med_d, &&med_d, ++ &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, ++ &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, ++ &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, ++ &&med_d, &&med_d, &&med_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, ++ &&pre_d, &&lrg_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, ++ &&lrg_d, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, ++ &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&lrg_l, ++ &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, ++ &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&lrg_m, &&sml_m, &&sml_m, ++ &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, ++ &&sml_m, &&sml_m, &&sml_m, &&sml_m ++ }; ++ size_t src_len = state->src_end - state->src; ++ size_t dst_len = state->dst_end - state->dst; ++ const unsigned char *src_ptr = state->src; ++ unsigned char *dst_ptr = state->dst; ++ size_t D = state->d_prev; ++ size_t M; ++ size_t L; ++ size_t opc_len; ++ unsigned char opc; ++ uint16_t opc23; ++ ++ if (src_len == 0 || dst_len == 0) ++ return; /* empty buffer */ ++ ++ /* Do we have a partially expanded match saved in state? */ ++ if (state->L != 0 || state->M != 0) { ++ L = state->L; ++ M = state->M; ++ D = state->D; ++ opc_len = 0; /* we already skipped the op */ ++ state->L = state->M = state->D = 0; ++ if (M == 0) ++ goto copy_literal; ++ if (L == 0) ++ goto copy_match; ++ goto copy_literal_and_match; ++ } ++ ++ opc = src_ptr[0]; ++ ++ goto *opc_tbl[opc]; ++/* ++ * =============================================================== ++ * These four opcodes (sml_d, med_d, lrg_d, and pre_d) encode both a ++ * literal and a match. The bulk of their implementations are shared; ++ * each label here only does the work of setting the opcode length (not ++ * including any literal bytes), and extracting the literal length, match ++ * length, and match distance (except in pre_d). They then jump into the ++ * shared implementation to actually output the literal and match bytes. ++ * ++ * No error checking happens in the first stage, except for ensuring that ++ * the source has enough length to represent the full opcode before ++ * reading past the first byte. ++ */ ++sml_d: ++ UPDATE_GOOD; ++ /* ++ * "small distance": This opcode has the structure LLMMMDDD DDDDDDDD ++ * LITERAL where the length of literal (0-3 bytes) is encoded by the ++ * high 2 bits of the first byte. We first extract the literal length so ++ * we know how long the opcode is, then check that the source can hold ++ * both this opcode and at least one byte of the next (because any valid ++ * input stream must be terminated with an eos token). ++ */ ++ opc_len = 2; ++ L = (size_t)extract(opc, 6, 2); ++ M = (size_t)extract(opc, 3, 3) + 3; ++ /* ++ * We need to ensure that the source buffer is long enough that we can ++ * safely read this entire opcode, the literal that follows, and the ++ * first byte of the next opcode. Once we satisfy this requirement, we ++ * can safely unpack the match distance. A check similar to this one is ++ * present in all the opcode implementations. ++ */ ++ if (src_len <= opc_len + L) ++ return; /* source truncated */ ++ D = (size_t)extract(opc, 0, 3) << 8 | src_ptr[1]; ++ goto copy_literal_and_match; ++ ++med_d: ++ UPDATE_GOOD; ++ /* ++ * "medium distance": This is a minor variant of the "small distance" ++ * encoding, where we will now use two extra bytes instead of one to ++ * encode the restof the match length and distance. This allows an extra ++ * two bits for the match length, and an extra three bits for the match ++ * distance. The full structure of the opcode is ++ * 101LLMMM DDDDDDMM DDDDDDDD LITERAL. ++ */ ++ opc_len = 3; ++ L = (size_t)extract(opc, 3, 2); ++ if (src_len <= opc_len + L) ++ return; /* source truncated */ ++ opc23 = load2(&src_ptr[1]); ++ M = (size_t)((extract(opc, 0, 3) << 2 | extract(opc23, 0, 2)) + 3); ++ D = (size_t)extract(opc23, 2, 14); ++ goto copy_literal_and_match; ++ ++lrg_d: ++ UPDATE_GOOD; ++ /* ++ * "large distance": This is another variant of the "small distance" ++ * encoding, where we will now use two extra bytes to encode the match ++ * distance, which allows distances up to 65535 to be represented. The ++ * full structure of the opcode is LLMMM111 DDDDDDDD DDDDDDDD LITERAL. ++ */ ++ opc_len = 3; ++ L = (size_t)extract(opc, 6, 2); ++ M = (size_t)extract(opc, 3, 3) + 3; ++ if (src_len <= opc_len + L) ++ return; /* source truncated */ ++ D = load2(&src_ptr[1]); ++ goto copy_literal_and_match; ++ ++pre_d: ++ UPDATE_GOOD; ++ /* ++ * "previous distance": This opcode has the structure LLMMM110, where ++ * the length of the literal (0-3 bytes) is encoded by the high 2 bits ++ * of the first byte. We first extract the literal length so we know how ++ * long the opcode is, then check that the source can hold both this ++ * opcode and at least one byte of the next (because any valid input ++ * stream must be terminated with an eos token). ++ */ ++ opc_len = 1; ++ L = (size_t)extract(opc, 6, 2); ++ M = (size_t)extract(opc, 3, 3) + 3; ++ if (src_len <= opc_len + L) ++ return; /* source truncated */ ++ goto copy_literal_and_match; ++ ++copy_literal_and_match: ++ /* ++ * Common implementation of writing data for opcodes that have both a ++ * literal and a match. We begin by advancing the source pointer past ++ * the opcode, so that it points at the first literal byte (if L ++ * is non-zero; otherwise it points at the next opcode). ++ */ ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ /* Now we copy the literal from the source pointer to the destination */ ++ if (__builtin_expect(dst_len >= 4 && src_len >= 4, 1)) { ++ /* ++ * The literal is 0-3 bytes; if we are not near the end of the ++ * buffer, we can safely just do a 4 byte copy (which is ++ * guaranteed to cover the complete literal, and may include ++ * some other bytes as well). ++ */ ++ store4(dst_ptr, load4(src_ptr)); ++ } else if (L <= dst_len) { ++ /* ++ * We are too close to the end of either the input or output ++ * stream to be able to safely use a four-byte copy, but we will ++ * not exhaust either stream (we already know that the source ++ * will not be exhausted from checks in the individual opcode ++ * implementations, and we just tested that dst_len > L). Thus, ++ * we need to do a byte-by-byte copy of the literal. This is ++ * slow, but it can only ever happen near the very end of a ++ * buffer, so it is not an important case to optimize. ++ */ ++ size_t i; ++ ++ for (i = 0; i < L; ++i) ++ dst_ptr[i] = src_ptr[i]; ++ } else { ++ /* Destination truncated: fill DST, and store partial match */ ++ ++ /* Copy partial literal */ ++ size_t i; ++ ++ for (i = 0; i < dst_len; ++i) ++ dst_ptr[i] = src_ptr[i]; ++ /* Save state */ ++ state->src = src_ptr + dst_len; ++ state->dst = dst_ptr + dst_len; ++ state->L = L - dst_len; ++ state->M = M; ++ state->D = D; ++ return; /* destination truncated */ ++ } ++ /* ++ * Having completed the copy of the literal, we advance both the source ++ * and destination pointers by the number of literal bytes. ++ */ ++ PTR_LEN_INC(dst_ptr, dst_len, L); ++ PTR_LEN_INC(src_ptr, src_len, L); ++ /* ++ * Check if the match distance is valid; matches must not reference ++ * bytes that preceed the start of the output buffer, nor can the match ++ * distance be zero. ++ */ ++ if (D > dst_ptr - state->dst_begin || D == 0) ++ goto invalid_match_distance; ++copy_match: ++ /* ++ * Now we copy the match from dst_ptr - D to dst_ptr. It is important to ++ * keep in mind that we may have D < M, in which case the source and ++ * destination windows overlap in the copy. The semantics of the match ++ * copy are *not* those of memmove( ); if the buffers overlap it needs ++ * to behave as though we were copying byte-by-byte in increasing ++ * address order. If, for example, D is 1, the copy operation is ++ * equivalent to: ++ * ++ * memset(dst_ptr, dst_ptr[-1], M); ++ * ++ * i.e. it splats the previous byte. This means that we need to be very ++ * careful about using wide loads or stores to perform the copy ++ * operation. ++ */ ++ if (__builtin_expect(dst_len >= M + 7 && D >= 8, 1)) { ++ /* ++ * We are not near the end of the buffer, and the match distance ++ * is at least eight. Thus, we can safely loop using eight byte ++ * copies. The last of these may slop over the intended end of ++ * the match, but this is OK because we know we have a safety ++ * bound away from the end of the destination buffer. ++ */ ++ size_t i; ++ ++ for (i = 0; i < M; i += 8) ++ store8(&dst_ptr[i], load8(&dst_ptr[i - D])); ++ } else if (M <= dst_len) { ++ /* ++ * Either the match distance is too small, or we are too close ++ * to the end of the buffer to safely use eight byte copies. ++ * Fall back on a simple byte-by-byte implementation. ++ */ ++ size_t i; ++ ++ for (i = 0; i < M; ++i) ++ dst_ptr[i] = dst_ptr[i - D]; ++ } else { ++ /* Destination truncated: fill DST, and store partial match */ ++ ++ /* Copy partial match */ ++ size_t i; ++ ++ for (i = 0; i < dst_len; ++i) ++ dst_ptr[i] = dst_ptr[i - D]; ++ /* Save state */ ++ state->src = src_ptr; ++ state->dst = dst_ptr + dst_len; ++ state->L = 0; ++ state->M = M - dst_len; ++ state->D = D; ++ return; /* destination truncated */ ++ } ++ /* ++ * Update the destination pointer and length to account for the bytes ++ * written by the match, then load the next opcode byte and branch to ++ * the appropriate implementation. ++ */ ++ PTR_LEN_INC(dst_ptr, dst_len, M); ++ opc = src_ptr[0]; ++ goto *opc_tbl[opc]; ++ ++/* ++ * =============================================================== ++ * Opcodes representing only a match (no literal). ++ * These two opcodes (lrg_m and sml_m) encode only a match. The match ++ * distance is carried over from the previous opcode, so all they need ++ * to encode is the match length. We are able to reuse the match copy ++ * sequence from the literal and match opcodes to perform the actual ++ * copy implementation. ++ */ ++sml_m: ++ UPDATE_GOOD; ++ /* ++ * "small match": This opcode has no literal, and uses the previous ++ * match distance (i.e. it encodes only the match length), in a single ++ * byte as 1111MMMM. ++ */ ++ opc_len = 1; ++ if (src_len <= opc_len) ++ return; /* source truncated */ ++ M = (size_t)extract(opc, 0, 4); ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ goto copy_match; ++ ++lrg_m: ++ UPDATE_GOOD; ++ /* ++ * "large match": This opcode has no literal, and uses the previous ++ * match distance (i.e. it encodes only the match length). It is encoded ++ * in two bytes as 11110000 MMMMMMMM. Because matches smaller than 16 ++ * bytes can be represented by sml_m, there is an implicit bias of 16 on ++ * the match length; the representable values are [16,271]. ++ */ ++ opc_len = 2; ++ if (src_len <= opc_len) ++ return; /* source truncated */ ++ M = src_ptr[1] + 16; ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ goto copy_match; ++ ++/* ++ * =============================================================== ++ * Opcodes representing only a literal (no match). ++ * These two opcodes (lrg_l and sml_l) encode only a literal. There is no ++ * match length or match distance to worry about (but we need to *not* ++ * touch D, as it must be preserved between opcodes). ++ */ ++sml_l: ++ UPDATE_GOOD; ++ /* ++ * "small literal": This opcode has no match, and encodes only a literal ++ * of length up to 15 bytes. The format is 1110LLLL LITERAL. ++ */ ++ opc_len = 1; ++ L = (size_t)extract(opc, 0, 4); ++ goto copy_literal; ++ ++lrg_l: ++ UPDATE_GOOD; ++ /* ++ * "large literal": This opcode has no match, and uses the previous ++ * match distance (i.e. it encodes only the match length). It is encoded ++ * in two bytes as 11100000 LLLLLLLL LITERAL. Because literals smaller ++ * than 16 bytes can be represented by sml_l, there is an implicit bias ++ * of 16 on the literal length; the representable values are [16,271]. ++ */ ++ opc_len = 2; ++ if (src_len <= 2) ++ return; /* source truncated */ ++ L = src_ptr[1] + 16; ++ goto copy_literal; ++ ++copy_literal: ++ /* ++ * Check that the source buffer is large enough to hold the complete ++ * literal and at least the first byte of the next opcode. If so, ++ * advance the source pointer to point to the first byte of the literal ++ * and adjust the source length accordingly. ++ */ ++ if (src_len <= opc_len + L) ++ return; /* source truncated */ ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ /* Now we copy the literal from the source pointer to the destination */ ++ if (dst_len >= L + 7 && src_len >= L + 7) { ++ /* ++ * We are not near the end of the source or destination buffers; ++ * thus we can safely copy the literal using wide copies, ++ * without worrying about reading or writing past the end of ++ * either buffer. ++ */ ++ size_t i; ++ ++ for (i = 0; i < L; i += 8) ++ store8(&dst_ptr[i], load8(&src_ptr[i])); ++ } else if (L <= dst_len) { ++ /* ++ * We are too close to the end of either the input or output ++ * stream to be able to safely use an eight-byte copy. Instead ++ * we copy the literal byte-by-byte. ++ */ ++ size_t i; ++ ++ for (i = 0; i < L; ++i) ++ dst_ptr[i] = src_ptr[i]; ++ } else { ++ /* Destination truncated: fill DST, and store partial match */ ++ ++ /* Copy partial literal */ ++ size_t i; ++ ++ for (i = 0; i < dst_len; ++i) ++ dst_ptr[i] = src_ptr[i]; ++ /* Save state */ ++ state->src = src_ptr + dst_len; ++ state->dst = dst_ptr + dst_len; ++ state->L = L - dst_len; ++ state->M = 0; ++ state->D = D; ++ return; /* destination truncated */ ++ } ++ /* ++ * Having completed the copy of the literal, we advance both the source ++ * and destination pointers by the number of literal bytes. ++ */ ++ PTR_LEN_INC(dst_ptr, dst_len, L); ++ PTR_LEN_INC(src_ptr, src_len, L); ++ /* Load the first byte of the next opcode, and jump to its implementation */ ++ opc = src_ptr[0]; ++ goto *opc_tbl[opc]; ++ ++/* ++ * =============================================================== ++ * Other opcodes ++ */ ++nop: ++ UPDATE_GOOD; ++ opc_len = 1; ++ if (src_len <= opc_len) ++ return; /* source truncated */ ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ opc = src_ptr[0]; ++ goto *opc_tbl[opc]; ++ ++eos: ++ opc_len = 8; ++ if (src_len < opc_len) ++ return; /* source truncated (here we don't need an extra byte for next op code) */ ++ PTR_LEN_INC(src_ptr, src_len, opc_len); ++ state->end_of_stream = 1; ++ UPDATE_GOOD; ++ return; /* end-of-stream */ ++ ++/* ++ * =============================================================== ++ * Return on error ++ */ ++udef: ++invalid_match_distance: ++ ++ return; /* we already updated state */ ++} +diff --git a/fs/apfs/lzfse/lzvn_decode_base.h b/fs/apfs/lzfse/lzvn_decode_base.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/lzfse/lzvn_decode_base.h +@@ -0,0 +1,73 @@ ++/* SPDX-License-Identifier: BSD-3-Clause */ ++/* ++ * Copyright (c) 2015-2016, Apple Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the distribution. ++ * ++ * 3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * LZVN low-level decoder (v2) ++ * Functions in the low-level API should switch to these at some point. ++ * Apr 2014 ++ */ ++ ++#ifndef LZVN_DECODE_BASE_H ++#define LZVN_DECODE_BASE_H ++ ++#include "lzfse_internal.h" ++ ++/*! @abstract Base decoder state. */ ++typedef struct { ++ /* Decoder I/O */ ++ ++ /* Next byte to read in source buffer */ ++ const unsigned char *src; ++ /* Next byte after source buffer */ ++ const unsigned char *src_end; ++ ++ /* Next byte to write in destination buffer (by decoder) */ ++ unsigned char *dst; ++ /* Valid range for destination buffer is [dst_begin, dst_end - 1] */ ++ unsigned char *dst_begin; ++ unsigned char *dst_end; ++ /* Next byte to read in destination buffer (modified by caller) */ ++ unsigned char *dst_current; ++ ++ /* Decoder state */ ++ ++ /* ++ * Partially expanded match, or 0,0,0. ++ * In that case, src points to the next literal to copy, or the next ++ * op-code if L==0. ++ */ ++ size_t L, M, D; ++ ++ /* Distance for last emitted match, or 0 */ ++ lzvn_offset d_prev; ++ ++ /* Did we decode end-of-stream? */ ++ int end_of_stream; ++ ++} lzvn_decoder_state; ++ ++/*! @abstract Decode source to destination. ++ * Updates \p state (src,dst,d_prev). ++ */ ++void lzvn_decode(lzvn_decoder_state *state); ++ ++#endif /* LZVN_DECODE_BASE_H */ +diff --git a/fs/apfs/message.c b/fs/apfs/message.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/message.c +@@ -0,0 +1,29 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include "apfs.h" ++ ++void apfs_msg(struct super_block *sb, const char *prefix, const char *func, int line, const char *fmt, ...) ++{ ++ char *sb_id = NULL; ++ struct va_format vaf; ++ va_list args; ++ ++ va_start(args, fmt); ++ ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ /* The superblock is not available to all callers */ ++ sb_id = sb ? sb->s_id : "?"; ++ ++ if (func) ++ printk("%sAPFS (%s): %pV (%s:%d)\n", prefix, sb_id, &vaf, func, line); ++ else ++ printk("%sAPFS (%s): %pV\n", prefix, sb_id, &vaf); ++ ++ va_end(args); ++} +diff --git a/fs/apfs/namei.c b/fs/apfs/namei.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/namei.c +@@ -0,0 +1,146 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include "apfs.h" ++#include "unicode.h" ++ ++static struct dentry *apfs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags) ++{ ++ struct inode *inode = NULL; ++ u64 ino = 0; ++ int err; ++ ++ if (dentry->d_name.len > APFS_NAME_LEN) ++ return ERR_PTR(-ENAMETOOLONG); ++ ++ err = apfs_inode_by_name(dir, &dentry->d_name, &ino); ++ if (err && err != -ENODATA) { ++ apfs_err(dir->i_sb, "inode lookup by name failed"); ++ return ERR_PTR(err); ++ } ++ ++ if (!err) { ++ inode = apfs_iget(dir->i_sb, ino); ++ if (IS_ERR(inode)) { ++ apfs_err(dir->i_sb, "iget failed"); ++ return ERR_CAST(inode); ++ } ++ } ++ ++ return d_splice_alias(inode, dentry); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++static int apfs_symlink(struct inode *dir, struct dentry *dentry, ++ const char *symname) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++static int apfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, ++ struct dentry *dentry, const char *symname) ++#else ++static int apfs_symlink(struct mnt_idmap *idmap, struct inode *dir, ++ struct dentry *dentry, const char *symname) ++#endif ++{ ++ /* Symlink permissions don't mean anything and their value is fixed */ ++ return apfs_mkany(dir, dentry, S_IFLNK | 0x1ed, 0 /* rdev */, symname); ++} ++ ++const struct inode_operations apfs_dir_inode_operations = { ++ .create = apfs_create, ++ .lookup = apfs_lookup, ++ .link = apfs_link, ++ .unlink = apfs_unlink, ++ .symlink = apfs_symlink, ++ .mkdir = apfs_mkdir, ++ .rmdir = apfs_rmdir, ++ .mknod = apfs_mknod, ++ .rename = apfs_rename, ++ .getattr = apfs_getattr, ++ .listxattr = apfs_listxattr, ++ .setattr = apfs_setattr, ++ .update_time = apfs_update_time, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) ++ .fileattr_get = apfs_fileattr_get, ++ .fileattr_set = apfs_fileattr_set, ++#endif ++}; ++ ++const struct inode_operations apfs_special_inode_operations = { ++ .getattr = apfs_getattr, ++ .listxattr = apfs_listxattr, ++ .setattr = apfs_setattr, ++ .update_time = apfs_update_time, ++}; ++ ++static int apfs_dentry_hash(const struct dentry *dir, struct qstr *child) ++{ ++ struct apfs_unicursor cursor; ++ unsigned long hash; ++ bool case_fold = apfs_is_case_insensitive(dir->d_sb); ++ ++ if (!apfs_is_normalization_insensitive(dir->d_sb)) ++ return 0; ++ ++ apfs_init_unicursor(&cursor, child->name, child->len); ++ hash = init_name_hash(dir); ++ ++ while (1) { ++ int i; ++ unicode_t utf32; ++ ++ utf32 = apfs_normalize_next(&cursor, case_fold); ++ if (!utf32) ++ break; ++ ++ /* Hash the unicode character one byte at a time */ ++ for (i = 0; i < 4; ++i) { ++ hash = partial_name_hash((u8)utf32, hash); ++ utf32 = utf32 >> 8; ++ } ++ } ++ child->hash = end_name_hash(hash); ++ ++ /* TODO: return error instead of truncating invalid UTF-8? */ ++ return 0; ++} ++ ++static int apfs_dentry_compare(const struct dentry *dentry, unsigned int len, ++ const char *str, const struct qstr *name) ++{ ++ return apfs_filename_cmp(dentry->d_sb, name->name, name->len, str, len); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 14, 0) ++static int apfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) ++#else ++static int apfs_dentry_revalidate(struct inode *dir, const struct qstr *name, struct dentry *dentry, unsigned int flags) ++#endif ++{ ++ struct super_block *sb = dentry->d_sb; ++ ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ ++ /* ++ * If we want to create a link with a name that normalizes to the same ++ * as an existing negative dentry, then we first need to invalidate the ++ * dentry; otherwise it would keep the existing name. ++ */ ++ if (d_really_is_positive(dentry)) ++ return 1; ++ if (!apfs_is_case_insensitive(sb) && !apfs_is_normalization_insensitive(sb)) ++ return 1; ++ if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) ++ return 0; ++ return 1; ++} ++ ++const struct dentry_operations apfs_dentry_operations = { ++ .d_revalidate = apfs_dentry_revalidate, ++ .d_hash = apfs_dentry_hash, ++ .d_compare = apfs_dentry_compare, ++}; +diff --git a/fs/apfs/node.c b/fs/apfs/node.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/node.c +@@ -0,0 +1,2069 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_node_is_valid - Check basic sanity of the node index ++ * @sb: filesystem superblock ++ * @node: node to check ++ * ++ * Verifies that the node index fits in a single block, and that the number ++ * of records fits in the index. Without this check a crafted filesystem could ++ * pretend to have too many records, and calls to apfs_node_locate_key() and ++ * apfs_node_locate_value() would read beyond the limits of the node. ++ */ ++static bool apfs_node_is_valid(struct super_block *sb, ++ struct apfs_node *node) ++{ ++ u32 records = node->records; ++ int index_size = node->key - sizeof(struct apfs_btree_node_phys); ++ int entry_size; ++ ++ if (node->key > sb->s_blocksize) ++ return false; ++ ++ entry_size = (apfs_node_has_fixed_kv_size(node)) ? ++ sizeof(struct apfs_kvoff) : sizeof(struct apfs_kvloc); ++ ++ /* Coarse bound to prevent multiplication overflow in final check */ ++ if (records > 1 << 16) ++ return false; ++ ++ return records * entry_size <= index_size; ++} ++ ++void apfs_node_free(struct apfs_node *node) ++{ ++ struct apfs_object *obj = NULL; ++ ++ if (!node) ++ return; ++ obj = &node->object; ++ ++ if (obj->o_bh) { ++ brelse(obj->o_bh); ++ obj->o_bh = NULL; ++ } else if (!obj->ephemeral) { ++ /* Ephemeral data always remains in memory */ ++ kfree(obj->data); ++ } ++ obj->data = NULL; ++ ++ kfree(node); ++} ++ ++/** ++ * apfs_read_node - Read a node header from disk ++ * @sb: filesystem superblock ++ * @oid: object id for the node ++ * @storage: storage type for the node object ++ * @write: request write access? ++ * ++ * Returns ERR_PTR in case of failure, otherwise return a pointer to the ++ * resulting apfs_node structure with the initial reference taken. ++ * ++ * For now we assume the node has not been read before. ++ */ ++struct apfs_node *apfs_read_node(struct super_block *sb, u64 oid, u32 storage, ++ bool write) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct buffer_head *bh = NULL; ++ struct apfs_ephemeral_object_info *eph_info = NULL; ++ struct apfs_btree_node_phys *raw = NULL; ++ struct apfs_node *node = NULL; ++ struct apfs_nloc *free_head = NULL; ++ u64 bno; ++ int err; ++ ++ switch (storage) { ++ case APFS_OBJ_VIRTUAL: ++ /* All virtual nodes are inside a volume, at least for now */ ++ err = apfs_omap_lookup_block(sb, sbi->s_omap, oid, &bno, write); ++ if (err) { ++ apfs_err(sb, "omap lookup failed for oid 0x%llx", oid); ++ return ERR_PTR(err); ++ } ++ /* CoW has already been done, don't worry about snapshots */ ++ bh = apfs_read_object_block(sb, bno, write, false /* preserve */); ++ if (IS_ERR(bh)) { ++ apfs_err(sb, "object read failed for bno 0x%llx", bno); ++ return (void *)bh; ++ } ++ bno = bh->b_blocknr; ++ raw = (struct apfs_btree_node_phys *)bh->b_data; ++ break; ++ case APFS_OBJ_PHYSICAL: ++ bh = apfs_read_object_block(sb, oid, write, false /* preserve */); ++ if (IS_ERR(bh)) { ++ apfs_err(sb, "object read failed for bno 0x%llx", oid); ++ return (void *)bh; ++ } ++ bno = oid = bh->b_blocknr; ++ raw = (struct apfs_btree_node_phys *)bh->b_data; ++ break; ++ case APFS_OBJ_EPHEMERAL: ++ /* Ephemeral objects are already in memory */ ++ eph_info = apfs_ephemeral_object_lookup(sb, oid); ++ if (IS_ERR(eph_info)) { ++ apfs_err(sb, "no ephemeral node for oid 0x%llx", oid); ++ return (void *)eph_info; ++ } ++ if (eph_info->size != sb->s_blocksize) { ++ apfs_err(sb, "unsupported size for ephemeral node (%u)", eph_info->size); ++ return ERR_PTR(-EOPNOTSUPP); ++ } ++ bno = 0; /* In memory, so meaningless */ ++ raw = eph_info->object; ++ /* Only for consistency, will happen again on commit */ ++ if (write) ++ raw->btn_o.o_xid = cpu_to_le64(nxi->nx_xid); ++ break; ++ default: ++ apfs_alert(sb, "invalid storage type %u - bug!", storage); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ node = kmalloc(sizeof(*node), GFP_KERNEL); ++ if (!node) { ++ brelse(bh); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ node->tree_type = le32_to_cpu(raw->btn_o.o_subtype); ++ node->flags = le16_to_cpu(raw->btn_flags); ++ node->records = le32_to_cpu(raw->btn_nkeys); ++ node->key = sizeof(*raw) + le16_to_cpu(raw->btn_table_space.off) ++ + le16_to_cpu(raw->btn_table_space.len); ++ node->free = node->key + le16_to_cpu(raw->btn_free_space.off); ++ node->val = node->free + le16_to_cpu(raw->btn_free_space.len); ++ ++ free_head = &raw->btn_key_free_list; ++ node->key_free_list_len = le16_to_cpu(free_head->len); ++ free_head = &raw->btn_val_free_list; ++ node->val_free_list_len = le16_to_cpu(free_head->len); ++ ++ node->object.sb = sb; ++ node->object.block_nr = bno; ++ node->object.oid = oid; ++ node->object.o_bh = bh; ++ node->object.data = (char *)raw; ++ node->object.ephemeral = !bh; ++ ++ /* Ephemeral objects already got checked on mount */ ++ if (!node->object.ephemeral && nxi->nx_flags & APFS_CHECK_NODES && !apfs_obj_verify_csum(sb, bh)) { ++ /* TODO: don't check this twice for virtual/physical objects */ ++ apfs_err(sb, "bad checksum for node in block 0x%llx", (unsigned long long)bno); ++ apfs_node_free(node); ++ return ERR_PTR(-EFSBADCRC); ++ } ++ if (!apfs_node_is_valid(sb, node)) { ++ apfs_err(sb, "bad node in block 0x%llx", (unsigned long long)bno); ++ apfs_node_free(node); ++ return ERR_PTR(-EFSCORRUPTED); ++ } ++ ++ return node; ++} ++ ++/** ++ * apfs_node_min_table_size - Return the minimum size for a node's toc ++ * @sb: superblock structure ++ * @type: tree type for the node ++ * @flags: flags for the node ++ */ ++static int apfs_node_min_table_size(struct super_block *sb, u32 type, u16 flags) ++{ ++ bool leaf = flags & APFS_BTNODE_LEAF; ++ int key_size, val_size, toc_size; ++ int space, count; ++ ++ /* Preallocate the whole table for trees with fixed key/value sizes */ ++ switch (type) { ++ case APFS_OBJECT_TYPE_OMAP: ++ key_size = sizeof(struct apfs_omap_key); ++ val_size = leaf ? sizeof(struct apfs_omap_val) : sizeof(__le64); ++ toc_size = sizeof(struct apfs_kvoff); ++ break; ++ case APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE: ++ key_size = sizeof(struct apfs_spaceman_free_queue_key); ++ val_size = sizeof(__le64); /* We assume no ghosts here */ ++ toc_size = sizeof(struct apfs_kvoff); ++ break; ++ case APFS_OBJECT_TYPE_OMAP_SNAPSHOT: ++ key_size = sizeof(__le64); ++ val_size = leaf ? sizeof(struct apfs_omap_snapshot) : sizeof(__le64); ++ toc_size = sizeof(struct apfs_kvoff); ++ break; ++ case APFS_OBJECT_TYPE_FEXT_TREE: ++ key_size = sizeof(struct apfs_fext_tree_key); ++ val_size = leaf ? sizeof(struct apfs_fext_tree_val) : sizeof(__le64); ++ toc_size = sizeof(struct apfs_kvoff); ++ break; ++ default: ++ /* Make room for one record at least */ ++ toc_size = sizeof(struct apfs_kvloc); ++ return APFS_BTREE_TOC_ENTRY_INCREMENT * toc_size; ++ } ++ ++ /* The footer of root nodes is ignored for some reason */ ++ space = sb->s_blocksize - sizeof(struct apfs_btree_node_phys); ++ count = space / (key_size + val_size + toc_size); ++ return count * toc_size; ++} ++ ++/** ++ * apfs_set_empty_btree_info - Set the info footer for an empty b-tree node ++ * @sb: filesystem superblock ++ * @info: pointer to the on-disk info footer ++ * @subtype: subtype of the root node, i.e., tree type ++ * ++ * For now only supports the extent reference tree. ++ */ ++static void apfs_set_empty_btree_info(struct super_block *sb, struct apfs_btree_info *info, u32 subtype) ++{ ++ u32 flags; ++ ++ ASSERT(subtype == APFS_OBJECT_TYPE_BLOCKREFTREE || subtype == APFS_OBJECT_TYPE_OMAP_SNAPSHOT); ++ ++ memset(info, 0, sizeof(*info)); ++ ++ flags = APFS_BTREE_PHYSICAL; ++ if (subtype == APFS_OBJECT_TYPE_BLOCKREFTREE) ++ flags |= APFS_BTREE_KV_NONALIGNED; ++ ++ info->bt_fixed.bt_flags = cpu_to_le32(flags); ++ info->bt_fixed.bt_node_size = cpu_to_le32(sb->s_blocksize); ++ info->bt_key_count = 0; ++ info->bt_node_count = cpu_to_le64(1); /* Only one node: the root */ ++ if (subtype == APFS_OBJECT_TYPE_BLOCKREFTREE) ++ return; ++ ++ info->bt_fixed.bt_key_size = cpu_to_le32(8); ++ info->bt_longest_key = info->bt_fixed.bt_key_size; ++ info->bt_fixed.bt_val_size = cpu_to_le32(sizeof(struct apfs_omap_snapshot)); ++ info->bt_longest_val = info->bt_fixed.bt_val_size; ++} ++ ++/** ++ * apfs_make_empty_btree_root - Make an empty root for a b-tree ++ * @sb: filesystem superblock ++ * @subtype: subtype of the root node, i.e., tree type ++ * @oid: on return, the root's object id ++ * ++ * For now only supports the extent reference tree and an omap's snapshot tree. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_make_empty_btree_root(struct super_block *sb, u32 subtype, u64 *oid) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_btree_node_phys *root = NULL; ++ struct buffer_head *bh = NULL; ++ u64 bno; ++ u16 flags; ++ int toc_len, free_len, head_len, info_len; ++ int err; ++ ++ ASSERT(subtype == APFS_OBJECT_TYPE_BLOCKREFTREE || subtype == APFS_OBJECT_TYPE_OMAP_SNAPSHOT); ++ ++ err = apfs_spaceman_allocate_block(sb, &bno, true /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ return err; ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, 1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_alloced, 1); ++ ++ bh = apfs_getblk(sb, bno); ++ if (!bh) ++ return -EIO; ++ root = (void *)bh->b_data; ++ err = apfs_transaction_join(sb, bh); ++ if (err) ++ goto fail; ++ set_buffer_csum(bh); ++ ++ flags = APFS_BTNODE_ROOT | APFS_BTNODE_LEAF; ++ if (subtype == APFS_OBJECT_TYPE_OMAP_SNAPSHOT) ++ flags |= APFS_BTNODE_FIXED_KV_SIZE; ++ root->btn_flags = cpu_to_le16(flags); ++ ++ toc_len = apfs_node_min_table_size(sb, subtype, flags); ++ head_len = sizeof(*root); ++ info_len = sizeof(struct apfs_btree_info); ++ free_len = sb->s_blocksize - head_len - toc_len - info_len; ++ ++ root->btn_level = 0; /* Root */ ++ ++ /* No keys and no values, so this is straightforward */ ++ root->btn_nkeys = 0; ++ root->btn_table_space.off = 0; ++ root->btn_table_space.len = cpu_to_le16(toc_len); ++ root->btn_free_space.off = 0; ++ root->btn_free_space.len = cpu_to_le16(free_len); ++ ++ /* No fragmentation */ ++ root->btn_key_free_list.off = cpu_to_le16(APFS_BTOFF_INVALID); ++ root->btn_key_free_list.len = 0; ++ root->btn_val_free_list.off = cpu_to_le16(APFS_BTOFF_INVALID); ++ root->btn_val_free_list.len = 0; ++ ++ apfs_set_empty_btree_info(sb, (void *)root + sb->s_blocksize - info_len, subtype); ++ ++ root->btn_o.o_oid = cpu_to_le64(bno); ++ root->btn_o.o_xid = cpu_to_le64(APFS_NXI(sb)->nx_xid); ++ root->btn_o.o_type = cpu_to_le32(APFS_OBJECT_TYPE_BTREE | APFS_OBJ_PHYSICAL); ++ root->btn_o.o_subtype = cpu_to_le32(subtype); ++ ++ *oid = bno; ++ err = 0; ++fail: ++ root = NULL; ++ brelse(bh); ++ bh = NULL; ++ return err; ++} ++ ++/** ++ * apfs_create_node - Allocates a new nonroot b-tree node on disk ++ * @sb: filesystem superblock ++ * @storage: storage type for the node object ++ * ++ * On success returns a pointer to the new in-memory node structure; the object ++ * header is initialized, and the node fields are given reasonable defaults. ++ * On failure, returns an error pointer. ++ */ ++static struct apfs_node *apfs_create_node(struct super_block *sb, u32 storage) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *msb_raw = nxi->nx_raw; ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_ephemeral_object_info *eph_info = NULL; ++ struct apfs_node *node = NULL; ++ struct buffer_head *bh = NULL; ++ struct apfs_btree_node_phys *raw = NULL; ++ u64 bno, oid; ++ int err; ++ ++ switch (storage) { ++ case APFS_OBJ_VIRTUAL: ++ err = apfs_spaceman_allocate_block(sb, &bno, true /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ return ERR_PTR(err); ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, 1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_alloced, 1); ++ ++ oid = le64_to_cpu(msb_raw->nx_next_oid); ++ le64_add_cpu(&msb_raw->nx_next_oid, 1); ++ err = apfs_create_omap_rec(sb, oid, bno); ++ if (err) { ++ apfs_err(sb, "omap rec creation failed (0x%llx-0x%llx)", oid, bno); ++ return ERR_PTR(err); ++ } ++ break; ++ case APFS_OBJ_PHYSICAL: ++ err = apfs_spaceman_allocate_block(sb, &bno, true /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ return ERR_PTR(err); ++ } ++ /* We don't write to the container's omap */ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, 1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_alloced, 1); ++ oid = bno; ++ break; ++ case APFS_OBJ_EPHEMERAL: ++ if (nxi->nx_eph_count >= APFS_EPHEMERAL_LIST_LIMIT) { ++ apfs_err(sb, "creating too many ephemeral objects?"); ++ return ERR_PTR(-EOPNOTSUPP); ++ } ++ eph_info = &nxi->nx_eph_list[nxi->nx_eph_count++]; ++ eph_info->object = kzalloc(sb->s_blocksize, GFP_KERNEL); ++ if (!eph_info->object) ++ return ERR_PTR(-ENOMEM); ++ eph_info->size = sb->s_blocksize; ++ oid = eph_info->oid = le64_to_cpu(msb_raw->nx_next_oid); ++ le64_add_cpu(&msb_raw->nx_next_oid, 1); ++ break; ++ default: ++ apfs_alert(sb, "invalid storage type %u - bug!", storage); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (storage == APFS_OBJ_EPHEMERAL) { ++ bh = NULL; ++ bno = 0; ++ raw = eph_info->object; ++ } else { ++ bh = apfs_getblk(sb, bno); ++ if (!bh) ++ return ERR_PTR(-EIO); ++ bno = bh->b_blocknr; ++ raw = (void *)bh->b_data; ++ err = apfs_transaction_join(sb, bh); ++ if (err) ++ goto fail; ++ set_buffer_csum(bh); ++ } ++ ++ /* Set most of the object header, but the subtype is up to the caller */ ++ raw->btn_o.o_oid = cpu_to_le64(oid); ++ raw->btn_o.o_xid = cpu_to_le64(nxi->nx_xid); ++ raw->btn_o.o_type = cpu_to_le32(storage | APFS_OBJECT_TYPE_BTREE_NODE); ++ raw->btn_o.o_subtype = 0; ++ ++ /* The caller is expected to change most node fields */ ++ raw->btn_flags = 0; ++ raw->btn_level = 0; ++ raw->btn_nkeys = 0; ++ raw->btn_table_space.off = 0; /* Put the toc right after the header */ ++ raw->btn_table_space.len = 0; ++ raw->btn_free_space.off = 0; ++ raw->btn_free_space.len = cpu_to_le16(sb->s_blocksize - sizeof(*raw)); ++ raw->btn_key_free_list.off = cpu_to_le16(APFS_BTOFF_INVALID); ++ raw->btn_key_free_list.len = 0; ++ raw->btn_val_free_list.off = cpu_to_le16(APFS_BTOFF_INVALID); ++ raw->btn_val_free_list.len = 0; ++ ++ node = kmalloc(sizeof(*node), GFP_KERNEL); ++ if (!node) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ node->object.sb = sb; ++ node->object.block_nr = bno; ++ node->object.oid = oid; ++ node->object.o_bh = bh; ++ node->object.data = (char *)raw; ++ node->object.ephemeral = !bh; ++ return node; ++ ++fail: ++ if (storage == APFS_OBJ_EPHEMERAL) ++ kfree(raw); ++ else ++ brelse(bh); ++ raw = NULL; ++ bh = NULL; ++ return ERR_PTR(err); ++} ++ ++/** ++ * apfs_delete_node - Deletes a nonroot node from disk ++ * @node: node to delete ++ * @type: tree type for the query that found the node ++ * ++ * Does nothing to the in-memory node structure. Returns 0 on success, or a ++ * negative error code in case of failure. ++ */ ++int apfs_delete_node(struct apfs_node *node, int type) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_superblock *vsb_raw; ++ u64 oid = node->object.oid; ++ u64 bno = node->object.block_nr; ++ struct apfs_ephemeral_object_info *eph_info = NULL, *eph_info_end = NULL; ++ int err; ++ ++ switch (type) { ++ case APFS_QUERY_CAT: ++ err = apfs_free_queue_insert(sb, bno, 1); ++ if (err) { ++ apfs_err(sb, "free queue insertion failed for 0x%llx", bno); ++ return err; ++ } ++ err = apfs_delete_omap_rec(sb, oid); ++ if (err) { ++ apfs_err(sb, "omap rec deletion failed (0x%llx)", oid); ++ return err; ++ } ++ vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, -1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_freed, 1); ++ return 0; ++ case APFS_QUERY_OMAP: ++ case APFS_QUERY_EXTENTREF: ++ case APFS_QUERY_SNAP_META: ++ err = apfs_free_queue_insert(sb, bno, 1); ++ if (err) { ++ apfs_err(sb, "free queue insertion failed for 0x%llx", bno); ++ return err; ++ } ++ /* We don't write to the container's omap */ ++ vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, -1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_freed, 1); ++ return 0; ++ case APFS_QUERY_FREE_QUEUE: ++ eph_info_end = &nxi->nx_eph_list[nxi->nx_eph_count]; ++ eph_info = apfs_ephemeral_object_lookup(sb, node->object.oid); ++ if (IS_ERR(eph_info)) { ++ apfs_alert(sb, "can't find ephemeral object to delete"); ++ return PTR_ERR(eph_info); ++ } ++ kfree(eph_info->object); ++ eph_info->object = NULL; ++ memmove(eph_info, eph_info + 1, (char *)eph_info_end - (char *)(eph_info + 1)); ++ eph_info_end->object = NULL; ++ --nxi->nx_eph_count; ++ return 0; ++ default: ++ apfs_alert(sb, "new query type must implement node deletion (%d)", type); ++ return -EOPNOTSUPP; ++ } ++} ++ ++/** ++ * apfs_update_node - Update an existing node header ++ * @node: the modified in-memory node ++ */ ++void apfs_update_node(struct apfs_node *node) ++{ ++ struct super_block *sb = node->object.sb; ++ struct buffer_head *bh = node->object.o_bh; ++ struct apfs_btree_node_phys *raw = (void *)node->object.data; ++ struct apfs_nloc *free_head; ++ u32 tflags, type; ++ int toc_off; ++ ++ apfs_assert_in_transaction(sb, &raw->btn_o); ++ ++ raw->btn_o.o_oid = cpu_to_le64(node->object.oid); ++ ++ /* The node may no longer be a root, so update the object type */ ++ tflags = le32_to_cpu(raw->btn_o.o_type) & APFS_OBJECT_TYPE_FLAGS_MASK; ++ type = (node->flags & APFS_BTNODE_ROOT) ? APFS_OBJECT_TYPE_BTREE : ++ APFS_OBJECT_TYPE_BTREE_NODE; ++ raw->btn_o.o_type = cpu_to_le32(type | tflags); ++ raw->btn_o.o_subtype = cpu_to_le32(node->tree_type); ++ ++ raw->btn_flags = cpu_to_le16(node->flags); ++ raw->btn_nkeys = cpu_to_le32(node->records); ++ ++ toc_off = sizeof(*raw) + le16_to_cpu(raw->btn_table_space.off); ++ raw->btn_table_space.len = cpu_to_le16(node->key - toc_off); ++ raw->btn_free_space.off = cpu_to_le16(node->free - node->key); ++ raw->btn_free_space.len = cpu_to_le16(node->val - node->free); ++ ++ /* Reset the lists on zero length, a defragmentation is taking place */ ++ free_head = &raw->btn_key_free_list; ++ free_head->len = cpu_to_le16(node->key_free_list_len); ++ if (!free_head->len) ++ free_head->off = cpu_to_le16(APFS_BTOFF_INVALID); ++ free_head = &raw->btn_val_free_list; ++ free_head->len = cpu_to_le16(node->val_free_list_len); ++ if (!free_head->len) ++ free_head->off = cpu_to_le16(APFS_BTOFF_INVALID); ++ ++ if (bh) { ++ ASSERT(buffer_trans(bh)); ++ ASSERT(buffer_csum(bh)); ++ } ++} ++ ++/** ++ * apfs_node_locate_key - Locate the key of a node record ++ * @node: node to be searched ++ * @index: number of the entry to locate ++ * @off: on return will hold the offset in the block ++ * ++ * Returns the length of the key, or 0 in case of failure. The function checks ++ * that this length fits within the block; callers must use it to make sure ++ * they never operate outside its bounds. ++ */ ++int apfs_node_locate_key(struct apfs_node *node, int index, int *off) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *raw; ++ int len; ++ ++ if (index >= node->records) { ++ apfs_err(sb, "index out of bounds (%d of %d)", index, node->records); ++ return 0; ++ } ++ ++ raw = (struct apfs_btree_node_phys *)node->object.data; ++ if (apfs_node_has_fixed_kv_size(node)) { ++ struct apfs_kvoff *entry; ++ ++ entry = (struct apfs_kvoff *)raw->btn_data + index; ++ ++ /* TODO: it would be cleaner to read this stuff from disk */ ++ if (node->tree_type == APFS_OBJECT_TYPE_OMAP_SNAPSHOT) ++ len = 8; ++ else ++ len = 16; ++ ++ /* Translate offset in key area to offset in block */ ++ *off = node->key + le16_to_cpu(entry->k); ++ } else { ++ /* These node types have variable length keys and values */ ++ struct apfs_kvloc *entry; ++ ++ entry = (struct apfs_kvloc *)raw->btn_data + index; ++ len = le16_to_cpu(entry->k.len); ++ /* Translate offset in key area to offset in block */ ++ *off = node->key + le16_to_cpu(entry->k.off); ++ } ++ ++ if (*off + len > sb->s_blocksize) { ++ apfs_err(sb, "key out of bounds (%d-%d)", *off, len); ++ return 0; ++ } ++ return len; ++} ++ ++/** ++ * apfs_node_locate_value - Locate the value of a node record ++ * @node: node to be searched ++ * @index: number of the entry to locate ++ * @off: on return will hold the offset in the block ++ * ++ * Returns the length of the value, which may be 0 in case of corruption or if ++ * the record is a ghost. The function checks that this length fits within the ++ * block; callers must use it to make sure they never operate outside its ++ * bounds. ++ */ ++static int apfs_node_locate_value(struct apfs_node *node, int index, int *off) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *raw; ++ int len; ++ ++ if (index >= node->records) { ++ apfs_err(sb, "index out of bounds (%d of %d)", index, node->records); ++ return 0; ++ } ++ ++ raw = (struct apfs_btree_node_phys *)node->object.data; ++ if (apfs_node_has_fixed_kv_size(node)) { ++ /* These node types have fixed length keys and values */ ++ struct apfs_kvoff *entry; ++ ++ entry = (struct apfs_kvoff *)raw->btn_data + index; ++ if (node->tree_type == APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE) { ++ /* A free-space queue record may have no value */ ++ if (le16_to_cpu(entry->v) == APFS_BTOFF_INVALID) { ++ *off = 0; ++ return 0; ++ } ++ len = 8; ++ } else { ++ /* This is an omap or omap snapshots node */ ++ len = apfs_node_is_leaf(node) ? 16 : 8; ++ } ++ /* ++ * Value offsets are counted backwards from the end of the ++ * block, or from the beginning of the footer when it exists ++ */ ++ if (apfs_node_is_root(node)) /* has footer */ ++ *off = sb->s_blocksize - sizeof(struct apfs_btree_info) ++ - le16_to_cpu(entry->v); ++ else ++ *off = sb->s_blocksize - le16_to_cpu(entry->v); ++ } else { ++ /* These node types have variable length keys and values */ ++ struct apfs_kvloc *entry; ++ ++ entry = (struct apfs_kvloc *)raw->btn_data + index; ++ len = le16_to_cpu(entry->v.len); ++ /* ++ * Value offsets are counted backwards from the end of the ++ * block, or from the beginning of the footer when it exists ++ */ ++ if (apfs_node_is_root(node)) /* has footer */ ++ *off = sb->s_blocksize - sizeof(struct apfs_btree_info) ++ - le16_to_cpu(entry->v.off); ++ else ++ *off = sb->s_blocksize - le16_to_cpu(entry->v.off); ++ } ++ ++ if (*off < 0 || *off + len > sb->s_blocksize) { ++ apfs_err(sb, "value out of bounds (%d-%d)", *off, len); ++ return 0; ++ } ++ return len; ++} ++ ++/** ++ * apfs_create_toc_entry - Create the table-of-contents entry for a record ++ * @query: query pointing to the record ++ * ++ * Creates a toc entry for the record at index @query->index and increases ++ * @node->records. The caller must ensure enough space in the table. ++ */ ++static void apfs_create_toc_entry(struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *raw = (void *)node->object.data; ++ int value_end; ++ int recs = node->records; ++ int index = query->index; ++ ++ value_end = sb->s_blocksize; ++ if (apfs_node_is_root(node)) ++ value_end -= sizeof(struct apfs_btree_info); ++ ++ if (apfs_node_has_fixed_kv_size(node)) { ++ struct apfs_kvoff *kvoff; ++ ++ kvoff = (struct apfs_kvoff *)raw->btn_data + query->index; ++ memmove(kvoff + 1, kvoff, (recs - index) * sizeof(*kvoff)); ++ ++ if (!query->len) /* Ghost record */ ++ kvoff->v = cpu_to_le16(APFS_BTOFF_INVALID); ++ else ++ kvoff->v = cpu_to_le16(value_end - query->off); ++ kvoff->k = cpu_to_le16(query->key_off - node->key); ++ } else { ++ struct apfs_kvloc *kvloc; ++ ++ kvloc = (struct apfs_kvloc *)raw->btn_data + query->index; ++ memmove(kvloc + 1, kvloc, (recs - index) * sizeof(*kvloc)); ++ ++ kvloc->v.off = cpu_to_le16(value_end - query->off); ++ kvloc->v.len = cpu_to_le16(query->len); ++ kvloc->k.off = cpu_to_le16(query->key_off - node->key); ++ kvloc->k.len = cpu_to_le16(query->key_len); ++ } ++ node->records++; ++} ++ ++/** ++ * apfs_key_from_query - Read the current key from a query structure ++ * @query: the query, with @query->key_off and @query->key_len already set ++ * @key: return parameter for the key ++ * ++ * Reads the key into @key and performs some basic sanity checks as a ++ * protection against crafted filesystems. Returns 0 on success or a ++ * negative error code otherwise. ++ */ ++static int apfs_key_from_query(struct apfs_query *query, struct apfs_key *key) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ void *raw_key = (void *)(raw + query->key_off); ++ bool hashed; ++ int err = 0; ++ ++ switch (query->flags & APFS_QUERY_TREE_MASK) { ++ case APFS_QUERY_CAT: ++ hashed = apfs_is_normalization_insensitive(sb); ++ err = apfs_read_cat_key(raw_key, query->key_len, key, hashed); ++ break; ++ case APFS_QUERY_OMAP: ++ err = apfs_read_omap_key(raw_key, query->key_len, key); ++ break; ++ case APFS_QUERY_FREE_QUEUE: ++ err = apfs_read_free_queue_key(raw_key, query->key_len, key); ++ break; ++ case APFS_QUERY_EXTENTREF: ++ err = apfs_read_extentref_key(raw_key, query->key_len, key); ++ break; ++ case APFS_QUERY_FEXT: ++ err = apfs_read_fext_key(raw_key, query->key_len, key); ++ break; ++ case APFS_QUERY_SNAP_META: ++ err = apfs_read_snap_meta_key(raw_key, query->key_len, key); ++ break; ++ case APFS_QUERY_OMAP_SNAP: ++ err = apfs_read_omap_snap_key(raw_key, query->key_len, key); ++ break; ++ default: ++ apfs_alert(sb, "new query type must implement key reads (%d)", query->flags & APFS_QUERY_TREE_MASK); ++ err = -EOPNOTSUPP; ++ break; ++ } ++ if (err) ++ apfs_err(sb, "bad node key in block 0x%llx", query->node->object.block_nr); ++ ++ /* A multiple query must ignore some of these fields */ ++ if (query->flags & APFS_QUERY_ANY_NAME) ++ key->name = NULL; ++ if (query->flags & APFS_QUERY_ANY_NUMBER) ++ key->number = 0; ++ ++ return err; ++} ++ ++/** ++ * apfs_node_prev - Find the previous record in the current node ++ * @sb: filesystem superblock ++ * @query: query in execution ++ * ++ * Returns 0 on success, -EAGAIN if the previous record is in another node, ++ * -ENODATA if no more records exist, or another negative error code in case ++ * of failure. ++ * ++ * The meaning of "next" and "previous" is reverted here, because regular ++ * multiple always start with the final record, and then they go backwards. ++ * TODO: consider renaming this for clarity. ++ */ ++static int apfs_node_prev(struct super_block *sb, struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ ++ if (query->index + 1 == node->records) { ++ /* The next record may be in another node */ ++ return -EAGAIN; ++ } ++ ++query->index; ++ ++ query->key_len = apfs_node_locate_key(node, query->index, &query->key_off); ++ if (query->key_len == 0) { ++ apfs_err(sb, "bad key for index %d", query->index); ++ return -EFSCORRUPTED; ++ } ++ query->len = apfs_node_locate_value(node, query->index, &query->off); ++ if (query->len == 0) { ++ apfs_err(sb, "bad value for index %d", query->index); ++ return -EFSCORRUPTED; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_node_next - Find the next matching record in the current node ++ * @sb: filesystem superblock ++ * @query: multiple query in execution ++ * ++ * Returns 0 on success, -EAGAIN if the next record is in another node, ++ * -ENODATA if no more matching records exist, or another negative error ++ * code in case of failure. ++ */ ++static int apfs_node_next(struct super_block *sb, struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ struct apfs_key curr_key; ++ int cmp, err; ++ ++ if (query->flags & APFS_QUERY_DONE) ++ /* Nothing left to search; the query failed */ ++ return -ENODATA; ++ ++ if (!query->index) /* The next record may be in another node */ ++ return -EAGAIN; ++ --query->index; ++ ++ query->key_len = apfs_node_locate_key(node, query->index, ++ &query->key_off); ++ err = apfs_key_from_query(query, &curr_key); ++ if (err) { ++ apfs_err(sb, "bad key for index %d", query->index); ++ return err; ++ } ++ ++ cmp = apfs_keycmp(&curr_key, &query->key); ++ ++ if (cmp > 0) { ++ apfs_err(sb, "records are out of order"); ++ return -EFSCORRUPTED; ++ } ++ ++ if (cmp != 0 && apfs_node_is_leaf(node) && ++ query->flags & APFS_QUERY_EXACT) ++ return -ENODATA; ++ ++ query->len = apfs_node_locate_value(node, query->index, &query->off); ++ if (query->len == 0) { ++ apfs_err(sb, "bad value for index %d", query->index); ++ return -EFSCORRUPTED; ++ } ++ ++ if (cmp != 0) { ++ /* ++ * This is the last entry that can be relevant in this node. ++ * Keep searching the children, but don't return to this level. ++ */ ++ query->flags |= APFS_QUERY_DONE; ++ } ++ ++ return 0; ++} ++ ++/** ++ * apfs_node_query - Execute a query on a single node ++ * @sb: filesystem superblock ++ * @query: the query to execute ++ * ++ * The search will start at index @query->index, looking for the key that comes ++ * right before @query->key, according to the order given by apfs_keycmp(). ++ * ++ * The @query->index will be updated to the last index checked. This is ++ * important when searching for multiple entries, since the query may need ++ * to remember where it was on this level. If we are done with this node, the ++ * query will be flagged as APFS_QUERY_DONE, and the search will end in failure ++ * as soon as we return to this level. The function may also return -EAGAIN, ++ * to signal that the search should go on in a different branch. ++ * ++ * On success returns 0; the offset of the value within the block will be saved ++ * in @query->off, and its length in @query->len. The function checks that this ++ * length fits within the block; callers must use the returned value to make ++ * sure they never operate outside its bounds. ++ * ++ * -ENODATA will be returned if no appropriate entry was found, -EFSCORRUPTED ++ * in case of corruption. ++ */ ++int apfs_node_query(struct super_block *sb, struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ int left, right; ++ int cmp; ++ int err; ++ ++ if (query->flags & APFS_QUERY_PREV) ++ return apfs_node_prev(sb, query); ++ if (query->flags & APFS_QUERY_NEXT) ++ return apfs_node_next(sb, query); ++ ++ /* Search by bisection */ ++ cmp = 1; ++ left = 0; ++ do { ++ struct apfs_key curr_key; ++ ++ if (cmp > 0) { ++ right = query->index - 1; ++ if (right < left) { ++ query->index = -1; ++ return -ENODATA; ++ } ++ query->index = (left + right) / 2; ++ } else { ++ left = query->index; ++ query->index = DIV_ROUND_UP(left + right, 2); ++ } ++ ++ query->key_len = apfs_node_locate_key(node, query->index, ++ &query->key_off); ++ err = apfs_key_from_query(query, &curr_key); ++ if (err) { ++ apfs_err(sb, "bad key for index %d", query->index); ++ return err; ++ } ++ ++ cmp = apfs_keycmp(&curr_key, &query->key); ++ if (cmp == 0 && !(query->flags & APFS_QUERY_MULTIPLE)) ++ break; ++ } while (left != right); ++ ++ if (cmp > 0) { ++ query->index = -1; ++ return -ENODATA; ++ } ++ ++ if (cmp != 0 && apfs_node_is_leaf(query->node) && ++ query->flags & APFS_QUERY_EXACT) ++ return -ENODATA; ++ ++ if (query->flags & APFS_QUERY_MULTIPLE) { ++ if (cmp != 0) /* Last relevant entry in level */ ++ query->flags |= APFS_QUERY_DONE; ++ query->flags |= APFS_QUERY_NEXT; ++ } ++ ++ query->len = apfs_node_locate_value(node, query->index, &query->off); ++ return 0; ++} ++ ++/** ++ * apfs_node_query_first - Find the first record in a node ++ * @query: on return this query points to the record ++ */ ++void apfs_node_query_first(struct apfs_query *query) ++{ ++ struct apfs_node *node = query->node; ++ ++ query->index = 0; ++ query->key_len = apfs_node_locate_key(node, query->index, &query->key_off); ++ query->len = apfs_node_locate_value(node, query->index, &query->off); ++} ++ ++/** ++ * apfs_omap_map_from_query - Read the mapping found by a successful omap query ++ * @query: the query that found the record ++ * @map: Return parameter. The mapping found. ++ * ++ * Returns -EOPNOTSUPP if the object doesn't fit in one block, and -EFSCORRUPTED ++ * if the filesystem appears to be malicious. Otherwise, reads the mapping info ++ * in the omap record into @map and returns 0. ++ */ ++int apfs_omap_map_from_query(struct apfs_query *query, struct apfs_omap_map *map) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_omap_key *key = NULL; ++ struct apfs_omap_val *val = NULL; ++ char *raw = query->node->object.data; ++ ++ if (query->len != sizeof(*val) || query->key_len != sizeof(*key)) { ++ apfs_err(sb, "bad length of key (%d) or value (%d)", query->key_len, query->len); ++ return -EFSCORRUPTED; ++ } ++ key = (struct apfs_omap_key *)(raw + query->key_off); ++ val = (struct apfs_omap_val *)(raw + query->off); ++ ++ /* TODO: support objects with multiple blocks */ ++ if (le32_to_cpu(val->ov_size) != sb->s_blocksize) { ++ apfs_err(sb, "object size doesn't match block size"); ++ return -EOPNOTSUPP; ++ } ++ ++ map->xid = le64_to_cpu(key->ok_xid); ++ map->bno = le64_to_cpu(val->ov_paddr); ++ map->flags = le32_to_cpu(val->ov_flags); ++ return 0; ++} ++ ++/** ++ * apfs_btree_inc_height - Increase the height of a b-tree ++ * @query: query pointing to the root node ++ * ++ * On success returns 0, and @query is left pointing to the same record. ++ * Returns a negative error code in case of failure. ++ */ ++static int apfs_btree_inc_height(struct apfs_query *query) ++{ ++ struct apfs_query *root_query; ++ struct apfs_node *root = query->node; ++ struct apfs_node *new_node; ++ struct super_block *sb = root->object.sb; ++ struct apfs_btree_node_phys *root_raw; ++ struct apfs_btree_node_phys *new_raw; ++ struct apfs_btree_info *info; ++ __le64 *raw_oid; ++ u32 storage = apfs_query_storage(query); ++ ++ root_raw = (void *)root->object.data; ++ apfs_assert_in_transaction(sb, &root_raw->btn_o); ++ ++ if (query->parent || query->depth) { ++ apfs_err(sb, "invalid root query"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* Create a new child node */ ++ new_node = apfs_create_node(sb, storage); ++ if (IS_ERR(new_node)) { ++ apfs_err(sb, "node creation failed"); ++ return PTR_ERR(new_node); ++ } ++ new_node->flags = root->flags & ~APFS_BTNODE_ROOT; ++ new_node->tree_type = root->tree_type; ++ ++ /* Move all records into the child node; get rid of the info footer */ ++ new_node->records = root->records; ++ new_node->key = root->key; ++ new_node->free = root->free; ++ new_node->val = root->val + sizeof(*info); ++ new_node->key_free_list_len = root->key_free_list_len; ++ new_node->val_free_list_len = root->val_free_list_len; ++ new_raw = (void *)new_node->object.data; ++ /* Don't copy the object header, already set by apfs_create_node() */ ++ memcpy((void *)new_raw + sizeof(new_raw->btn_o), ++ (void *)root_raw + sizeof(root_raw->btn_o), ++ root->free - sizeof(new_raw->btn_o)); ++ memcpy((void *)new_raw + new_node->val, ++ (void *)root_raw + root->val, ++ sb->s_blocksize - new_node->val); ++ query->off += sizeof(*info); ++ apfs_update_node(new_node); ++ ++ /* Add a new level to the query chain */ ++ root_query = query->parent = apfs_alloc_query(root, NULL /* parent */); ++ if (!query->parent) { ++ apfs_node_free(new_node); ++ return -ENOMEM; ++ } ++ root_query->key = query->key; ++ root_query->flags = query->flags; ++ query->node = new_node; ++ query->depth = 1; ++ ++ /* Now assemble the new root with only the first key */ ++ root_query->key_len = apfs_node_locate_key(root, 0 /* index */, ++ &root_query->key_off); ++ if (!root_query->key_len) { ++ apfs_err(sb, "bad key for index %d", 0); ++ return -EFSCORRUPTED; ++ } ++ root->key = sizeof(*root_raw) + ++ apfs_node_min_table_size(sb, root->tree_type, root->flags & ~APFS_BTNODE_LEAF); ++ memmove((void *)root_raw + root->key, ++ (void *)root_raw + root_query->key_off, root_query->key_len); ++ root_query->key_off = root->key; ++ root->free = root->key + root_query->key_len; ++ ++ /* The new root is a nonleaf node; the record value is the child id */ ++ root->flags &= ~APFS_BTNODE_LEAF; ++ root->val = sb->s_blocksize - sizeof(*info) - sizeof(*raw_oid); ++ raw_oid = (void *)root_raw + root->val; ++ *raw_oid = cpu_to_le64(new_node->object.oid); ++ root_query->off = root->val; ++ root_query->len = sizeof(*raw_oid); ++ ++ /* With the key and value in place, set the table-of-contents */ ++ root->records = 0; ++ root_query->index = 0; ++ apfs_create_toc_entry(root_query); ++ ++ /* There is no internal fragmentation */ ++ root->key_free_list_len = 0; ++ root->val_free_list_len = 0; ++ ++ /* Finally, update the node count in the info footer */ ++ apfs_btree_change_node_count(root_query, 1 /* change */); ++ ++ le16_add_cpu(&root_raw->btn_level, 1); /* TODO: move to update_node() */ ++ apfs_update_node(root); ++ return 0; ++} ++ ++/** ++ * apfs_copy_record_range - Copy a range of records to an empty node ++ * @dest_node: destination node ++ * @src_node: source node ++ * @start: index of first record in range ++ * @end: index of first record after the range ++ * ++ * Doesn't modify the info footer of root nodes. Returns 0 on success or a ++ * negative error code in case of failure. ++ */ ++static int apfs_copy_record_range(struct apfs_node *dest_node, ++ struct apfs_node *src_node, ++ int start, int end) ++{ ++ struct super_block *sb = dest_node->object.sb; ++ struct apfs_btree_node_phys *dest_raw; ++ struct apfs_btree_node_phys *src_raw; ++ struct apfs_query *query = NULL; ++ int toc_size, toc_entry_size; ++ int err; ++ int i; ++ ++ dest_raw = (void *)dest_node->object.data; ++ src_raw = (void *)src_node->object.data; ++ ++ ASSERT(!dest_node->records); ++ apfs_assert_in_transaction(sb, &dest_raw->btn_o); ++ ++ /* Resize the table of contents so that all the records fit */ ++ if (apfs_node_has_fixed_kv_size(src_node)) ++ toc_entry_size = sizeof(struct apfs_kvoff); ++ else ++ toc_entry_size = sizeof(struct apfs_kvloc); ++ toc_size = apfs_node_min_table_size(sb, src_node->tree_type, src_node->flags); ++ if (toc_size < toc_entry_size * (end - start)) ++ toc_size = toc_entry_size * round_up(end - start, APFS_BTREE_TOC_ENTRY_INCREMENT); ++ dest_node->key = sizeof(*dest_raw) + toc_size; ++ dest_node->free = dest_node->key; ++ dest_node->val = sb->s_blocksize; ++ if (apfs_node_is_root(dest_node)) ++ dest_node->val -= sizeof(struct apfs_btree_info); ++ ++ /* We'll use a temporary query structure to move the records around */ ++ query = apfs_alloc_query(dest_node, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ err = -EFSCORRUPTED; ++ for (i = start; i < end; ++i) { ++ int len, off; ++ ++ len = apfs_node_locate_key(src_node, i, &off); ++ if (dest_node->free + len > sb->s_blocksize) { ++ apfs_err(sb, "key of length %d doesn't fit", len); ++ goto fail; ++ } ++ memcpy((char *)dest_raw + dest_node->free, ++ (char *)src_raw + off, len); ++ query->key_off = dest_node->free; ++ query->key_len = len; ++ dest_node->free += len; ++ ++ len = apfs_node_locate_value(src_node, i, &off); ++ dest_node->val -= len; ++ if (dest_node->val < 0) { ++ apfs_err(sb, "value of length %d doesn't fit", len); ++ goto fail; ++ } ++ memcpy((char *)dest_raw + dest_node->val, ++ (char *)src_raw + off, len); ++ query->off = dest_node->val; ++ query->len = len; ++ ++ query->index = i - start; ++ apfs_create_toc_entry(query); ++ } ++ err = 0; ++ ++fail: ++ apfs_free_query(query); ++ return err; ++} ++ ++/** ++ * apfs_attach_child - Attach a new node to its parent ++ * @query: query pointing to the previous record in the parent ++ * @child: the new child node to attach ++ * ++ * Returns 0 on success or a negative error code in case of failure (which may ++ * be -EAGAIN if a node split has happened and the caller must refresh and ++ * retry). ++ */ ++static int apfs_attach_child(struct apfs_query *query, struct apfs_node *child) ++{ ++ struct apfs_object *object = &child->object; ++ struct apfs_btree_node_phys *raw = (void *)object->data; ++ int key_len, key_off; ++ __le64 raw_oid = cpu_to_le64(object->oid); ++ ++ key_len = apfs_node_locate_key(child, 0, &key_off); ++ if (!key_len) { ++ /* This should never happen: @child was made by us */ ++ apfs_alert(object->sb, "bad key for index %d", 0); ++ return -EFSCORRUPTED; ++ } ++ ++ return __apfs_btree_insert(query, (void *)raw + key_off, key_len, &raw_oid, sizeof(raw_oid)); ++} ++ ++/** ++ * apfs_node_temp_dup - Make an in-memory duplicate of a node ++ * @original: node to duplicate ++ * @duplicate: on success, the duplicate node ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_node_temp_dup(const struct apfs_node *original, struct apfs_node **duplicate) ++{ ++ struct super_block *sb = original->object.sb; ++ struct apfs_node *dup = NULL; ++ char *buffer = NULL; ++ ++ dup = kmalloc(sizeof(*dup), GFP_KERNEL); ++ if (!dup) ++ return -ENOMEM; ++ *dup = *original; ++ dup->object.o_bh = NULL; ++ dup->object.data = NULL; ++ dup->object.ephemeral = false; ++ ++ buffer = kmalloc(sb->s_blocksize, GFP_KERNEL); ++ if (!buffer) { ++ kfree(dup); ++ return -ENOMEM; ++ } ++ memcpy(buffer, original->object.data, sb->s_blocksize); ++ dup->object.data = buffer; ++ ++ *duplicate = dup; ++ return 0; ++} ++ ++/** ++ * apfs_node_split - Split a b-tree node in two ++ * @query: query pointing to the node ++ * ++ * On success returns 0, and @query is left pointing to the same record on the ++ * tip; to simplify the implementation, @query->parent is set to NULL. Returns ++ * a negative error code in case of failure, which may be -EAGAIN if a node ++ * split has happened and the caller must refresh and retry. ++ */ ++int apfs_node_split(struct apfs_query *query) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_node *old_node = NULL, *new_node = NULL, *tmp_node = NULL; ++ struct apfs_btree_node_phys *new_raw = NULL, *old_raw = NULL; ++ u32 storage = apfs_query_storage(query); ++ int record_count, new_rec_count, old_rec_count; ++ int err; ++ ++ apfs_assert_query_is_valid(query); ++ ++ if (apfs_node_is_root(query->node)) { ++ err = apfs_btree_inc_height(query); ++ if (err) { ++ apfs_err(sb, "failed to increase tree height"); ++ return err; ++ } ++ } else if (!query->parent) { ++ apfs_err(sb, "nonroot node with no parent"); ++ return -EFSCORRUPTED; ++ } ++ old_node = query->node; ++ ++ old_raw = (void *)old_node->object.data; ++ apfs_assert_in_transaction(sb, &old_raw->btn_o); ++ ++ /* ++ * To defragment the original node, we put all records in a temporary ++ * in-memory node before dealing them out. ++ */ ++ err = apfs_node_temp_dup(old_node, &tmp_node); ++ if (err) ++ return err; ++ ++ record_count = old_node->records; ++ if (record_count == 1) { ++ apfs_alert(sb, "splitting node with a single record"); ++ err = -EFSCORRUPTED; ++ goto out; ++ } ++ new_rec_count = record_count / 2; ++ old_rec_count = record_count - new_rec_count; ++ ++ /* ++ * The second half of the records go into a new node. This is done ++ * before the first half to avoid committing to any actual changes ++ * until we know for sure that no ancestor splits are expected. ++ */ ++ ++ new_node = apfs_create_node(sb, storage); ++ if (IS_ERR(new_node)) { ++ apfs_err(sb, "node creation failed"); ++ err = PTR_ERR(new_node); ++ new_node = NULL; ++ goto out; ++ } ++ new_node->tree_type = old_node->tree_type; ++ new_node->flags = old_node->flags; ++ new_node->records = 0; ++ new_node->key_free_list_len = 0; ++ new_node->val_free_list_len = 0; ++ err = apfs_copy_record_range(new_node, tmp_node, old_rec_count, record_count); ++ if (err) { ++ apfs_err(sb, "record copy failed"); ++ goto out; ++ } ++ new_raw = (void *)new_node->object.data; ++ apfs_assert_in_transaction(sb, &new_raw->btn_o); ++ new_raw->btn_level = old_raw->btn_level; ++ apfs_update_node(new_node); ++ ++ err = apfs_attach_child(query->parent, new_node); ++ if (err) { ++ if (err != -EAGAIN) { ++ apfs_err(sb, "child attachment failed"); ++ goto out; ++ } ++ err = apfs_delete_node(new_node, query->flags & APFS_QUERY_TREE_MASK); ++ if (err) { ++ apfs_err(sb, "node cleanup failed for query retry"); ++ goto out; ++ } ++ err = -EAGAIN; ++ goto out; ++ } ++ apfs_assert_query_is_valid(query->parent); ++ apfs_btree_change_node_count(query->parent, 1 /* change */); ++ ++ /* ++ * No more risk of ancestor splits, now actual changes can be made. The ++ * first half of the records go into the original node. ++ */ ++ ++ old_node->records = 0; ++ old_node->key_free_list_len = 0; ++ old_node->val_free_list_len = 0; ++ err = apfs_copy_record_range(old_node, tmp_node, 0, old_rec_count); ++ if (err) { ++ apfs_err(sb, "record copy failed"); ++ goto out; ++ } ++ apfs_update_node(old_node); ++ ++ /* Point the query back to the original record */ ++ if (query->index >= old_rec_count) { ++ /* The record got moved to the new node */ ++ apfs_node_free(query->node); ++ query->node = new_node; ++ new_node = NULL; ++ query->index -= old_rec_count; ++ } ++ ++ /* ++ * This could be avoided in most cases, and queries could get refreshed ++ * only when really orphaned. But refreshing queries is probably not a ++ * bottleneck, and trying to be clever with this stuff has caused me a ++ * lot of trouble already. ++ */ ++ apfs_free_query(query->parent); ++ query->parent = NULL; /* The caller only gets the leaf */ ++ ++out: ++ apfs_node_free(new_node); ++ apfs_node_free(tmp_node); ++ return err; ++} ++ ++/* TODO: the following 4 functions could be reused elsewhere */ ++ ++/** ++ * apfs_off_to_val_off - Translate offset in node to offset in value area ++ * @node: the node ++ * @off: offset in the node ++ */ ++static u16 apfs_off_to_val_off(struct apfs_node *node, u16 off) ++{ ++ struct super_block *sb = node->object.sb; ++ u16 val_end; ++ ++ val_end = sb->s_blocksize; ++ if (apfs_node_is_root(node)) /* has footer */ ++ val_end -= sizeof(struct apfs_btree_info); ++ return val_end - off; ++} ++ ++/** ++ * apfs_val_off_to_off - Translate offset in value area to offset in node ++ * @node: the node ++ * @off: offset in the value area ++ */ ++static u16 apfs_val_off_to_off(struct apfs_node *node, u16 off) ++{ ++ return apfs_off_to_val_off(node, off); ++} ++ ++/** ++ * apfs_off_to_key_off - Translate offset in node to offset in key area ++ * @node: the node ++ * @off: offset in the node ++ */ ++static u16 apfs_off_to_key_off(struct apfs_node *node, u16 off) ++{ ++ return off - node->key; ++} ++ ++/** ++ * apfs_key_off_to_off - Translate offset in key area to offset in node ++ * @node: the node ++ * @off: offset in the key area ++ */ ++static u16 apfs_key_off_to_off(struct apfs_node *node, u16 off) ++{ ++ return off + node->key; ++} ++ ++/* The type of the previous four functions, used for node offset calculations */ ++typedef u16 (*offcalc)(struct apfs_node *, u16); ++ ++/** ++ * apfs_node_free_list_add - Add a free node segment to the proper free list ++ * @node: node for the segment ++ * @off: offset of the segment to add ++ * @len: length of the segment to add ++ * ++ * The caller must ensure that the freed segment fits in the node. ++ */ ++static void apfs_node_free_list_add(struct apfs_node *node, u16 off, u16 len) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ struct apfs_nloc *head, *new; ++ offcalc off_to_rel; ++ ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++ if (off >= node->val) { /* Value area */ ++ off_to_rel = apfs_off_to_val_off; ++ head = &node_raw->btn_val_free_list; ++ node->val_free_list_len += len; ++ } else { /* Key area */ ++ off_to_rel = apfs_off_to_key_off; ++ head = &node_raw->btn_key_free_list; ++ node->key_free_list_len += len; ++ } ++ ++ /* Very small segments are leaked until defragmentation */ ++ if (len < sizeof(*new)) ++ return; ++ ++ /* The free list doesn't seem to be kept in any particular order */ ++ new = (void *)node_raw + off; ++ new->off = head->off; ++ new->len = cpu_to_le16(len); ++ head->off = cpu_to_le16(off_to_rel(node, off)); ++} ++ ++/** ++ * apfs_node_free_range - Free space from a node's key or value areas ++ * @node: the node ++ * @off: offset to free ++ * @len: length to free ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++void apfs_node_free_range(struct apfs_node *node, u16 off, u16 len) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *raw = (void *)node->object.data; ++ ++ apfs_assert_in_transaction(sb, &raw->btn_o); ++ ++ if (off == node->val) ++ node->val += len; ++ else if (off + len == node->free) ++ node->free -= len; ++ else ++ apfs_node_free_list_add(node, off, len); ++} ++ ++/** ++ * apfs_node_free_list_unlink - Unlink an entry from a node's free list ++ * @prev: previous entry ++ * @curr: entry to unlink ++ */ ++static void apfs_node_free_list_unlink(struct apfs_nloc *prev, struct apfs_nloc *curr) ++{ ++ prev->off = curr->off; ++} ++ ++/** ++ * apfs_node_free_list_alloc - Allocate a free segment from a free list ++ * @node: the node ++ * @len: length to allocate ++ * @value: true to allocate in the value area, false for the key area ++ * ++ * Returns the offset in the node on success, or a negative error code in case ++ * of failure, which may be -ENOSPC if the node seems full. ++ */ ++static int apfs_node_free_list_alloc(struct apfs_node *node, u16 len, bool value) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ struct apfs_nloc *head, *curr, *prev; ++ offcalc rel_to_off; ++ int *list_len; ++ int bound = sb->s_blocksize; ++ ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++ if (value) { /* Value area */ ++ rel_to_off = apfs_val_off_to_off; ++ head = &node_raw->btn_val_free_list; ++ list_len = &node->val_free_list_len; ++ } else { /* Key area */ ++ rel_to_off = apfs_key_off_to_off; ++ head = &node_raw->btn_key_free_list; ++ list_len = &node->key_free_list_len; ++ } ++ ++ if (*list_len < len) ++ return -ENOSPC; ++ ++ prev = head; ++ while (bound--) { ++ u16 curr_off = le16_to_cpu(prev->off); ++ u16 abs_off = rel_to_off(node, curr_off); ++ u16 curr_len; ++ ++ if (curr_off == APFS_BTOFF_INVALID) ++ return -ENOSPC; ++ if (abs_off + sizeof(*curr) > sb->s_blocksize) { ++ apfs_err(sb, "nloc out of bounds (%d-%d)", abs_off, (int)sizeof(*curr)); ++ return -EFSCORRUPTED; ++ } ++ curr = (void *)node_raw + abs_off; ++ ++ curr_len = le16_to_cpu(curr->len); ++ if (curr_len >= len) { ++ if (abs_off + curr_len > sb->s_blocksize) { ++ apfs_err(sb, "entry out of bounds (%d-%d)", abs_off, curr_len); ++ return -EFSCORRUPTED; ++ } ++ *list_len -= curr_len; ++ apfs_node_free_list_unlink(prev, curr); ++ apfs_node_free_list_add(node, abs_off + len, curr_len - len); ++ return abs_off; ++ } ++ ++ prev = curr; ++ } ++ ++ /* Don't loop forever if the free list is corrupted and doesn't end */ ++ apfs_err(sb, "free list never ends"); ++ return -EFSCORRUPTED; ++} ++ ++/** ++ * apfs_node_alloc_key - Allocated free space for a new key ++ * @node: the node to search ++ * @len: wanted key length ++ * ++ * Returns the offset in the node on success, or a negative error code in case ++ * of failure, which may be -ENOSPC if the node seems full. ++ */ ++static int apfs_node_alloc_key(struct apfs_node *node, u16 len) ++{ ++ int off; ++ ++ if (node->free + len <= node->val) { ++ off = node->free; ++ node->free += len; ++ return off; ++ } ++ return apfs_node_free_list_alloc(node, len, false /* value */); ++} ++ ++/** ++ * apfs_node_alloc_val - Allocated free space for a new value ++ * @node: the node to search ++ * @len: wanted value length ++ * ++ * Returns the offset in the node on success, or a negative error code in case ++ * of failure, which may be -ENOSPC if the node seems full. ++ */ ++static int apfs_node_alloc_val(struct apfs_node *node, u16 len) ++{ ++ int off; ++ ++ if (node->free + len <= node->val) { ++ off = node->val - len; ++ node->val -= len; ++ return off; ++ } ++ return apfs_node_free_list_alloc(node, len, true /* value */); ++} ++ ++/** ++ * apfs_node_total_room - Total free space in a node ++ * @node: the node ++ */ ++static int apfs_node_total_room(struct apfs_node *node) ++{ ++ return node->val - node->free + node->key_free_list_len + node->val_free_list_len; ++} ++ ++/** ++ * apfs_node_has_room - Check if a node has room for insertion or replacement ++ * @node: node to check ++ * @length: length of the needed space (may be negative on replace) ++ * @replace: are we replacing a record? ++ */ ++bool apfs_node_has_room(struct apfs_node *node, int length, bool replace) ++{ ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ int toc_entry_size, needed_room; ++ ++ if (apfs_node_has_fixed_kv_size(node)) ++ toc_entry_size = sizeof(struct apfs_kvoff); ++ else ++ toc_entry_size = sizeof(struct apfs_kvloc); ++ ++ needed_room = length; ++ if (!replace) { ++ if (sizeof(*node_raw) + (node->records + 1) * toc_entry_size > node->key) ++ needed_room += APFS_BTREE_TOC_ENTRY_INCREMENT * toc_entry_size; ++ } ++ ++ return apfs_node_total_room(node) >= needed_room; ++} ++ ++/** ++ * apfs_defragment_node - Make all free space in a node contiguous ++ * @node: node to defragment ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_defragment_node(struct apfs_node *node) ++{ ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ struct apfs_node *tmp_node = NULL; ++ int record_count, err; ++ ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++ /* Put all records in a temporary in-memory node and deal them out */ ++ err = apfs_node_temp_dup(node, &tmp_node); ++ if (err) ++ return err; ++ record_count = node->records; ++ node->records = 0; ++ node->key_free_list_len = 0; ++ node->val_free_list_len = 0; ++ err = apfs_copy_record_range(node, tmp_node, 0, record_count); ++ if (err) { ++ apfs_err(sb, "record copy failed"); ++ goto fail; ++ } ++ apfs_update_node(node); ++fail: ++ apfs_node_free(tmp_node); ++ return err; ++} ++ ++/** ++ * apfs_node_update_toc_entry - Update a table of contents entry in place ++ * @query: query pointing to the toc entry ++ * ++ * The toc entry gets updated with the length and offset for the key/value ++ * provided by @query. Don't call this function for nodes with fixed length ++ * key/values, those never need to update their toc entries. ++ */ ++static void apfs_node_update_toc_entry(struct apfs_query *query) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_node *node = NULL; ++ struct apfs_btree_node_phys *node_raw = NULL; ++ struct apfs_kvloc *kvloc = NULL; ++ int value_end; ++ ++ node = query->node; ++ ASSERT(!apfs_node_has_fixed_kv_size(node)); ++ sb = node->object.sb; ++ node_raw = (void *)node->object.data; ++ ++ value_end = sb->s_blocksize; ++ if (apfs_node_is_root(node)) ++ value_end -= sizeof(struct apfs_btree_info); ++ ++ kvloc = (struct apfs_kvloc *)node_raw->btn_data + query->index; ++ kvloc->v.off = cpu_to_le16(value_end - query->off); ++ kvloc->v.len = cpu_to_le16(query->len); ++ kvloc->k.off = cpu_to_le16(query->key_off - node->key); ++ kvloc->k.len = cpu_to_le16(query->key_len); ++} ++ ++/** ++ * apfs_node_replace - Replace a record in a node that has enough room ++ * @query: exact query that found the record ++ * @key: new on-disk record key (NULL if unchanged) ++ * @key_len: length of @key ++ * @val: new on-disk record value (NULL if unchanged) ++ * @val_len: length of @val ++ * ++ * Returns 0 on success, and @query is left pointing to the same record. Returns ++ * a negative error code in case of failure. ++ */ ++int apfs_node_replace(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ int key_off = 0, val_off = 0, err = 0; ++ bool defragged = false; ++ int qtree = query->flags & APFS_QUERY_TREE_MASK; ++ ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++ /* ++ * Free queues are weird because their tables of contents don't report ++ * record lengths, as if they were fixed, but some of the leaf values ++ * are actually "ghosts", that is, zero-length. Supporting replace of ++ * such records would require some changes, and so far I've had no need ++ * for it. ++ */ ++ (void)qtree; ++ ASSERT(!(qtree == APFS_QUERY_FREE_QUEUE && apfs_node_is_leaf(node))); ++ ++retry: ++ if (key) { ++ if (key_len <= query->key_len) { ++ u16 end = query->key_off + key_len; ++ u16 diff = query->key_len - key_len; ++ ++ apfs_node_free_range(node, end, diff); ++ key_off = query->key_off; ++ } else { ++ apfs_node_free_range(node, query->key_off, query->key_len); ++ key_off = apfs_node_alloc_key(node, key_len); ++ if (key_off < 0) { ++ if (key_off == -ENOSPC) ++ goto defrag; ++ return key_off; ++ } ++ } ++ } ++ ++ if (val) { ++ if (val_len <= query->len) { ++ u16 end = query->off + val_len; ++ u16 diff = query->len - val_len; ++ ++ apfs_node_free_range(node, end, diff); ++ val_off = query->off; ++ } else { ++ apfs_node_free_range(node, query->off, query->len); ++ val_off = apfs_node_alloc_val(node, val_len); ++ if (val_off < 0) { ++ if (val_off == -ENOSPC) ++ goto defrag; ++ return val_off; ++ } ++ } ++ } ++ ++ if (key) { ++ query->key_off = key_off; ++ query->key_len = key_len; ++ memcpy((void *)node_raw + key_off, key, key_len); ++ } ++ if (val) { ++ query->off = val_off; ++ query->len = val_len; ++ memcpy((void *)node_raw + val_off, val, val_len); ++ } ++ ++ /* If the key or value were resized, update the table of contents */ ++ if (!apfs_node_has_fixed_kv_size(node)) ++ apfs_node_update_toc_entry(query); ++ ++ apfs_update_node(node); ++ return 0; ++ ++defrag: ++ if (defragged) { ++ apfs_alert(sb, "no room in defragged node"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* Crush the replaced entry, so that defragmentation is complete */ ++ if (apfs_node_has_fixed_kv_size(node)) { ++ apfs_alert(sb, "failed to replace a fixed size record"); ++ return -EFSCORRUPTED; ++ } ++ if (key) ++ query->key_len = 0; ++ if (val) ++ query->len = 0; ++ apfs_node_update_toc_entry(query); ++ ++ err = apfs_defragment_node(node); ++ if (err) { ++ apfs_err(sb, "failed to defragment node"); ++ return err; ++ } ++ defragged = true; ++ ++ /* The record to replace probably moved around */ ++ query->len = apfs_node_locate_value(query->node, query->index, &query->off); ++ query->key_len = apfs_node_locate_key(query->node, query->index, &query->key_off); ++ goto retry; ++} ++ ++/** ++ * apfs_node_insert - Insert a new record in a node that has enough room ++ * @query: query run to search for the record ++ * @key: on-disk record key ++ * @key_len: length of @key ++ * @val: on-disk record value (NULL for ghost records) ++ * @val_len: length of @val (0 for ghost records) ++ * ++ * The new record is placed right after the one found by @query. On success, ++ * returns 0 and sets @query to the new record. In case of failure, returns a ++ * negative error code and leaves @query pointing to the same record. ++ */ ++int apfs_node_insert(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct apfs_node *node = query->node; ++ struct super_block *sb = node->object.sb; ++ struct apfs_btree_node_phys *node_raw = (void *)node->object.data; ++ int toc_entry_size; ++ int key_off, val_off, err; ++ bool defragged = false; ++ ++ apfs_assert_in_transaction(sb, &node_raw->btn_o); ++ ++retry: ++ if (apfs_node_has_fixed_kv_size(node)) ++ toc_entry_size = sizeof(struct apfs_kvoff); ++ else ++ toc_entry_size = sizeof(struct apfs_kvloc); ++ ++ /* Expand the table of contents if necessary */ ++ if (sizeof(*node_raw) + (node->records + 1) * toc_entry_size > node->key) { ++ int new_key_base = node->key; ++ int new_free_base = node->free; ++ int inc; ++ ++ inc = APFS_BTREE_TOC_ENTRY_INCREMENT * toc_entry_size; ++ ++ new_key_base += inc; ++ new_free_base += inc; ++ if (new_free_base > node->val) ++ goto defrag; ++ memmove((void *)node_raw + new_key_base, ++ (void *)node_raw + node->key, node->free - node->key); ++ ++ node->key = new_key_base; ++ node->free = new_free_base; ++ query->key_off += inc; ++ } ++ ++ key_off = apfs_node_alloc_key(node, key_len); ++ if (key_off < 0) { ++ if (key_off == -ENOSPC) ++ goto defrag; ++ return key_off; ++ } ++ ++ if (val) { ++ val_off = apfs_node_alloc_val(node, val_len); ++ if (val_off < 0) { ++ if (val_off == -ENOSPC) { ++ /* ++ * There is no need for an update of the on-disk ++ * node before the defrag, since only in-memory ++ * data should be used there... ++ */ ++ goto defrag; ++ } ++ return val_off; ++ } ++ } ++ ++ query->key_len = key_len; ++ query->key_off = key_off; ++ memcpy((void *)node_raw + key_off, key, key_len); ++ ++ query->len = val_len; ++ if (val) { ++ query->off = val_off; ++ memcpy((void *)node_raw + val_off, val, val_len); ++ } else { ++ query->off = 0; ++ } ++ ++ query->index++; /* The query returned the record right before @key */ ++ ++ /* Add the new entry to the table of contents */ ++ apfs_create_toc_entry(query); ++ ++ apfs_update_node(node); ++ return 0; ++ ++defrag: ++ if (defragged) { ++ apfs_err(sb, "node reports incorrect free space"); ++ return -EFSCORRUPTED; ++ } ++ err = apfs_defragment_node(node); ++ if (err) { ++ apfs_err(sb, "failed to defragment node"); ++ return err; ++ } ++ defragged = true; ++ goto retry; ++} ++ ++/** ++ * apfs_create_single_rec_node - Creates a new node with a single record ++ * @query: query run to search for the record ++ * @key: on-disk record key ++ * @key_len: length of @key ++ * @val: on-disk record value ++ * @val_len: length of @val ++ * ++ * The new node is placed right after the one found by @query, which must have ++ * a single record. On success, returns 0 and sets @query to the new record; ++ * returns a negative error code in case of failure, which may be -EAGAIN if a ++ * node split has happened and the caller must refresh and retry. ++ */ ++int apfs_create_single_rec_node(struct apfs_query *query, void *key, int key_len, void *val, int val_len) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_node *new_node = NULL, *prev_node = NULL; ++ struct apfs_btree_node_phys *prev_raw = NULL; ++ struct apfs_btree_node_phys *new_raw = NULL; ++ int err; ++ ++ prev_node = query->node; ++ sb = prev_node->object.sb; ++ ++ ASSERT(query->parent); ++ ASSERT(prev_node->records == 1); ++ ASSERT(val && val_len); ++ ++ /* This function should only be needed for huge catalog records */ ++ if (prev_node->tree_type != APFS_OBJECT_TYPE_FSTREE) { ++ apfs_err(sb, "huge node records in the wrong tree"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* ++ * This will only be called for leaf nodes because it's the values that ++ * can get huge, not the keys. It will also never be called for root, ++ * because the catalog always has more than a single record. ++ */ ++ if (apfs_node_is_root(prev_node) || !apfs_node_is_leaf(prev_node)) { ++ apfs_err(sb, "huge record in index node"); ++ return -EFSCORRUPTED; ++ } ++ ++ new_node = apfs_create_node(sb, apfs_query_storage(query)); ++ if (IS_ERR(new_node)) { ++ apfs_err(sb, "node creation failed"); ++ return PTR_ERR(new_node); ++ } ++ new_node->tree_type = prev_node->tree_type; ++ new_node->flags = prev_node->flags; ++ new_node->records = 0; ++ new_node->key_free_list_len = 0; ++ new_node->val_free_list_len = 0; ++ new_node->key = new_node->free = sizeof(*new_raw); ++ new_node->val = sb->s_blocksize; /* Nonroot */ ++ ++ prev_raw = (void *)prev_node->object.data; ++ new_raw = (void *)new_node->object.data; ++ apfs_assert_in_transaction(sb, &new_raw->btn_o); ++ new_raw->btn_level = prev_raw->btn_level; ++ apfs_update_node(new_node); ++ ++ query->node = new_node; ++ new_node = NULL; ++ query->index = -1; ++ err = apfs_node_insert(query, key, key_len, val, val_len); ++ if (err) { ++ apfs_err(sb, "node record insertion failed"); ++ goto fail; ++ } ++ ++ err = apfs_attach_child(query->parent, query->node); ++ if (err) { ++ if (err != -EAGAIN) { ++ apfs_err(sb, "child attachment failed"); ++ goto fail; ++ } ++ err = apfs_delete_node(query->node, query->flags & APFS_QUERY_TREE_MASK); ++ if (err) { ++ apfs_err(sb, "node cleanup failed for query retry"); ++ goto fail; ++ } ++ ++ /* ++ * The query must remain pointing to the original node for the ++ * refresh to take place. The index will not matter though. ++ */ ++ new_node = query->node; ++ query->node = prev_node; ++ prev_node = NULL; ++ err = -EAGAIN; ++ goto fail; ++ } ++ apfs_btree_change_node_count(query->parent, 1 /* change */); ++ ++fail: ++ apfs_node_free(prev_node); ++ apfs_node_free(new_node); ++ return err; ++} +diff --git a/fs/apfs/object.c b/fs/apfs/object.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/object.c +@@ -0,0 +1,315 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Checksum routines for an APFS object ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/* ++ * Note that this is not a generic implementation of fletcher64, as it assumes ++ * a message length that doesn't overflow sum1 and sum2. This constraint is ok ++ * for apfs, though, since the block size is limited to 2^16. For a more ++ * generic optimized implementation, see Nakassis (1988). ++ */ ++static u64 apfs_fletcher64(void *addr, size_t len) ++{ ++ __le32 *buff = addr; ++ u64 sum1 = 0; ++ u64 sum2 = 0; ++ u64 c1, c2; ++ int i, count_32; ++ ++ count_32 = len >> 2; ++ for (i = 0; i < count_32; i++) { ++ sum1 += le32_to_cpu(buff[i]); ++ sum2 += sum1; ++ } ++ ++ c1 = sum1 + sum2; ++ c1 = 0xFFFFFFFF - do_div(c1, 0xFFFFFFFF); ++ c2 = sum1 + c1; ++ c2 = 0xFFFFFFFF - do_div(c2, 0xFFFFFFFF); ++ ++ return (c2 << 32) | c1; ++} ++ ++int apfs_obj_verify_csum(struct super_block *sb, struct buffer_head *bh) ++{ ++ /* The checksum may be stale until the transaction is committed */ ++ if (buffer_trans(bh)) ++ return 1; ++ return apfs_multiblock_verify_csum(bh->b_data, sb->s_blocksize); ++} ++ ++/** ++ * apfs_multiblock_verify_csum - Verify an object's checksum ++ * @object: the object to verify ++ * @size: size of the object in bytes (may be multiple blocks) ++ * ++ * Returns 1 on success, 0 on failure. ++ */ ++int apfs_multiblock_verify_csum(char *object, u32 size) ++{ ++ struct apfs_obj_phys *obj = (struct apfs_obj_phys *)object; ++ u64 actual_csum, header_csum; ++ ++ header_csum = le64_to_cpu(obj->o_cksum); ++ actual_csum = apfs_fletcher64(object + APFS_MAX_CKSUM_SIZE, size - APFS_MAX_CKSUM_SIZE); ++ return header_csum == actual_csum; ++} ++ ++/** ++ * apfs_obj_set_csum - Set the fletcher checksum in an object header ++ * @sb: superblock structure ++ * @obj: the object header ++ * ++ * The object must have a length of a single block. ++ */ ++void apfs_obj_set_csum(struct super_block *sb, struct apfs_obj_phys *obj) ++{ ++ apfs_multiblock_set_csum((char *)obj, sb->s_blocksize); ++} ++ ++/** ++ * apfs_multiblock_set_csum - Set an object's checksum ++ * @object: the object to checksum ++ * @size: size of the object in bytes (may be multiple blocks) ++ */ ++void apfs_multiblock_set_csum(char *object, u32 size) ++{ ++ struct apfs_obj_phys *obj = (struct apfs_obj_phys *)object; ++ u64 cksum; ++ ++ cksum = apfs_fletcher64(object + APFS_MAX_CKSUM_SIZE, size - APFS_MAX_CKSUM_SIZE); ++ obj->o_cksum = cpu_to_le64(cksum); ++} ++ ++/** ++ * apfs_create_cpm_block - Create a new checkpoint-mapping block ++ * @sb: filesystem superblock ++ * @bno: block number to use ++ * @bh_p: on return, the buffer head for the block ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_create_cpm_block(struct super_block *sb, u64 bno, struct buffer_head **bh_p) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_checkpoint_map_phys *cpm = NULL; ++ struct buffer_head *bh = NULL; ++ int err; ++ ++ bh = apfs_getblk(sb, bno); ++ if (!bh) { ++ apfs_err(sb, "failed to map cpm block"); ++ return -EIO; ++ } ++ err = apfs_transaction_join(sb, bh); ++ if (err) { ++ brelse(bh); ++ return err; ++ } ++ set_buffer_csum(bh); ++ ++ cpm = (void *)bh->b_data; ++ memset(cpm, 0, sb->s_blocksize); ++ cpm->cpm_o.o_oid = cpu_to_le64(bno); ++ cpm->cpm_o.o_xid = cpu_to_le64(nxi->nx_xid); ++ cpm->cpm_o.o_type = cpu_to_le32(APFS_OBJ_PHYSICAL | APFS_OBJECT_TYPE_CHECKPOINT_MAP); ++ cpm->cpm_o.o_subtype = cpu_to_le32(APFS_OBJECT_TYPE_INVALID); ++ ++ /* For now: the caller will have to update these fields */ ++ cpm->cpm_flags = cpu_to_le32(APFS_CHECKPOINT_MAP_LAST); ++ cpm->cpm_count = 0; ++ ++ *bh_p = bh; ++ return 0; ++} ++ ++/** ++ * apfs_create_cpoint_map - Create a checkpoint mapping for an object ++ * @sb: filesystem superblock ++ * @cpm: checkpoint mapping block to use ++ * @obj: header for the ephemeral object ++ * @bno: block number for the ephemeral object ++ * @size: size of the ephemeral object in bytes ++ * ++ * Returns 0 on success or a negative error code in case of failure, which may ++ * be -ENOSPC if @cpm is full. ++ */ ++int apfs_create_cpoint_map(struct super_block *sb, struct apfs_checkpoint_map_phys *cpm, struct apfs_obj_phys *obj, u64 bno, u32 size) ++{ ++ struct apfs_checkpoint_mapping *map = NULL; ++ u32 cpm_count; ++ ++ apfs_assert_in_transaction(sb, &cpm->cpm_o); ++ ++ cpm_count = le32_to_cpu(cpm->cpm_count); ++ if (cpm_count >= apfs_max_maps_per_block(sb)) ++ return -ENOSPC; ++ map = &cpm->cpm_map[cpm_count]; ++ le32_add_cpu(&cpm->cpm_count, 1); ++ ++ map->cpm_type = obj->o_type; ++ map->cpm_subtype = obj->o_subtype; ++ map->cpm_size = cpu_to_le32(size); ++ map->cpm_pad = 0; ++ map->cpm_fs_oid = 0; ++ map->cpm_oid = obj->o_oid; ++ map->cpm_paddr = cpu_to_le64(bno); ++ return 0; ++} ++ ++/** ++ * apfs_index_in_data_area - Get position of block in current checkpoint's data ++ * @sb: superblock structure ++ * @bno: block number ++ */ ++u32 apfs_index_in_data_area(struct super_block *sb, u64 bno) ++{ ++ struct apfs_nx_superblock *raw_sb = APFS_NXI(sb)->nx_raw; ++ u64 data_base = le64_to_cpu(raw_sb->nx_xp_data_base); ++ u32 data_index = le32_to_cpu(raw_sb->nx_xp_data_index); ++ u32 data_blks = le32_to_cpu(raw_sb->nx_xp_data_blocks); ++ u64 tmp; ++ ++ tmp = bno - data_base + data_blks - data_index; ++ return do_div(tmp, data_blks); ++} ++ ++/** ++ * apfs_data_index_to_bno - Convert index in data area to block number ++ * @sb: superblock structure ++ * @index: index of the block in the current checkpoint's data area ++ */ ++u64 apfs_data_index_to_bno(struct super_block *sb, u32 index) ++{ ++ struct apfs_nx_superblock *raw_sb = APFS_NXI(sb)->nx_raw; ++ u64 data_base = le64_to_cpu(raw_sb->nx_xp_data_base); ++ u32 data_index = le32_to_cpu(raw_sb->nx_xp_data_index); ++ u32 data_blks = le32_to_cpu(raw_sb->nx_xp_data_blocks); ++ ++ return data_base + (index + data_index) % data_blks; ++} ++ ++/** ++ * apfs_ephemeral_object_lookup - Find an ephemeral object info in memory ++ * @sb: superblock structure ++ * @oid: ephemeral object id ++ * ++ * Returns a pointer to the object info on success, or an error pointer in case ++ * of failure. ++ */ ++struct apfs_ephemeral_object_info *apfs_ephemeral_object_lookup(struct super_block *sb, u64 oid) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_ephemeral_object_info *list = NULL; ++ int i; ++ ++ list = nxi->nx_eph_list; ++ for (i = 0; i < nxi->nx_eph_count; ++i) { ++ if (list[i].oid == oid) ++ return &list[i]; ++ } ++ apfs_err(sb, "no mapping for oid 0x%llx", oid); ++ return ERR_PTR(-EFSCORRUPTED); ++} ++ ++/** ++ * apfs_read_object_block - Map a non-ephemeral object block ++ * @sb: superblock structure ++ * @bno: block number for the object ++ * @write: request write access? ++ * @preserve: preserve the old block? ++ * ++ * On success returns the mapped buffer head for the object, which may now be ++ * in a new location if write access was requested. Returns an error pointer ++ * in case of failure. ++ */ ++struct buffer_head *apfs_read_object_block(struct super_block *sb, u64 bno, bool write, bool preserve) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_superblock *vsb_raw = NULL; ++ struct buffer_head *bh, *new_bh; ++ struct apfs_obj_phys *obj; ++ u32 type; ++ u64 new_bno; ++ int err; ++ ++ ASSERT(write || !preserve); ++ ++ bh = apfs_sb_bread(sb, bno); ++ if (!bh) { ++ apfs_err(sb, "failed to read object block 0x%llx", bno); ++ return ERR_PTR(-EIO); ++ } ++ ++ obj = (struct apfs_obj_phys *)bh->b_data; ++ type = le32_to_cpu(obj->o_type); ++ ASSERT(!(type & APFS_OBJ_EPHEMERAL)); ++ if (nxi->nx_flags & APFS_CHECK_NODES && !apfs_obj_verify_csum(sb, bh)) { ++ apfs_err(sb, "bad checksum for object in block 0x%llx", bno); ++ err = -EFSBADCRC; ++ goto fail; ++ } ++ ++ if (!write) ++ return bh; ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ ++ /* Is the object already part of the current transaction? */ ++ if (obj->o_xid == cpu_to_le64(nxi->nx_xid)) ++ return bh; ++ ++ err = apfs_spaceman_allocate_block(sb, &new_bno, true /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ goto fail; ++ } ++ new_bh = apfs_getblk(sb, new_bno); ++ if (!new_bh) { ++ apfs_err(sb, "failed to map block for CoW (0x%llx)", new_bno); ++ err = -EIO; ++ goto fail; ++ } ++ memcpy(new_bh->b_data, bh->b_data, sb->s_blocksize); ++ ++ /* ++ * Don't free the old copy of the object if it's part of a snapshot. ++ * Also increase the allocation count, except for the volume superblock ++ * which is never counted there. ++ */ ++ if (!preserve) { ++ err = apfs_free_queue_insert(sb, bh->b_blocknr, 1); ++ if (err) ++ apfs_err(sb, "free queue insertion failed for 0x%llx", (unsigned long long)bh->b_blocknr); ++ } else if ((type & APFS_OBJECT_TYPE_MASK) != APFS_OBJECT_TYPE_FS) { ++ vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_fs_alloc_count, 1); ++ le64_add_cpu(&vsb_raw->apfs_total_blocks_alloced, 1); ++ } ++ ++ brelse(bh); ++ bh = new_bh; ++ new_bh = NULL; ++ if (err) ++ goto fail; ++ obj = (struct apfs_obj_phys *)bh->b_data; ++ ++ if (type & APFS_OBJ_PHYSICAL) ++ obj->o_oid = cpu_to_le64(new_bno); ++ obj->o_xid = cpu_to_le64(nxi->nx_xid); ++ err = apfs_transaction_join(sb, bh); ++ if (err) ++ goto fail; ++ ++ set_buffer_csum(bh); ++ return bh; ++ ++fail: ++ brelse(bh); ++ return ERR_PTR(err); ++} +diff --git a/fs/apfs/snapshot.c b/fs/apfs/snapshot.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/snapshot.c +@@ -0,0 +1,687 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2022 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_create_superblock_snapshot - Take a snapshot of the volume superblock ++ * @sb: superblock structure ++ * @bno: on return, the block number for the new superblock copy ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_create_superblock_snapshot(struct super_block *sb, u64 *bno) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct buffer_head *curr_bh = NULL; ++ struct buffer_head *snap_bh = NULL; ++ struct apfs_superblock *snap_raw = NULL; ++ int err; ++ ++ err = apfs_spaceman_allocate_block(sb, bno, true /* backwards */); ++ if (err) { ++ apfs_err(sb, "block allocation failed"); ++ goto fail; ++ } ++ ++ snap_bh = apfs_getblk(sb, *bno); ++ if (!snap_bh) { ++ apfs_err(sb, "failed to map block for volume snap (0x%llx)", *bno); ++ err = -EIO; ++ goto fail; ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ ++ curr_bh = sbi->s_vobject.o_bh; ++ memcpy(snap_bh->b_data, curr_bh->b_data, sb->s_blocksize); ++ curr_bh = NULL; ++ ++ err = apfs_transaction_join(sb, snap_bh); ++ if (err) ++ goto fail; ++ set_buffer_csum(snap_bh); ++ ++ snap_raw = (struct apfs_superblock *)snap_bh->b_data; ++ /* Volume superblocks in snapshots are physical objects */ ++ snap_raw->apfs_o.o_oid = cpu_to_le64p(bno); ++ snap_raw->apfs_o.o_type = cpu_to_le32(APFS_OBJ_PHYSICAL | APFS_OBJECT_TYPE_FS); ++ /* The omap is shared with the current volume */ ++ snap_raw->apfs_omap_oid = 0; ++ /* The extent reference tree is given by the snapshot metadata */ ++ snap_raw->apfs_extentref_tree_oid = 0; ++ /* No snapshots inside snapshots */ ++ snap_raw->apfs_snap_meta_tree_oid = 0; ++ ++ err = 0; ++fail: ++ snap_raw = NULL; ++ brelse(snap_bh); ++ snap_bh = NULL; ++ return err; ++} ++ ++static int apfs_create_snap_metadata_rec(struct inode *mntpoint, struct apfs_node *snap_root, const char *name, int name_len, u64 sblock_oid) ++{ ++ struct super_block *sb = mntpoint->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_query *query = NULL; ++ struct apfs_snap_metadata_key raw_key; ++ struct apfs_snap_metadata_val *raw_val = NULL; ++ int val_len; ++ struct timespec64 now; ++ u64 xid = APFS_NXI(sb)->nx_xid; ++ int err; ++ ++ query = apfs_alloc_query(snap_root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ apfs_init_snap_metadata_key(xid, &query->key); ++ query->flags |= APFS_QUERY_SNAP_META | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err == 0) { ++ apfs_err(sb, "record exists for xid 0x%llx", xid); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ if (err != -ENODATA) { ++ apfs_err(sb, "query failed for xid 0x%llx", xid); ++ goto fail; ++ } ++ ++ apfs_key_set_hdr(APFS_TYPE_SNAP_METADATA, xid, &raw_key); ++ ++ val_len = sizeof(*raw_val) + name_len + 1; ++ raw_val = kzalloc(val_len, GFP_KERNEL); ++ if (!raw_val) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ raw_val->extentref_tree_oid = vsb_raw->apfs_extentref_tree_oid; ++ raw_val->sblock_oid = cpu_to_le64(sblock_oid); ++ now = current_time(mntpoint); ++ raw_val->create_time = cpu_to_le64(timespec64_to_ns(&now)); ++ raw_val->change_time = raw_val->create_time; ++ raw_val->extentref_tree_type = vsb_raw->apfs_extentref_tree_type; ++ raw_val->flags = 0; ++ raw_val->name_len = cpu_to_le16(name_len + 1); /* Count the null byte */ ++ strscpy(raw_val->name, name, name_len + 1); ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ raw_val->inum = vsb_raw->apfs_next_obj_id; ++ le64_add_cpu(&vsb_raw->apfs_next_obj_id, 1); ++ ++ err = apfs_btree_insert(query, &raw_key, sizeof(raw_key), raw_val, val_len); ++ if (err) ++ apfs_err(sb, "insertion failed for xid 0x%llx", xid); ++fail: ++ kfree(raw_val); ++ raw_val = NULL; ++ apfs_free_query(query); ++ query = NULL; ++ return err; ++} ++ ++static int apfs_create_snap_name_rec(struct apfs_node *snap_root, const char *name, int name_len) ++{ ++ struct super_block *sb = snap_root->object.sb; ++ struct apfs_query *query = NULL; ++ struct apfs_snap_name_key *raw_key = NULL; ++ struct apfs_snap_name_val raw_val; ++ int key_len; ++ int err; ++ ++ query = apfs_alloc_query(snap_root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ apfs_init_snap_name_key(name, &query->key); ++ query->flags |= APFS_QUERY_SNAP_META | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err == 0) { ++ /* This should never happen here, the caller has checked */ ++ apfs_alert(sb, "snapshot name record already exists"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ if (err != -ENODATA) { ++ apfs_err(sb, "query failed (%s)", name); ++ goto fail; ++ } ++ ++ key_len = sizeof(*raw_key) + name_len + 1; ++ raw_key = kzalloc(key_len, GFP_KERNEL); ++ if (!raw_key) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ apfs_key_set_hdr(APFS_TYPE_SNAP_NAME, APFS_SNAP_NAME_OBJ_ID, raw_key); ++ raw_key->name_len = cpu_to_le16(name_len + 1); /* Count the null byte */ ++ strscpy(raw_key->name, name, name_len + 1); ++ ++ raw_val.snap_xid = cpu_to_le64(APFS_NXI(sb)->nx_xid); ++ ++ err = apfs_btree_insert(query, raw_key, key_len, &raw_val, sizeof(raw_val)); ++ if (err) ++ apfs_err(sb, "insertion failed (%s)", name); ++fail: ++ kfree(raw_key); ++ raw_key = NULL; ++ apfs_free_query(query); ++ query = NULL; ++ return err; ++} ++ ++static int apfs_create_snap_meta_records(struct inode *mntpoint, const char *name, int name_len, u64 sblock_oid) ++{ ++ struct super_block *sb = mntpoint->i_sb; ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_node *snap_root = NULL; ++ int err; ++ ++ snap_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid), APFS_OBJ_PHYSICAL, true /* write */); ++ if (IS_ERR(snap_root)) { ++ apfs_err(sb, "failed to read snap meta root 0x%llx", le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid)); ++ return PTR_ERR(snap_root); ++ } ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_snap_meta_tree_oid = cpu_to_le64(snap_root->object.oid); ++ ++ err = apfs_create_snap_metadata_rec(mntpoint, snap_root, name, name_len, sblock_oid); ++ if (err) { ++ apfs_err(sb, "meta rec creation failed"); ++ goto fail; ++ } ++ err = apfs_create_snap_name_rec(snap_root, name, name_len); ++ if (err) ++ apfs_err(sb, "name rec creation failed"); ++ ++fail: ++ apfs_node_free(snap_root); ++ return err; ++} ++ ++static int apfs_create_new_extentref_tree(struct super_block *sb) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ u64 oid; ++ int err; ++ ++ err = apfs_make_empty_btree_root(sb, APFS_OBJECT_TYPE_BLOCKREFTREE, &oid); ++ if (err) { ++ apfs_err(sb, "failed to make empty root"); ++ return err; ++ } ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_extentref_tree_oid = cpu_to_le64(oid); ++ return 0; ++} ++ ++/** ++ * apfs_update_omap_snap_tree - Add the current xid to the omap's snapshot tree ++ * @sb: filesystem superblock ++ * @oid_p: pointer to the on-disk block number for the root node ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_update_omap_snap_tree(struct super_block *sb, __le64 *oid_p) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_node *root = NULL; ++ u64 oid = le64_to_cpup(oid_p); ++ struct apfs_query *query = NULL; ++ __le64 raw_key; ++ struct apfs_omap_snapshot raw_val = {0}; ++ int err; ++ ++ /* An empty snapshots tree may not even have a root yet */ ++ if (!oid) { ++ err = apfs_make_empty_btree_root(sb, APFS_OBJECT_TYPE_OMAP_SNAPSHOT, &oid); ++ if (err) { ++ apfs_err(sb, "failed to make empty root"); ++ return err; ++ } ++ } ++ ++ root = apfs_read_node(sb, oid, APFS_OBJ_PHYSICAL, true /* write */); ++ if (IS_ERR(root)) { ++ apfs_err(sb, "failed to read omap snap root 0x%llx", oid); ++ return PTR_ERR(root); ++ } ++ oid = 0; ++ ++ query = apfs_alloc_query(root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ apfs_init_omap_snap_key(nxi->nx_xid, &query->key); ++ query->flags = APFS_QUERY_OMAP_SNAP | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err == 0) { ++ apfs_err(sb, "record exists for xid 0x%llx", nxi->nx_xid); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ if (err != -ENODATA) { ++ apfs_err(sb, "query failed for xid 0x%llx", nxi->nx_xid); ++ goto fail; ++ } ++ ++ raw_key = cpu_to_le64(nxi->nx_xid); ++ err = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ if (err) ++ apfs_err(sb, "insertion failed for xid 0x%llx", nxi->nx_xid); ++ *oid_p = cpu_to_le64(root->object.block_nr); ++ ++fail: ++ apfs_free_query(query); ++ query = NULL; ++ apfs_node_free(root); ++ root = NULL; ++ return err; ++} ++ ++/** ++ * apfs_update_omap_snapshots - Add the current xid to the omap's snapshots ++ * @sb: filesystem superblock ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_update_omap_snapshots(struct super_block *sb) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct buffer_head *bh = NULL; ++ struct apfs_omap_phys *omap = NULL; ++ u64 omap_blk; ++ u64 xid; ++ int err; ++ ++ xid = APFS_NXI(sb)->nx_xid; ++ ++ omap_blk = le64_to_cpu(vsb_raw->apfs_omap_oid); ++ bh = apfs_read_object_block(sb, omap_blk, true /* write */, false /* preserve */); ++ if (IS_ERR(bh)) { ++ apfs_err(sb, "CoW failed for bno 0x%llx", omap_blk); ++ return PTR_ERR(bh); ++ } ++ omap = (struct apfs_omap_phys *)bh->b_data; ++ ++ apfs_assert_in_transaction(sb, &omap->om_o); ++ le32_add_cpu(&omap->om_snap_count, 1); ++ omap->om_most_recent_snap = cpu_to_le64(xid); ++ err = apfs_update_omap_snap_tree(sb, &omap->om_snapshot_tree_oid); ++ if (err) ++ apfs_err(sb, "omap snap tree update failed"); ++ ++ omap = NULL; ++ brelse(bh); ++ bh = NULL; ++ return err; ++} ++ ++/** ++ * apfs_snapshot_name_check - Check if a snapshot with the given name exists ++ * @sb: filesystem superblock ++ * @name: name to check ++ * @name_len: length of @name ++ * @eexist: on return, whether the name exists or not ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_snapshot_name_check(struct super_block *sb, const char *name, int name_len, bool *eexist) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_node *snap_root = NULL; ++ struct apfs_query *query = NULL; ++ int err; ++ ++ snap_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid), APFS_OBJ_PHYSICAL, false /* write */); ++ if (IS_ERR(snap_root)) { ++ apfs_err(sb, "failed to read snap meta root 0x%llx", le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid)); ++ return PTR_ERR(snap_root); ++ } ++ vsb_raw = NULL; ++ ++ query = apfs_alloc_query(snap_root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto out; ++ } ++ apfs_init_snap_name_key(name, &query->key); ++ query->flags |= APFS_QUERY_SNAP_META | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err == 0) { ++ *eexist = true; ++ } else if (err == -ENODATA) { ++ *eexist = false; ++ err = 0; ++ } else { ++ apfs_err(sb, "query failed (%s)", name); ++ } ++ ++out: ++ apfs_free_query(query); ++ query = NULL; ++ apfs_node_free(snap_root); ++ snap_root = NULL; ++ return err; ++} ++ ++/** ++ * apfs_do_ioc_takesnapshot - Actual work for apfs_ioc_take_snapshot() ++ * @mntpoint: inode of the mount point to snapshot ++ * @name: label for the snapshot ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_do_ioc_take_snapshot(struct inode *mntpoint, const char *name, int name_len) ++{ ++ struct super_block *sb = mntpoint->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = NULL; ++ struct apfs_omap *omap = sbi->s_omap; ++ u64 sblock_oid; ++ bool eexist = false; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ ++ /* ++ * This check can fail in normal operation, so run it before making any ++ * changes and exit the transaction cleanly if necessary. The name ++ * lookup will have to be repeated later, but it's ok because I don't ++ * expect snapshot creation to be a bottleneck for anyone. ++ */ ++ err = apfs_snapshot_name_check(sb, name, name_len, &eexist); ++ if (err) { ++ apfs_err(sb, "snapshot name existence check failed"); ++ goto fail; ++ } ++ if (eexist) { ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ apfs_warn(sb, "snapshot name already in use (%s)", name); ++ return -EEXIST; ++ } ++ ++ /* ++ * Flush the extent caches to the extenref tree before it gets moved to ++ * the snapshot. It seems safer in general to avoid big unpredictable ++ * changes to the layout after the snapshot is set up. ++ */ ++ err = apfs_transaction_flush_all_inodes(sb); ++ if (err) { ++ apfs_err(sb, "failed to flush all inodes"); ++ goto fail; ++ } ++ ++ err = apfs_create_superblock_snapshot(sb, &sblock_oid); ++ if (err) { ++ apfs_err(sb, "failed to snapshot superblock"); ++ goto fail; ++ } ++ ++ err = apfs_create_snap_meta_records(mntpoint, name, name_len, sblock_oid); ++ if (err) { ++ apfs_err(sb, "failed to create snap meta records"); ++ goto fail; ++ } ++ ++ err = apfs_create_new_extentref_tree(sb); ++ if (err) { ++ apfs_err(sb, "failed to create new extref tree"); ++ goto fail; ++ } ++ ++ err = apfs_update_omap_snapshots(sb); ++ if (err) { ++ apfs_err(sb, "failed to update omap snapshots"); ++ goto fail; ++ } ++ ++ /* ++ * The official reference allows old implementations to ignore extended ++ * snapshot metadata, so I don't see any reason why we can't do the ++ * same for now. ++ */ ++ ++ vsb_raw = sbi->s_vsb_raw; ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ le64_add_cpu(&vsb_raw->apfs_num_snapshots, 1); ++ ++ omap->omap_latest_snap = APFS_NXI(sb)->nx_xid; ++ ++ sbi->s_nxi->nx_transaction.t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_ioc_take_snapshot - Ioctl handler for APFS_IOC_CREATE_SNAPSHOT ++ * @file: affected file ++ * @arg: ioctl argument ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_ioc_take_snapshot(struct file *file, void __user *user_arg) ++{ ++ struct inode *inode = file_inode(file); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_ioctl_snap_name *arg = NULL; ++ size_t name_len; ++ int err; ++ ++ if (apfs_ino(inode) != APFS_ROOT_DIR_INO_NUM) { ++ apfs_info(sb, "snapshot must be requested on mountpoint"); ++ return -ENOTTY; ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ if (!inode_owner_or_capable(inode)) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++ if (!inode_owner_or_capable(&init_user_ns, inode)) ++#else ++ if (!inode_owner_or_capable(&nop_mnt_idmap, inode)) ++#endif ++ return -EPERM; ++ ++ err = mnt_want_write_file(file); ++ if (err) ++ return err; ++ ++ arg = kzalloc(sizeof(*arg), GFP_KERNEL); ++ if (!arg) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ if (copy_from_user(arg, user_arg, sizeof(*arg))) { ++ err = -EFAULT; ++ goto fail; ++ } ++ ++ name_len = strnlen(arg->name, sizeof(arg->name)); ++ if (name_len == sizeof(arg->name)) { ++ apfs_warn(sb, "snapshot name is too long (%d)", (int)name_len); ++ err = -EINVAL; ++ goto fail; ++ } ++ ++ err = apfs_do_ioc_take_snapshot(inode, arg->name, name_len); ++fail: ++ kfree(arg); ++ arg = NULL; ++ mnt_drop_write_file(file); ++ return err; ++} ++ ++static int apfs_snap_xid_from_query(struct apfs_query *query, u64 *xid) ++{ ++ char *raw = query->node->object.data; ++ __le64 *val = NULL; ++ ++ if (query->len != sizeof(*val)) { ++ apfs_err(query->node->object.sb, "bad value length (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ val = (__le64 *)(raw + query->off); ++ ++ *xid = le64_to_cpup(val); ++ return 0; ++} ++ ++static int apfs_snapshot_name_to_xid(struct apfs_node *snap_root, const char *name, u64 *xid) ++{ ++ struct super_block *sb = snap_root->object.sb; ++ struct apfs_query *query = NULL; ++ int err; ++ ++ query = apfs_alloc_query(snap_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_snap_name_key(name, &query->key); ++ query->flags |= APFS_QUERY_SNAP_META | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err) { ++ if (err != -ENODATA) ++ apfs_err(sb, "query failed (%s)", name); ++ goto fail; ++ } ++ ++ err = apfs_snap_xid_from_query(query, xid); ++ if (err) ++ apfs_err(sb, "bad snap name record (%s)", name); ++fail: ++ apfs_free_query(query); ++ query = NULL; ++ return err; ++} ++ ++static int apfs_snap_sblock_from_query(struct apfs_query *query, u64 *sblock_oid) ++{ ++ struct super_block *sb = query->node->object.sb; ++ char *raw = query->node->object.data; ++ struct apfs_snap_metadata_val *val = NULL; ++ ++ if (query->len < sizeof(*val)) { ++ apfs_err(sb, "bad value length (%d)", query->len); ++ return -EFSCORRUPTED; ++ } ++ val = (struct apfs_snap_metadata_val *)(raw + query->off); ++ ++ /* I don't know anything about these snapshots, can they be mounted? */ ++ if (le32_to_cpu(val->flags) & APFS_SNAP_META_PENDING_DATALESS) { ++ apfs_warn(sb, "the requested snapshot is dataless"); ++ return -EOPNOTSUPP; ++ } ++ ++ *sblock_oid = le64_to_cpu(val->sblock_oid); ++ return 0; ++} ++ ++static int apfs_snapshot_xid_to_sblock(struct apfs_node *snap_root, u64 xid, u64 *sblock_oid) ++{ ++ struct super_block *sb = snap_root->object.sb; ++ struct apfs_query *query = NULL; ++ int err; ++ ++ query = apfs_alloc_query(snap_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_snap_metadata_key(xid, &query->key); ++ query->flags |= APFS_QUERY_SNAP_META | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err) { ++ apfs_err(sb, "query failed for xid 0x%llx", xid); ++ goto fail; ++ } ++ ++ err = apfs_snap_sblock_from_query(query, sblock_oid); ++ if (err) ++ apfs_err(sb, "bad snap meta record for xid 0x%llx", xid); ++fail: ++ apfs_free_query(query); ++ query = NULL; ++ return err; ++} ++ ++/** ++ * apfs_switch_to_snapshot - Start working with the snapshot volume superblock ++ * @sb: superblock structure ++ * ++ * Maps the volume superblock from the snapshot specified in the mount options. ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_switch_to_snapshot(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_node *snap_root = NULL; ++ const char *name = NULL; ++ u64 sblock_oid = 0; ++ u64 xid = 0; ++ int err; ++ ++ ASSERT(sb->s_flags & SB_RDONLY); ++ ++ name = sbi->s_snap_name; ++ if (strlen(name) > APFS_SNAP_MAX_NAMELEN) { ++ apfs_warn(sb, "snapshot name is too long"); ++ return -EINVAL; ++ } ++ ++ snap_root = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid), APFS_OBJ_PHYSICAL, false /* write */); ++ if (IS_ERR(snap_root)) { ++ apfs_err(sb, "failed to read snap meta root 0x%llx", le64_to_cpu(vsb_raw->apfs_snap_meta_tree_oid)); ++ return PTR_ERR(snap_root); ++ } ++ vsb_raw = NULL; ++ ++ err = apfs_snapshot_name_to_xid(snap_root, name, &xid); ++ if (err) { ++ if (err == -ENODATA) ++ apfs_info(sb, "no snapshot under that name (%s)", name); ++ goto fail; ++ } ++ sbi->s_snap_xid = xid; ++ ++ err = apfs_snapshot_xid_to_sblock(snap_root, xid, &sblock_oid); ++ if (err) ++ goto fail; ++ ++ apfs_unmap_volume_super(sb); ++ err = apfs_map_volume_super_bno(sb, sblock_oid, nxi->nx_flags & APFS_CHECK_NODES); ++ if (err) ++ apfs_err(sb, "failed to map volume block 0x%llx", sblock_oid); ++ ++fail: ++ apfs_node_free(snap_root); ++ return err; ++} +diff --git a/fs/apfs/spaceman.c b/fs/apfs/spaceman.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/spaceman.c +@@ -0,0 +1,1479 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2019 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_spaceman_read_cib_addr - Get the address of a cib from the spaceman ++ * @sb: superblock structure ++ * @index: index of the chunk-info block ++ * ++ * Returns the block number for the chunk-info block. ++ * ++ * This is not described in the official documentation; credit for figuring it ++ * out should go to Joachim Metz: . ++ */ ++static u64 apfs_spaceman_read_cib_addr(struct super_block *sb, int index) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ u32 offset; ++ __le64 *addr_p; ++ ++ offset = sm->sm_addr_offset + index * sizeof(*addr_p); ++ addr_p = (void *)sm_raw + offset; ++ return le64_to_cpup(addr_p); ++} ++ ++/** ++ * apfs_spaceman_write_cib_addr - Store the address of a cib in the spaceman ++ * @sb: superblock structure ++ * @index: index of the chunk-info block ++ * @addr: address of the chunk-info block ++ */ ++static void apfs_spaceman_write_cib_addr(struct super_block *sb, ++ int index, u64 addr) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ u32 offset; ++ __le64 *addr_p; ++ ++ apfs_assert_in_transaction(sb, &sm_raw->sm_o); ++ ++ offset = sm->sm_addr_offset + index * sizeof(*addr_p); ++ addr_p = (void *)sm_raw + offset; ++ *addr_p = cpu_to_le64(addr); ++} ++ ++/** ++ * apfs_max_chunks_per_cib - Find the maximum chunk count for a chunk-info block ++ * @sb: superblock structure ++ */ ++static inline int apfs_max_chunks_per_cib(struct super_block *sb) ++{ ++ return (sb->s_blocksize - sizeof(struct apfs_chunk_info_block)) / ++ sizeof(struct apfs_chunk_info); ++} ++ ++/** ++ * apfs_read_spaceman_dev - Read a space manager device structure ++ * @sb: superblock structure ++ * @dev: on-disk device structure ++ * ++ * Initializes the in-memory spaceman fields related to the main device; fusion ++ * drives are not yet supported. Returns 0 on success, or a negative error code ++ * in case of failure. ++ */ ++static int apfs_read_spaceman_dev(struct super_block *sb, ++ struct apfs_spaceman_device *dev) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ ++ if (dev->sm_cab_count) { ++ apfs_err(sb, "large devices are not supported"); ++ return -EINVAL; ++ } ++ ++ spaceman->sm_block_count = le64_to_cpu(dev->sm_block_count); ++ spaceman->sm_chunk_count = le64_to_cpu(dev->sm_chunk_count); ++ spaceman->sm_cib_count = le32_to_cpu(dev->sm_cib_count); ++ spaceman->sm_free_count = le64_to_cpu(dev->sm_free_count); ++ spaceman->sm_addr_offset = le32_to_cpu(dev->sm_addr_offset); ++ ++ /* Check that all the cib addresses fit in the spaceman object */ ++ if ((long long)spaceman->sm_addr_offset + ++ (long long)spaceman->sm_cib_count * sizeof(u64) > spaceman->sm_size) { ++ apfs_err(sb, "too many cibs (%u)", spaceman->sm_cib_count); ++ return -EFSCORRUPTED; ++ } ++ ++ return 0; ++} ++ ++/** ++ * apfs_spaceman_get_16 - Get a 16-bit value from an offset in the spaceman ++ * @sb: superblock structure ++ * @off: offset for the value ++ * ++ * Returns a pointer to the value, or NULL if it doesn't fit. ++ */ ++static __le16 *apfs_spaceman_get_16(struct super_block *sb, size_t off) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = spaceman->sm_raw; ++ ++ if (off > spaceman->sm_size) ++ return NULL; ++ if (off + sizeof(__le16) > spaceman->sm_size) ++ return NULL; ++ return (void *)sm_raw + off; ++} ++ ++/** ++ * apfs_spaceman_get_64 - Get a 64-bit value from an offset in the spaceman ++ * @sb: superblock structure ++ * @off: offset for the value ++ * ++ * Returns a pointer to the value, or NULL if it doesn't fit. ++ */ ++static __le64 *apfs_spaceman_get_64(struct super_block *sb, size_t off) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = spaceman->sm_raw; ++ ++ if (off > spaceman->sm_size) ++ return NULL; ++ if (off + sizeof(__le64) > spaceman->sm_size) ++ return NULL; ++ return (void *)sm_raw + off; ++} ++ ++/** ++ * apfs_allocate_ip_bitmap - Allocate a free ip bitmap block ++ * @sb: filesystem superblock ++ * @offset_p: on return, the offset from sm_ip_bm_base of the allocated block ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_allocate_ip_bitmap(struct super_block *sb, u16 *offset_p) ++{ ++ struct apfs_spaceman *spaceman = NULL; ++ struct apfs_spaceman_phys *sm_raw = NULL; ++ u32 free_next_offset, old_head_off; ++ u16 free_head, blkcnt; ++ __le16 *old_head_p = NULL; ++ ++ spaceman = APFS_SM(sb); ++ sm_raw = spaceman->sm_raw; ++ free_next_offset = le32_to_cpu(sm_raw->sm_ip_bm_free_next_offset); ++ free_head = le16_to_cpu(sm_raw->sm_ip_bm_free_head); ++ blkcnt = (u16)le32_to_cpu(sm_raw->sm_ip_bm_block_count); ++ ++ /* ++ * The "free_next" array is a linked list of free blocks that starts ++ * with the "free_head". Allocate this head then, and make the next ++ * block into the new head. ++ */ ++ old_head_off = free_next_offset + free_head * sizeof(*old_head_p); ++ old_head_p = apfs_spaceman_get_16(sb, old_head_off); ++ if (!old_head_p) { ++ apfs_err(sb, "free_next head offset out of bounds (%u)", old_head_off); ++ return -EFSCORRUPTED; ++ } ++ *offset_p = free_head; ++ free_head = le16_to_cpup(old_head_p); ++ sm_raw->sm_ip_bm_free_head = *old_head_p; ++ /* No longer free, no longer part of the linked list */ ++ *old_head_p = cpu_to_le16(APFS_SPACEMAN_IP_BM_INDEX_INVALID); ++ ++ /* Just a little sanity check because I've messed this up before */ ++ if (free_head >= blkcnt || *offset_p >= blkcnt) { ++ apfs_err(sb, "free next list seems empty or corrupt"); ++ return -EFSCORRUPTED; ++ } ++ ++ return 0; ++} ++ ++/** ++ * apfs_free_ip_bitmap - Free a used ip bitmap block ++ * @sb: filesystem superblock ++ * @offset: the offset from sm_ip_bm_base of the block to free ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_free_ip_bitmap(struct super_block *sb, u16 offset) ++{ ++ struct apfs_spaceman *spaceman = NULL; ++ struct apfs_spaceman_phys *sm_raw = NULL; ++ u32 free_next_offset, old_tail_off; ++ u16 free_tail; ++ __le16 *old_tail_p = NULL; ++ ++ spaceman = APFS_SM(sb); ++ sm_raw = spaceman->sm_raw; ++ free_next_offset = le32_to_cpu(sm_raw->sm_ip_bm_free_next_offset); ++ free_tail = le16_to_cpu(sm_raw->sm_ip_bm_free_tail); ++ ++ /* ++ * The "free_next" array is a linked list of free blocks that ends ++ * with the "free_tail". The block getting freed will become the new ++ * tail of the list. ++ */ ++ old_tail_off = free_next_offset + free_tail * sizeof(*old_tail_p); ++ old_tail_p = apfs_spaceman_get_16(sb, old_tail_off); ++ if (!old_tail_p) { ++ apfs_err(sb, "free_next tail offset out of bounds (%u)", old_tail_off); ++ return -EFSCORRUPTED; ++ } ++ *old_tail_p = cpu_to_le16(offset); ++ sm_raw->sm_ip_bm_free_tail = cpu_to_le16(offset); ++ free_tail = offset; ++ ++ return 0; ++} ++ ++/** ++ * apfs_reallocate_ip_bitmap - Find a new block for an ip bitmap ++ * @sb: filesystem superblock ++ * @offset_p: the offset from sm_ip_bm_base of the block to free ++ * ++ * On success returns 0 and updates @offset_p to the new offset allocated for ++ * the ip bitmap. Since blocks are allocated at the head of the list and freed ++ * at the tail, there is no risk of reuse by future reallocations within the ++ * same transaction (under there is some serious corruption, of course). ++ * ++ * Returns a negative error code in case of failure. ++ */ ++static int apfs_reallocate_ip_bitmap(struct super_block *sb, __le16 *offset_p) ++{ ++ int err; ++ u16 offset; ++ ++ offset = le16_to_cpup(offset_p); ++ ++ err = apfs_free_ip_bitmap(sb, offset); ++ if (err) { ++ apfs_err(sb, "failed to free ip bitmap %u", offset); ++ return err; ++ } ++ err = apfs_allocate_ip_bitmap(sb, &offset); ++ if (err) { ++ apfs_err(sb, "failed to allocate a new ip bitmap block"); ++ return err; ++ } ++ ++ *offset_p = cpu_to_le16(offset); ++ return 0; ++} ++ ++/** ++ * apfs_write_single_ip_bitmap - Write a single ip bitmap to disk ++ * @sb: filesystem superblock ++ * @bitmap: bitmap to write ++ * @idx: index of the ip bitmap to write ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_write_single_ip_bitmap(struct super_block *sb, char *bitmap, u32 idx) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = spaceman->sm_raw; ++ struct buffer_head *bh = NULL; ++ u64 ip_bm_base, ip_bitmap_bno; ++ u32 xid_off, ip_bitmap_off; ++ __le64 *xid_p = NULL; ++ __le16 *ip_bitmap_p = NULL; ++ int err; ++ ++ ip_bm_base = le64_to_cpu(sm_raw->sm_ip_bm_base); ++ ++ /* First update the xid, which is kept in a separate array */ ++ xid_off = le32_to_cpu(sm_raw->sm_ip_bm_xid_offset) + idx * sizeof(*xid_p); ++ xid_p = apfs_spaceman_get_64(sb, xid_off); ++ if (!xid_p) { ++ apfs_err(sb, "xid out of bounds (%u)", xid_off); ++ return -EFSCORRUPTED; ++ } ++ *xid_p = cpu_to_le64(nxi->nx_xid); ++ ++ /* Now get find new location for the ip bitmap (and free the old one) */ ++ ip_bitmap_off = le32_to_cpu(sm_raw->sm_ip_bitmap_offset) + idx * sizeof(*ip_bitmap_p); ++ ip_bitmap_p = apfs_spaceman_get_16(sb, ip_bitmap_off); ++ if (!ip_bitmap_p) { ++ apfs_err(sb, "bmap offset out of bounds (%u)", ip_bitmap_off); ++ return -EFSCORRUPTED; ++ } ++ err = apfs_reallocate_ip_bitmap(sb, ip_bitmap_p); ++ if (err) { ++ apfs_err(sb, "failed to reallocate ip bitmap %u", le16_to_cpup(ip_bitmap_p)); ++ return err; ++ } ++ ++ /* Finally, write the dirty bitmap to the new location */ ++ ip_bitmap_bno = ip_bm_base + le16_to_cpup(ip_bitmap_p); ++ bh = apfs_getblk(sb, ip_bitmap_bno); ++ if (!bh) { ++ apfs_err(sb, "failed to map block for CoW (0x%llx)", ip_bitmap_bno); ++ return -EIO; ++ } ++ memcpy(bh->b_data, bitmap, sb->s_blocksize); ++ err = apfs_transaction_join(sb, bh); ++ if (err) ++ goto fail; ++ bh = NULL; ++ ++ spaceman->sm_ip_bmaps[idx].dirty = false; ++ return 0; ++ ++fail: ++ brelse(bh); ++ bh = NULL; ++ return err; ++} ++ ++/** ++ * apfs_write_ip_bitmaps - Write all dirty ip bitmaps to disk ++ * @sb: superblock structure ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_write_ip_bitmaps(struct super_block *sb) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = spaceman->sm_raw; ++ struct apfs_ip_bitmap_block_info *info = NULL; ++ u32 bmaps_count = spaceman->sm_ip_bmaps_count; ++ int err; ++ u32 i; ++ ++ apfs_assert_in_transaction(sb, &sm_raw->sm_o); ++ ++ for (i = 0; i < bmaps_count; ++i) { ++ info = &spaceman->sm_ip_bmaps[i]; ++ if (!info->dirty) ++ continue; ++ err = apfs_write_single_ip_bitmap(sb, info->block, i); ++ if (err) { ++ apfs_err(sb, "failed to rotate ip bitmap %u", i); ++ return err; ++ } ++ } ++ return 0; ++} ++ ++/** ++* apfs_read_single_ip_bitmap - Read a single ip bitmap to memory ++* @sb: filesystem superblock ++* @idx: index of the ip bitmap to read ++* ++* Returns 0 on success or a negative error code in case of failure. ++*/ ++static int apfs_read_single_ip_bitmap(struct super_block *sb, u32 idx) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = spaceman->sm_raw; ++ struct buffer_head *bh = NULL; ++ char *bitmap = NULL; ++ u64 ip_bm_base, ip_bitmap_bno; ++ u32 ip_bitmap_off; ++ __le16 *ip_bitmap_p = NULL; ++ int err; ++ ++ ip_bm_base = le64_to_cpu(sm_raw->sm_ip_bm_base); ++ ++ ip_bitmap_off = le32_to_cpu(sm_raw->sm_ip_bitmap_offset) + idx * sizeof(*ip_bitmap_p); ++ ip_bitmap_p = apfs_spaceman_get_16(sb, ip_bitmap_off); ++ if (!ip_bitmap_p) { ++ apfs_err(sb, "bmap offset out of bounds (%u)", ip_bitmap_off); ++ return -EFSCORRUPTED; ++ } ++ ++ bitmap = kmalloc(sb->s_blocksize, GFP_KERNEL); ++ if (!bitmap) ++ return -ENOMEM; ++ ++ ip_bitmap_bno = ip_bm_base + le16_to_cpup(ip_bitmap_p); ++ bh = apfs_sb_bread(sb, ip_bitmap_bno); ++ if (!bh) { ++ apfs_err(sb, "failed to read ip bitmap (0x%llx)", ip_bitmap_bno); ++ err = -EIO; ++ goto fail; ++ } ++ memcpy(bitmap, bh->b_data, sb->s_blocksize); ++ brelse(bh); ++ bh = NULL; ++ ++ spaceman->sm_ip_bmaps[idx].dirty = false; ++ spaceman->sm_ip_bmaps[idx].block = bitmap; ++ bitmap = NULL; ++ return 0; ++ ++fail: ++ kfree(bitmap); ++ bitmap = NULL; ++ return err; ++} ++ ++/** ++ * apfs_read_ip_bitmaps - Read all the ip bitmaps to memory ++ * @sb: superblock structure ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_read_ip_bitmaps(struct super_block *sb) ++{ ++ struct apfs_spaceman *spaceman = APFS_SM(sb); ++ u32 bmaps_count = spaceman->sm_ip_bmaps_count; ++ int err; ++ u32 i; ++ ++ for (i = 0; i < bmaps_count; ++i) { ++ err = apfs_read_single_ip_bitmap(sb, i); ++ if (err) { ++ apfs_err(sb, "failed to read ip bitmap %u", i); ++ return err; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * Free queue record data ++ */ ++struct apfs_fq_rec { ++ u64 xid; ++ u64 bno; ++ u64 len; ++}; ++ ++/** ++ * apfs_fq_rec_from_query - Read the free queue record found by a query ++ * @query: the query that found the record ++ * @fqrec: on return, the free queue record ++ * ++ * Reads the free queue record into @fqrec and performs some basic sanity ++ * checks as a protection against crafted filesystems. Returns 0 on success ++ * or -EFSCORRUPTED otherwise. ++ */ ++static int apfs_fq_rec_from_query(struct apfs_query *query, struct apfs_fq_rec *fqrec) ++{ ++ char *raw = query->node->object.data; ++ struct apfs_spaceman_free_queue_key *key; ++ ++ if (query->key_len != sizeof(*key)) { ++ apfs_err(query->node->object.sb, "bad key length (%d)", query->key_len); ++ return -EFSCORRUPTED; ++ } ++ key = (struct apfs_spaceman_free_queue_key *)(raw + query->key_off); ++ ++ fqrec->xid = le64_to_cpu(key->sfqk_xid); ++ fqrec->bno = le64_to_cpu(key->sfqk_paddr); ++ ++ if (query->len == 0) { ++ fqrec->len = 1; /* Ghost record */ ++ return 0; ++ } else if (query->len == sizeof(__le64)) { ++ fqrec->len = le64_to_cpup((__le64 *)(raw + query->off)); ++ return 0; ++ } ++ apfs_err(query->node->object.sb, "bad value length (%d)", query->len); ++ return -EFSCORRUPTED; ++} ++ ++/** ++ * apfs_block_in_ip - Does this block belong to the internal pool? ++ * @sm: in-memory spaceman structure ++ * @bno: block number to check ++ */ ++static inline bool apfs_block_in_ip(struct apfs_spaceman *sm, u64 bno) ++{ ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ u64 start = le64_to_cpu(sm_raw->sm_ip_base); ++ u64 end = start + le64_to_cpu(sm_raw->sm_ip_block_count); ++ ++ return bno >= start && bno < end; ++} ++ ++/** ++ * apfs_ip_mark_free - Mark a block in the internal pool as free ++ * @sb: superblock structure ++ * @bno: block number (must belong to the ip) ++ */ ++static int apfs_ip_mark_free(struct super_block *sb, u64 bno) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_ip_bitmap_block_info *info = NULL; ++ ++ bno -= le64_to_cpu(sm_raw->sm_ip_base); ++ info = &sm->sm_ip_bmaps[bno >> sm->sm_ip_bmaps_shift]; ++ __clear_bit_le(bno & sm->sm_ip_bmaps_mask, info->block); ++ info->dirty = true; ++ ++ return 0; ++} ++ ++/* ++ * apfs_main_free - Mark a regular block as free ++ */ ++static int apfs_main_free(struct super_block *sb, u64 bno); ++ ++/** ++ * apfs_flush_fq_rec - Delete a single fq record and mark its blocks as free ++ * @root: free queue root node ++ * @xid: transaction to target ++ * @len: on return, the number of freed blocks ++ * ++ * Returns 0 on success, or a negative error code in case of failure. -ENODATA ++ * in particular means that there are no matching records left. ++ */ ++static int apfs_flush_fq_rec(struct apfs_node *root, u64 xid, u64 *len) ++{ ++ struct super_block *sb = root->object.sb; ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_query *query = NULL; ++ struct apfs_fq_rec fqrec = {0}; ++ u64 bno; ++ int err; ++ ++ query = apfs_alloc_query(root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_free_queue_key(xid, 0 /* paddr */, &query->key); ++ query->flags |= APFS_QUERY_FREE_QUEUE | APFS_QUERY_ANY_NUMBER | APFS_QUERY_EXACT; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err) { ++ if (err != -ENODATA) ++ apfs_err(sb, "query failed for xid 0x%llx, paddr 0x%llx", xid, 0ULL); ++ goto fail; ++ } ++ err = apfs_fq_rec_from_query(query, &fqrec); ++ if (err) { ++ apfs_err(sb, "bad free queue rec for xid 0x%llx", xid); ++ goto fail; ++ } ++ ++ for (bno = fqrec.bno; bno < fqrec.bno + fqrec.len; ++bno) { ++ if (apfs_block_in_ip(sm, bno)) ++ err = apfs_ip_mark_free(sb, bno); ++ else ++ err = apfs_main_free(sb, bno); ++ if (err) { ++ apfs_err(sb, "freeing block 0x%llx failed (%d)", (unsigned long long)bno, err); ++ goto fail; ++ } ++ } ++ err = apfs_btree_remove(query); ++ if (err) { ++ apfs_err(sb, "removal failed for xid 0x%llx", xid); ++ goto fail; ++ } ++ *len = fqrec.len; ++ ++fail: ++ apfs_free_query(query); ++ return err; ++} ++ ++/** ++ * apfs_free_queue_oldest_xid - Find the oldest xid among the free queue records ++ * @root: free queue root node ++ */ ++static u64 apfs_free_queue_oldest_xid(struct apfs_node *root) ++{ ++ struct apfs_spaceman_free_queue_key *key; ++ char *raw = root->object.data; ++ int len, off; ++ ++ if (root->records == 0) ++ return 0; ++ len = apfs_node_locate_key(root, 0, &off); ++ if (len != sizeof(*key)) { ++ /* TODO: abort transaction */ ++ apfs_err(root->object.sb, "bad key length (%d)", len); ++ return 0; ++ } ++ key = (struct apfs_spaceman_free_queue_key *)(raw + off); ++ return le64_to_cpu(key->sfqk_xid); ++} ++ ++/** ++ * apfs_flush_free_queue - Free ip blocks queued by old transactions ++ * @sb: superblock structure ++ * @qid: queue to be freed ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_flush_free_queue(struct super_block *sb, unsigned int qid) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_spaceman_free_queue *fq = &sm_raw->sm_fq[qid]; ++ struct apfs_node *fq_root; ++ struct apfs_btree_info *fq_info = NULL; ++ u64 oldest = le64_to_cpu(fq->sfq_oldest_xid); ++ int err; ++ ++ fq_root = apfs_read_node(sb, le64_to_cpu(fq->sfq_tree_oid), ++ APFS_OBJ_EPHEMERAL, true /* write */); ++ if (IS_ERR(fq_root)) { ++ apfs_err(sb, "failed to read fq root 0x%llx", le64_to_cpu(fq->sfq_tree_oid)); ++ return PTR_ERR(fq_root); ++ } ++ ++ while (oldest) { ++ /* ++ * Blocks freed in the current transaction can't be reused ++ * safely until after the commit, but I don't think there is ++ * any point in preserving old transacions. I'm guessing the ++ * official driver keeps multiple transactions going at the ++ * same time, that must be why they need a free queue. ++ */ ++ if (oldest == nxi->nx_xid) ++ break; ++ ++ while (true) { ++ u64 count = 0; ++ ++ /* Probably not very efficient... */ ++ err = apfs_flush_fq_rec(fq_root, oldest, &count); ++ if (err == -ENODATA) { ++ err = 0; ++ break; ++ } else if (err) { ++ apfs_err(sb, "failed to flush fq"); ++ goto fail; ++ } else { ++ le64_add_cpu(&fq->sfq_count, -count); ++ } ++ } ++ oldest = apfs_free_queue_oldest_xid(fq_root); ++ fq->sfq_oldest_xid = cpu_to_le64(oldest); ++ } ++ ++ if (qid == APFS_SFQ_MAIN) { ++ fq_info = (void *)fq_root->object.data + sb->s_blocksize - sizeof(*fq_info); ++ sm->sm_main_fq_nodes = le64_to_cpu(fq_info->bt_node_count); ++ if (sm->sm_main_fq_nodes != 1) { ++ apfs_alert(sb, "main queue wasn't flushed in full - bug!"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ } ++ ++fail: ++ apfs_node_free(fq_root); ++ return err; ++} ++ ++/** ++ * apfs_allocate_spaceman - Allocate an in-memory spaceman struct, if needed ++ * @sb: superblock structure ++ * @raw: on-disk spaceman struct ++ * @size: size of the on-disk spaceman ++ * ++ * Returns the spaceman and sets it in the superblock info. Also performs all ++ * initializations for the internal pool, including reading all the ip bitmaps. ++ * This is a bit out of place here, but it's convenient because it has to ++ * happen only once. ++ * ++ * On failure, returns an error pointer. ++ */ ++static struct apfs_spaceman *apfs_allocate_spaceman(struct super_block *sb, struct apfs_spaceman_phys *raw, u32 size) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *spaceman = NULL; ++ int blk_bitcnt = sb->s_blocksize * 8; ++ size_t sm_size; ++ u32 bmap_cnt; ++ int err; ++ ++ if (nxi->nx_spaceman) ++ return nxi->nx_spaceman; ++ ++ /* We don't expect filesystems this big, it would be like 260 TiB */ ++ bmap_cnt = le32_to_cpu(raw->sm_ip_bm_size_in_blocks); ++ if (bmap_cnt > 200) { ++ apfs_err(sb, "too many ip bitmap blocks (%u)", bmap_cnt); ++ return ERR_PTR(-EFSCORRUPTED); ++ } ++ sm_size = sizeof(*spaceman) + bmap_cnt * sizeof(spaceman->sm_ip_bmaps[0]); ++ ++ spaceman = nxi->nx_spaceman = kzalloc(sm_size, GFP_KERNEL); ++ if (!spaceman) ++ return ERR_PTR(-ENOMEM); ++ spaceman->sm_nxi = nxi; ++ /* ++ * These two fields must be set before reading the ip bitmaps, since ++ * that stuff involves several variable-length arrays inside the ++ * spaceman object itself. ++ */ ++ spaceman->sm_raw = raw; ++ spaceman->sm_size = size; ++ ++ spaceman->sm_ip_bmaps_count = bmap_cnt; ++ spaceman->sm_ip_bmaps_mask = blk_bitcnt - 1; ++ spaceman->sm_ip_bmaps_shift = order_base_2(blk_bitcnt); ++ ++ /* This must happen only once, so it's easier to just leave it here */ ++ err = apfs_read_ip_bitmaps(sb); ++ if (err) { ++ apfs_err(sb, "failed to read the ip bitmaps"); ++ kfree(spaceman); ++ nxi->nx_spaceman = spaceman = NULL; ++ return ERR_PTR(err); ++ } ++ ++ return nxi->nx_spaceman; ++} ++ ++/** ++ * apfs_read_spaceman - Find and read the space manager ++ * @sb: superblock structure ++ * ++ * Reads the space manager structure from disk and initializes its in-memory ++ * counterpart; returns 0 on success, or a negative error code in case of ++ * failure. ++ */ ++int apfs_read_spaceman(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = nxi->nx_raw; ++ struct apfs_spaceman *spaceman = NULL; ++ struct apfs_ephemeral_object_info *sm_eph_info = NULL; ++ struct apfs_spaceman_phys *sm_raw; ++ u32 sm_flags; ++ u64 oid = le64_to_cpu(raw_sb->nx_spaceman_oid); ++ int err; ++ ++ if (sb->s_flags & SB_RDONLY) /* The space manager won't be needed */ ++ return 0; ++ ++ sm_eph_info = apfs_ephemeral_object_lookup(sb, oid); ++ if (IS_ERR(sm_eph_info)) { ++ apfs_err(sb, "no spaceman object for oid 0x%llx", oid); ++ return PTR_ERR(sm_eph_info); ++ } ++ sm_raw = (struct apfs_spaceman_phys *)sm_eph_info->object; ++ sm_raw->sm_o.o_xid = cpu_to_le64(nxi->nx_xid); ++ ++ spaceman = apfs_allocate_spaceman(sb, sm_raw, sm_eph_info->size); ++ if (IS_ERR(spaceman)) { ++ apfs_err(sb, "failed to allocate spaceman"); ++ err = PTR_ERR(spaceman); ++ goto fail; ++ } ++ ++ spaceman->sm_free_cache_base = spaceman->sm_free_cache_blkcnt = 0; ++ ++ sm_flags = le32_to_cpu(sm_raw->sm_flags); ++ /* Undocumented feature, but it's too common to refuse to mount */ ++ if (sm_flags & APFS_SM_FLAG_VERSIONED) ++ pr_warn_once("APFS: space manager is versioned\n"); ++ ++ /* Only read the main device; fusion drives are not yet supported */ ++ err = apfs_read_spaceman_dev(sb, &sm_raw->sm_dev[APFS_SD_MAIN]); ++ if (err) { ++ apfs_err(sb, "failed to read main device"); ++ goto fail; ++ } ++ ++ spaceman->sm_blocks_per_chunk = ++ le32_to_cpu(sm_raw->sm_blocks_per_chunk); ++ spaceman->sm_chunks_per_cib = le32_to_cpu(sm_raw->sm_chunks_per_cib); ++ if (spaceman->sm_chunks_per_cib > apfs_max_chunks_per_cib(sb)) { ++ apfs_err(sb, "too many chunks per cib (%u)", spaceman->sm_chunks_per_cib); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ /* ++ * We flush free queues whole when each transaction begins, to make it ++ * harder for the btrees to become too unbalanced. ++ */ ++ err = apfs_flush_free_queue(sb, APFS_SFQ_IP); ++ if (err) { ++ apfs_err(sb, "failed to flush ip fq"); ++ goto fail; ++ } ++ err = apfs_flush_free_queue(sb, APFS_SFQ_MAIN); ++ if (err) { ++ apfs_err(sb, "failed to flush main fq"); ++ goto fail; ++ } ++ return 0; ++ ++fail: ++ spaceman->sm_raw = NULL; ++ return err; ++} ++ ++/** ++ * apfs_write_spaceman - Write the in-memory spaceman fields to the disk buffer ++ * @sm: in-memory spaceman structure ++ * ++ * Copies the updated in-memory fields of the space manager into the on-disk ++ * structure; the buffer is not dirtied. ++ */ ++static void apfs_write_spaceman(struct apfs_spaceman *sm) ++{ ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_spaceman_device *dev_raw = &sm_raw->sm_dev[APFS_SD_MAIN]; ++ struct apfs_nxsb_info *nxi; ++ ++ nxi = sm->sm_nxi; ++ ASSERT(le64_to_cpu(sm_raw->sm_o.o_xid) == nxi->nx_xid); ++ ++ dev_raw->sm_free_count = cpu_to_le64(sm->sm_free_count); ++} ++ ++/** ++ * apfs_ip_find_free - Find a free block inside the internal pool ++ * @sb: superblock structure ++ * ++ * Returns the block number for a free block, or 0 in case of corruption. ++ */ ++static u64 apfs_ip_find_free(struct super_block *sb) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ int blk_bitcnt = sb->s_blocksize * 8; ++ u64 full_bitcnt = le64_to_cpu(sm_raw->sm_ip_block_count); ++ u32 i; ++ ++ for (i = 0; i < sm->sm_ip_bmaps_count; ++i) { ++ char *bitmap = sm->sm_ip_bmaps[i].block; ++ u64 off_in_bmap_blk, off_in_ip; ++ ++ off_in_bmap_blk = find_next_zero_bit_le(bitmap, blk_bitcnt, 0 /* offset */); ++ if (off_in_bmap_blk >= blk_bitcnt) /* No space in this chunk */ ++ continue; ++ ++ /* We found something, confirm that it's not outside the ip */ ++ off_in_ip = (i << sm->sm_ip_bmaps_shift) + off_in_bmap_blk; ++ if (off_in_ip >= full_bitcnt) ++ break; ++ return le64_to_cpu(sm_raw->sm_ip_base) + off_in_ip; ++ } ++ apfs_err(sb, "internal pool seems full"); ++ return 0; ++} ++ ++/** ++ * apfs_chunk_find_free - Find a free block inside a chunk ++ * @sb: superblock structure ++ * @bitmap: allocation bitmap for the chunk, which should have free blocks ++ * @addr: number of the first block in the chunk ++ * ++ * Returns the block number for a free block, or 0 in case of corruption. ++ */ ++static u64 apfs_chunk_find_free(struct super_block *sb, char *bitmap, u64 addr) ++{ ++ int bitcount = sb->s_blocksize * 8; ++ u64 bno; ++ ++ bno = find_next_zero_bit_le(bitmap, bitcount, 0 /* offset */); ++ if (bno >= bitcount) ++ return 0; ++ return addr + bno; ++} ++ ++/** ++ * apfs_ip_mark_used - Mark a block in the internal pool as used ++ * @sb: superblock strucuture ++ * @bno: block number (must belong to the ip) ++ */ ++static void apfs_ip_mark_used(struct super_block *sb, u64 bno) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_ip_bitmap_block_info *info = NULL; ++ ++ bno -= le64_to_cpu(sm_raw->sm_ip_base); ++ info = &sm->sm_ip_bmaps[bno >> sm->sm_ip_bmaps_shift]; ++ __set_bit_le(bno & sm->sm_ip_bmaps_mask, info->block); ++ info->dirty = true; ++} ++ ++/** ++ * apfs_chunk_mark_used - Mark a block inside a chunk as used ++ * @sb: superblock structure ++ * @bitmap: allocation bitmap for the chunk ++ * @bno: block number (must belong to the chunk) ++ */ ++static inline void apfs_chunk_mark_used(struct super_block *sb, char *bitmap, ++ u64 bno) ++{ ++ int bitcount = sb->s_blocksize * 8; ++ ++ __set_bit_le(bno & (bitcount - 1), bitmap); ++} ++ ++/** ++ * apfs_chunk_mark_free - Mark a block inside a chunk as free ++ * @sb: superblock structure ++ * @bitmap: allocation bitmap for the chunk ++ * @bno: block number (must belong to the chunk) ++ */ ++static inline int apfs_chunk_mark_free(struct super_block *sb, char *bitmap, ++ u64 bno) ++{ ++ int bitcount = sb->s_blocksize * 8; ++ ++ return __test_and_clear_bit_le(bno & (bitcount - 1), bitmap); ++} ++ ++/** ++ * apfs_free_queue_try_insert - Try to add a block range to its free queue ++ * @sb: superblock structure ++ * @bno: first block number to free ++ * @count: number of consecutive blocks to free ++ * ++ * Same as apfs_free_queue_insert_nocache(), except that this one can also fail ++ * with -ENOSPC if there is no room for the new record. ++ */ ++static int apfs_free_queue_try_insert(struct super_block *sb, u64 bno, u64 count) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_spaceman_free_queue *fq; ++ struct apfs_node *fq_root = NULL; ++ struct apfs_btree_info *fq_info = NULL; ++ struct apfs_query *query = NULL; ++ struct apfs_spaceman_free_queue_key raw_key; ++ bool ghost = count == 1; ++ int needed_room; ++ __le64 raw_val; ++ u64 node_count; ++ u16 node_limit; ++ unsigned int qid; ++ int err; ++ ++ qid = apfs_block_in_ip(sm, bno) ? APFS_SFQ_IP : APFS_SFQ_MAIN; ++ fq = &sm_raw->sm_fq[qid]; ++ ++ fq_root = apfs_read_node(sb, le64_to_cpu(fq->sfq_tree_oid), ++ APFS_OBJ_EPHEMERAL, true /* write */); ++ if (IS_ERR(fq_root)) { ++ apfs_err(sb, "failed to read fq root 0x%llx", le64_to_cpu(fq->sfq_tree_oid)); ++ return PTR_ERR(fq_root); ++ } ++ ++ query = apfs_alloc_query(fq_root, NULL /* parent */); ++ if (!query) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ apfs_init_free_queue_key(nxi->nx_xid, bno, &query->key); ++ query->flags |= APFS_QUERY_FREE_QUEUE; ++ ++ err = apfs_btree_query(sb, &query); ++ if (err && err != -ENODATA) { ++ apfs_err(sb, "query failed for xid 0x%llx, paddr 0x%llx", nxi->nx_xid, bno); ++ goto fail; ++ } ++ ++ fq_info = (void *)fq_root->object.data + sb->s_blocksize - sizeof(*fq_info); ++ node_count = le64_to_cpu(fq_info->bt_node_count); ++ node_limit = le16_to_cpu(fq->sfq_tree_node_limit); ++ if (node_count == node_limit) { ++ needed_room = sizeof(raw_key) + (ghost ? 0 : sizeof(raw_val)); ++ if (!apfs_node_has_room(query->node, needed_room, false /* replace */)) { ++ err = -ENOSPC; ++ goto fail; ++ } ++ } ++ ++ raw_key.sfqk_xid = cpu_to_le64(nxi->nx_xid); ++ raw_key.sfqk_paddr = cpu_to_le64(bno); ++ if (ghost) { ++ /* A lack of value (ghost record) means single-block extent */ ++ err = apfs_btree_insert(query, &raw_key, sizeof(raw_key), NULL /* val */, 0 /* val_len */); ++ } else { ++ raw_val = cpu_to_le64(count); ++ err = apfs_btree_insert(query, &raw_key, sizeof(raw_key), &raw_val, sizeof(raw_val)); ++ } ++ if (err) { ++ apfs_err(sb, "insertion failed for xid 0x%llx, paddr 0x%llx", nxi->nx_xid, bno); ++ goto fail; ++ } ++ ++ if (!fq->sfq_oldest_xid) ++ fq->sfq_oldest_xid = cpu_to_le64(nxi->nx_xid); ++ le64_add_cpu(&fq->sfq_count, count); ++ ++ if (qid == APFS_SFQ_MAIN) ++ sm->sm_main_fq_nodes = le64_to_cpu(fq_info->bt_node_count); ++ ++fail: ++ apfs_free_query(query); ++ apfs_node_free(fq_root); ++ return err; ++} ++ ++/** ++ * apfs_free_queue_insert_nocache - Add a block range to its free queue ++ * @sb: superblock structure ++ * @bno: first block number to free ++ * @count: number of consecutive blocks to free ++ * ++ * Same as apfs_free_queue_insert(), but writes to the free queue directly, ++ * bypassing the cache of the latest freed block range. ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_free_queue_insert_nocache(struct super_block *sb, u64 bno, u64 count) ++{ ++ unsigned int qid; ++ int err; ++ ++ err = apfs_free_queue_try_insert(sb, bno, count); ++ if (err == -ENOSPC) { ++ qid = apfs_block_in_ip(APFS_SM(sb), bno) ? APFS_SFQ_IP : APFS_SFQ_MAIN; ++ apfs_alert(sb, "free queue (%u) seems full - bug!", qid); ++ err = -EFSCORRUPTED; ++ } ++ if (err) { ++ apfs_err(sb, "fq insert failed (0x%llx-0x%llx)", bno, count); ++ return err; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_free_queue_insert - Add a block range to its free queue ++ * @sb: superblock structure ++ * @bno: first block number to free ++ * @count: number of consecutive blocks to free ++ * ++ * Uses a cache to delay the actual tree operations as much as possible. ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_free_queue_insert(struct super_block *sb, u64 bno, u64 count) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ int err; ++ ++ if (sm->sm_free_cache_base == 0) { ++ /* Nothing yet cached */ ++ sm->sm_free_cache_base = bno; ++ sm->sm_free_cache_blkcnt = count; ++ return 0; ++ } ++ ++ /* ++ * First attempt to extend the cache of freed blocks, but never cache ++ * a range that doesn't belong to a single free queue. ++ */ ++ if (apfs_block_in_ip(sm, bno) == apfs_block_in_ip(sm, sm->sm_free_cache_base)) { ++ if (bno == sm->sm_free_cache_base + sm->sm_free_cache_blkcnt) { ++ sm->sm_free_cache_blkcnt += count; ++ return 0; ++ } ++ if (bno + count == sm->sm_free_cache_base) { ++ sm->sm_free_cache_base -= count; ++ sm->sm_free_cache_blkcnt += count; ++ return 0; ++ } ++ } ++ ++ /* Failed to extend the cache, so flush it and replace it */ ++ err = apfs_free_queue_insert_nocache(sb, sm->sm_free_cache_base, sm->sm_free_cache_blkcnt); ++ if (err) { ++ apfs_err(sb, "fq cache flush failed (0x%llx-0x%llx)", sm->sm_free_cache_base, sm->sm_free_cache_blkcnt); ++ return err; ++ } ++ sm->sm_free_cache_base = bno; ++ sm->sm_free_cache_blkcnt = count; ++ return 0; ++} ++ ++/** ++ * apfs_chunk_alloc_free - Allocate or free block in given CIB and chunk ++ * @sb: superblock structure ++ * @cib_bh: buffer head for the chunk-info block ++ * @index: index of this chunk's info structure inside @cib ++ * @bno: block number ++ * @is_alloc: true to allocate, false to free ++ */ ++static int apfs_chunk_alloc_free(struct super_block *sb, ++ struct buffer_head **cib_bh, ++ int index, u64 *bno, bool is_alloc) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_chunk_info_block *cib; ++ struct apfs_chunk_info *ci; ++ struct buffer_head *bmap_bh = NULL; ++ char *bmap = NULL; ++ bool old_cib = false; ++ bool old_bmap = false; ++ int err = 0; ++ ++ cib = (struct apfs_chunk_info_block *)(*cib_bh)->b_data; ++ ci = &cib->cib_chunk_info[index]; ++ ++ /* Cibs and bitmaps from old transactions can't be modified in place */ ++ if (le64_to_cpu(cib->cib_o.o_xid) < nxi->nx_xid) ++ old_cib = true; ++ if (le64_to_cpu(ci->ci_xid) < nxi->nx_xid) ++ old_bmap = true; ++ if (is_alloc && le32_to_cpu(ci->ci_free_count) < 1) ++ return -ENOSPC; ++ ++ /* Read the current bitmap, or allocate it if necessary */ ++ if (!ci->ci_bitmap_addr) { ++ u64 bmap_bno; ++ ++ if (!is_alloc) { ++ apfs_err(sb, "attempt to free block in all-free chunk"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* All blocks in this chunk are free */ ++ bmap_bno = apfs_ip_find_free(sb); ++ if (!bmap_bno) { ++ apfs_err(sb, "no free blocks in ip"); ++ return -EFSCORRUPTED; ++ } ++ bmap_bh = apfs_sb_bread(sb, bmap_bno); ++ } else { ++ bmap_bh = apfs_sb_bread(sb, le64_to_cpu(ci->ci_bitmap_addr)); ++ } ++ if (!bmap_bh) { ++ apfs_err(sb, "failed to read bitmap block"); ++ return -EIO; ++ } ++ bmap = bmap_bh->b_data; ++ if (!ci->ci_bitmap_addr) { ++ memset(bmap, 0, sb->s_blocksize); ++ old_bmap = false; ++ } ++ ++ /* Write the bitmap to its location for the next transaction */ ++ if (old_bmap) { ++ struct buffer_head *new_bmap_bh; ++ u64 new_bmap_bno; ++ ++ new_bmap_bno = apfs_ip_find_free(sb); ++ if (!new_bmap_bno) { ++ apfs_err(sb, "no free blocks in ip"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ new_bmap_bh = apfs_getblk(sb, new_bmap_bno); ++ if (!new_bmap_bh) { ++ apfs_err(sb, "failed to map new bmap block (0x%llx)", new_bmap_bno); ++ err = -EIO; ++ goto fail; ++ } ++ memcpy(new_bmap_bh->b_data, bmap, sb->s_blocksize); ++ err = apfs_free_queue_insert(sb, bmap_bh->b_blocknr, 1); ++ brelse(bmap_bh); ++ bmap_bh = new_bmap_bh; ++ if (err) { ++ apfs_err(sb, "free queue insertion failed"); ++ goto fail; ++ } ++ bmap = bmap_bh->b_data; ++ } ++ apfs_ip_mark_used(sb, bmap_bh->b_blocknr); ++ ++ /* Write the cib to its location for the next transaction */ ++ if (old_cib) { ++ struct buffer_head *new_cib_bh; ++ u64 new_cib_bno; ++ ++ new_cib_bno = apfs_ip_find_free(sb); ++ if (!new_cib_bno) { ++ apfs_err(sb, "no free blocks in ip"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ new_cib_bh = apfs_getblk(sb, new_cib_bno); ++ if (!new_cib_bh) { ++ apfs_err(sb, "failed to map new cib block (0x%llx)", new_cib_bno); ++ err = -EIO; ++ goto fail; ++ } ++ memcpy(new_cib_bh->b_data, (*cib_bh)->b_data, sb->s_blocksize); ++ err = apfs_free_queue_insert(sb, (*cib_bh)->b_blocknr, 1); ++ brelse(*cib_bh); ++ *cib_bh = new_cib_bh; ++ if (err) { ++ apfs_err(sb, "free queue insertion failed"); ++ goto fail; ++ } ++ ++ err = apfs_transaction_join(sb, *cib_bh); ++ if (err) ++ goto fail; ++ ++ cib = (struct apfs_chunk_info_block *)(*cib_bh)->b_data; ++ ci = &cib->cib_chunk_info[index]; ++ cib->cib_o.o_oid = cpu_to_le64(new_cib_bno); ++ cib->cib_o.o_xid = cpu_to_le64(nxi->nx_xid); ++ ++ apfs_ip_mark_used(sb, new_cib_bno); ++ } ++ ++ /* The chunk info can be updated now */ ++ apfs_assert_in_transaction(sb, &cib->cib_o); ++ ci->ci_xid = cpu_to_le64(nxi->nx_xid); ++ le32_add_cpu(&ci->ci_free_count, is_alloc ? -1 : 1); ++ ci->ci_bitmap_addr = cpu_to_le64(bmap_bh->b_blocknr); ++ ASSERT(buffer_trans(*cib_bh)); ++ set_buffer_csum(*cib_bh); ++ ++ /* Finally, allocate / free the actual block that was requested */ ++ if (is_alloc) { ++ *bno = apfs_chunk_find_free(sb, bmap, le64_to_cpu(ci->ci_addr)); ++ if (!*bno) { ++ apfs_err(sb, "no free blocks in chunk"); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ apfs_chunk_mark_used(sb, bmap, *bno); ++ sm->sm_free_count -= 1; ++ } else { ++ if (!apfs_chunk_mark_free(sb, bmap, *bno)) { ++ apfs_err(sb, "block already marked as free (0x%llx)", *bno); ++ le32_add_cpu(&ci->ci_free_count, -1); ++ set_buffer_csum(*cib_bh); ++ err = -EFSCORRUPTED; ++ } else ++ sm->sm_free_count += 1; ++ } ++ mark_buffer_dirty(bmap_bh); ++ ++fail: ++ brelse(bmap_bh); ++ return err; ++} ++ ++/** ++ * apfs_chunk_allocate_block - Allocate a single block from a chunk ++ * @sb: superblock structure ++ * @cib_bh: buffer head for the chunk-info block ++ * @index: index of this chunk's info structure inside @cib ++ * @bno: on return, the allocated block number ++ * ++ * Finds a free block in the chunk and marks it as used; the buffer at @cib_bh ++ * may be replaced if needed for copy-on-write. Returns 0 on success, or a ++ * negative error code in case of failure. ++ */ ++static int apfs_chunk_allocate_block(struct super_block *sb, ++ struct buffer_head **cib_bh, ++ int index, u64 *bno) ++{ ++ return apfs_chunk_alloc_free(sb, cib_bh, index, bno, true); ++} ++ ++/** ++ * apfs_cib_allocate_block - Allocate a single block from a cib ++ * @sb: superblock structure ++ * @cib_bh: buffer head for the chunk-info block ++ * @bno: on return, the allocated block number ++ * @backwards: start the search on the last chunk ++ * ++ * Finds a free block among all the chunks in the cib and marks it as used; the ++ * buffer at @cib_bh may be replaced if needed for copy-on-write. Returns 0 on ++ * success, or a negative error code in case of failure. ++ */ ++static int apfs_cib_allocate_block(struct super_block *sb, ++ struct buffer_head **cib_bh, u64 *bno, bool backwards) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_chunk_info_block *cib; ++ u32 chunk_count; ++ int i; ++ ++ cib = (struct apfs_chunk_info_block *)(*cib_bh)->b_data; ++ if (nxi->nx_flags & APFS_CHECK_NODES && !apfs_obj_verify_csum(sb, *cib_bh)) { ++ apfs_err(sb, "bad checksum for chunk-info block"); ++ return -EFSBADCRC; ++ } ++ ++ /* Avoid out-of-bounds operations on corrupted cibs */ ++ chunk_count = le32_to_cpu(cib->cib_chunk_info_count); ++ if (chunk_count > sm->sm_chunks_per_cib) { ++ apfs_err(sb, "too many chunks in cib (%u)", chunk_count); ++ return -EFSCORRUPTED; ++ } ++ ++ for (i = 0; i < chunk_count; ++i) { ++ int index; ++ int err; ++ ++ index = backwards ? chunk_count - 1 - i : i; ++ ++ err = apfs_chunk_allocate_block(sb, cib_bh, index, bno); ++ if (err == -ENOSPC) /* This chunk is full */ ++ continue; ++ if (err) ++ apfs_err(sb, "error during allocation"); ++ return err; ++ } ++ return -ENOSPC; ++} ++ ++/** ++ * apfs_spaceman_allocate_block - Allocate a single on-disk block ++ * @sb: superblock structure ++ * @bno: on return, the allocated block number ++ * @backwards: start the search on the last chunk ++ * ++ * Finds a free block among the spaceman bitmaps and marks it as used. Returns ++ * 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_spaceman_allocate_block(struct super_block *sb, u64 *bno, bool backwards) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ int i; ++ ++ for (i = 0; i < sm->sm_cib_count; ++i) { ++ struct buffer_head *cib_bh; ++ u64 cib_bno; ++ int index; ++ int err; ++ ++ /* Keep extents and metadata separate to limit fragmentation */ ++ index = backwards ? sm->sm_cib_count - 1 - i : i; ++ ++ cib_bno = apfs_spaceman_read_cib_addr(sb, index); ++ cib_bh = apfs_sb_bread(sb, cib_bno); ++ if (!cib_bh) { ++ apfs_err(sb, "failed to read cib"); ++ return -EIO; ++ } ++ ++ err = apfs_cib_allocate_block(sb, &cib_bh, bno, backwards); ++ if (!err) { ++ /* The cib may have been moved */ ++ apfs_spaceman_write_cib_addr(sb, index, cib_bh->b_blocknr); ++ /* The free block count has changed */ ++ apfs_write_spaceman(sm); ++ } ++ brelse(cib_bh); ++ if (err == -ENOSPC) /* This cib is full */ ++ continue; ++ if (err) ++ apfs_err(sb, "error during allocation"); ++ return err; ++ } ++ /* ++ * We checked the free space before starting the transaction, so this ++ * isn't expected to happen. ++ */ ++ apfs_err(sb, "ran out of space during transaction"); ++ return -ENOSPC; ++} ++ ++/** ++ * apfs_chunk_free - Mark a regular block as free given CIB and chunk ++ * @sb: superblock structure ++ * @cib_bh: buffer head for the chunk-info block ++ * @index: index of this chunk's info structure inside @cib ++ * @bno: block number (must not belong to the ip) ++ */ ++static int apfs_chunk_free(struct super_block *sb, ++ struct buffer_head **cib_bh, ++ int index, u64 bno) ++{ ++ return apfs_chunk_alloc_free(sb, cib_bh, index, &bno, false); ++} ++ ++/** ++ * apfs_main_free - Mark a regular block as free ++ * @sb: superblock structure ++ * @bno: block number (must not belong to the ip) ++ */ ++static int apfs_main_free(struct super_block *sb, u64 bno) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_sb_info *sbi = NULL; ++ u64 cib_idx, chunk_idx; ++ struct buffer_head *cib_bh; ++ u64 cib_bno; ++ int err, orphan_err; ++ ++ if (!sm_raw->sm_blocks_per_chunk || !sm_raw->sm_chunks_per_cib) { ++ apfs_err(sb, "block or chunk count not set"); ++ return -EINVAL; ++ } ++ /* TODO: use bitshifts instead of do_div() */ ++ chunk_idx = bno; ++ do_div(chunk_idx, sm->sm_blocks_per_chunk); ++ cib_idx = chunk_idx; ++ chunk_idx = do_div(cib_idx, sm->sm_chunks_per_cib); ++ ++ cib_bno = apfs_spaceman_read_cib_addr(sb, cib_idx); ++ cib_bh = apfs_sb_bread(sb, cib_bno); ++ if (!cib_bh) { ++ apfs_err(sb, "failed to read cib"); ++ return -EIO; ++ } ++ ++ err = apfs_chunk_free(sb, &cib_bh, chunk_idx, bno); ++ if (!err) { ++ /* The cib may have been moved */ ++ apfs_spaceman_write_cib_addr(sb, cib_idx, cib_bh->b_blocknr); ++ /* The free block count has changed */ ++ apfs_write_spaceman(sm); ++ } ++ brelse(cib_bh); ++ if (err) { ++ apfs_err(sb, "error during free"); ++ return err; ++ } ++ ++ /* It may be time to resume orphan cleanups, if we made enough room */ ++ sbi = APFS_SB(sb); ++ orphan_err = atomic_read(&sbi->s_orphan_cleanup_err); ++ if (orphan_err == -ENOSPC && sm->sm_free_count >= 2 * APFS_DEL_ROOM) { ++ atomic_set(&sbi->s_orphan_cleanup_err, 0); ++ apfs_schedule_orphan_cleanup(sb); ++ } ++ ++ return err; ++} ++ ++/** ++ * apfs_spaceman_get_free_blkcnt - Calculate the total number of free blocks ++ * @sb: filesystem superblock ++ * @blkcnt: on return, the total number of free blocks for all devices ++ * ++ * Can be called even if the spaceman has not been read (for example, on a ++ * read-only mount). Returns 0 on success, or a negative error code in case of ++ * failure. ++ */ ++int apfs_spaceman_get_free_blkcnt(struct super_block *sb, u64 *blkcnt) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = NULL; ++ struct apfs_spaceman_phys *sm_raw = NULL; ++ struct apfs_ephemeral_object_info *sm_eph_info = NULL; ++ struct apfs_spaceman_device *dev = NULL; ++ u64 oid; ++ int err; ++ ++ if (!nxi->nx_eph_list) { ++ err = apfs_read_ephemeral_objects(sb); ++ if (err) { ++ apfs_err(sb, "failed to read the ephemeral objects"); ++ return err; ++ } ++ } ++ ++ raw_sb = nxi->nx_raw; ++ oid = le64_to_cpu(raw_sb->nx_spaceman_oid); ++ sm_eph_info = apfs_ephemeral_object_lookup(sb, oid); ++ if (IS_ERR(sm_eph_info)) { ++ apfs_err(sb, "no spaceman object for oid 0x%llx", oid); ++ return PTR_ERR(sm_eph_info); ++ } ++ sm_raw = (struct apfs_spaceman_phys *)sm_eph_info->object; ++ ++ *blkcnt = 0; ++ dev = &sm_raw->sm_dev[APFS_SD_MAIN]; ++ *blkcnt += le64_to_cpu(dev->sm_free_count); ++ dev = &sm_raw->sm_dev[APFS_SD_TIER2]; ++ *blkcnt += le64_to_cpu(dev->sm_free_count); ++ return 0; ++} +diff --git a/fs/apfs/super.c b/fs/apfs/super.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/super.c +@@ -0,0 +1,2127 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "apfs.h" ++#include "version.h" ++ ++#define APFS_MODULE_ID_STRING "linux-apfs by eafer (" GIT_COMMIT ")" ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) /* iversion came in 4.16 */ ++#include ++#endif ++ ++/* Keep a list of mounted containers, so that their volumes can share them */ ++static LIST_HEAD(nxs); ++/* ++ * The main purpose of this mutex is to protect the list of containers and ++ * their reference counts, but it also has other uses during mounts/unmounts: ++ * - it prevents new mounts from starting while an unmount is updating the ++ * backup superblock (apfs_attach_nxi vs apfs_make_super_copy) ++ * - it prevents a new container superblock read from starting while another ++ * is taking place, which could cause leaks and other issues if both ++ * containers are the same (apfs_read_main_super vs itself) ++ * - it protects the list of volumes for each container, and keeps it ++ * consistent with the reference count ++ * - it prevents two different snapshots for a single volume from trying to ++ * do the first read of their shared omap at the same time ++ * (apfs_first_read_omap vs itself) ++ * - it protects the reference count for that shared omap, keeping it ++ * consistent with the number of volumes that are set with that omap ++ * - it protects the container mount flags, so that they can only be set by ++ * the first volume mount to attempt it (apfs_set_nx_flags vs itself) ++ */ ++DEFINE_MUTEX(nxs_mutex); ++ ++/** ++ * apfs_nx_find_by_dev - Search for a device in the list of mounted containers ++ * @dev: device number of block device for the wanted container ++ * ++ * Returns a pointer to the container structure in the list, or NULL if the ++ * container isn't currently mounted. ++ */ ++static struct apfs_nxsb_info *apfs_nx_find_by_dev(dev_t dev) ++{ ++ struct apfs_nxsb_info *curr; ++ ++ lockdep_assert_held(&nxs_mutex); ++ list_for_each_entry(curr, &nxs, nx_list) { ++ struct block_device *curr_bdev = curr->nx_blkdev_info->blki_bdev; ++ ++ if (curr_bdev->bd_dev == dev) ++ return curr; ++ } ++ return NULL; ++} ++ ++/** ++ * apfs_blkdev_set_blocksize - Set the blocksize for a block device ++ * @info: info struct for the block device ++ * @size: size to set ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_blkdev_set_blocksize(struct apfs_blkdev_info *info, int size) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0) ++ return set_blocksize(info->blki_bdev_file, size); ++#else ++ return set_blocksize(info->blki_bdev, size); ++#endif ++} ++ ++/** ++ * apfs_sb_set_blocksize - Set the block size for the container's device ++ * @sb: superblock structure ++ * @size: size to set ++ * ++ * This is like sb_set_blocksize(), but it uses the container's device instead ++ * of the nonexistent volume device. ++ */ ++static int apfs_sb_set_blocksize(struct super_block *sb, int size) ++{ ++ if (apfs_blkdev_set_blocksize(APFS_NXI(sb)->nx_blkdev_info, size)) ++ return 0; ++ sb->s_blocksize = size; ++ sb->s_blocksize_bits = blksize_bits(size); ++ return sb->s_blocksize; ++} ++ ++/** ++ * apfs_read_super_copy - Read the copy of the container superblock in block 0 ++ * @sb: superblock structure ++ * ++ * Returns a pointer to the buffer head, or an error pointer in case of failure. ++ */ ++static struct buffer_head *apfs_read_super_copy(struct super_block *sb) ++{ ++ struct buffer_head *bh; ++ struct apfs_nx_superblock *msb_raw; ++ int blocksize; ++ int err = -EINVAL; ++ ++ /* ++ * For now assume a small blocksize, we only need it so that we can ++ * read the actual blocksize from disk. ++ */ ++ if (!apfs_sb_set_blocksize(sb, APFS_NX_DEFAULT_BLOCK_SIZE)) { ++ apfs_err(sb, "unable to set blocksize"); ++ return ERR_PTR(err); ++ } ++ bh = apfs_sb_bread(sb, APFS_NX_BLOCK_NUM); ++ if (!bh) { ++ apfs_err(sb, "unable to read superblock"); ++ return ERR_PTR(err); ++ } ++ msb_raw = (struct apfs_nx_superblock *)bh->b_data; ++ blocksize = le32_to_cpu(msb_raw->nx_block_size); ++ ++ sb->s_magic = le32_to_cpu(msb_raw->nx_magic); ++ if (sb->s_magic != APFS_NX_MAGIC) { ++ apfs_warn(sb, "not an apfs container - are you mounting the right partition?"); ++ goto fail; ++ } ++ ++ if (sb->s_blocksize != blocksize) { ++ brelse(bh); ++ ++ if (!apfs_sb_set_blocksize(sb, blocksize)) { ++ apfs_err(sb, "bad blocksize %d", blocksize); ++ return ERR_PTR(err); ++ } ++ bh = apfs_sb_bread(sb, APFS_NX_BLOCK_NUM); ++ if (!bh) { ++ apfs_err(sb, "unable to read superblock 2nd time"); ++ return ERR_PTR(err); ++ } ++ msb_raw = (struct apfs_nx_superblock *)bh->b_data; ++ } ++ ++ if (!apfs_obj_verify_csum(sb, bh)) ++ apfs_notice(sb, "backup superblock seems corrupted"); ++ return bh; ++ ++fail: ++ brelse(bh); ++ return ERR_PTR(err); ++} ++ ++/** ++ * apfs_make_super_copy - Write a copy of the checkpoint superblock to block 0 ++ * @sb: superblock structure ++ */ ++static void apfs_make_super_copy(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = sbi->s_nxi; ++ struct buffer_head *bh; ++ ++ if (!(nxi->nx_flags & APFS_READWRITE)) ++ return; ++ ++ /* ++ * Only update the backup when the last volume is getting unmounted. ++ * Of course a new mounter could still come along before we actually ++ * release the nxi. ++ */ ++ mutex_lock(&nxs_mutex); ++ if (nxi->nx_refcnt > 1) ++ goto out_unlock; ++ ++ bh = apfs_sb_bread(sb, APFS_NX_BLOCK_NUM); ++ if (!bh) { ++ apfs_err(sb, "failed to write block zero"); ++ goto out_unlock; ++ } ++ memcpy(bh->b_data, nxi->nx_raw, sb->s_blocksize); ++ mark_buffer_dirty(bh); ++ brelse(bh); ++out_unlock: ++ mutex_unlock(&nxs_mutex); ++} ++ ++static int apfs_check_nx_features(struct super_block *sb); ++static void apfs_set_trans_buffer_limit(struct super_block *sb); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0) ++static inline void import_uuid(uuid_t *dst, const __u8 *src) ++{ ++ memcpy(dst, src, sizeof(uuid_t)); ++} ++#endif ++ ++/** ++ * apfs_check_fusion_uuid - Verify that the main and tier 2 devices match ++ * @sb: filesystem superblock ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_check_fusion_uuid(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = NULL; ++ struct apfs_nx_superblock *main_raw = NULL, *tier2_raw = NULL; ++ uuid_t main_uuid, tier2_uuid; ++ struct buffer_head *bh = NULL; ++ ++ nxi = APFS_NXI(sb); ++ main_raw = nxi->nx_raw; ++ if (!main_raw) { ++ apfs_alert(sb, "fusion uuid checks are misplaced"); ++ return -EINVAL; ++ } ++ import_uuid(&main_uuid, main_raw->nx_fusion_uuid); ++ main_raw = NULL; ++ ++ if (!nxi->nx_tier2_info) { ++ /* Not a fusion drive */ ++ if (!uuid_is_null(&main_uuid)) { ++ apfs_err(sb, "fusion uuid on a regular drive"); ++ return -EFSCORRUPTED; ++ } ++ return 0; ++ } ++ if (uuid_is_null(&main_uuid)) { ++ apfs_err(sb, "no fusion uuid on fusion drive"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* Tier 2 also has a copy of the superblock in block zero */ ++ bh = apfs_sb_bread(sb, nxi->nx_tier2_bno); ++ if (IS_ERR(bh)) ++ return PTR_ERR(bh); ++ tier2_raw = (struct apfs_nx_superblock *)bh->b_data; ++ import_uuid(&tier2_uuid, tier2_raw->nx_fusion_uuid); ++ brelse(bh); ++ bh = NULL; ++ tier2_raw = NULL; ++ ++ /* ++ * The only difference between both superblocks (other than the ++ * checksum) is this one bit here, so it can be used to tell which is ++ * main and which is tier 2. By the way, the reference seems to have ++ * this backwards. ++ */ ++ if (main_uuid.b[15] & 0x01) { ++ apfs_warn(sb, "bad bit on main device - are you mixing up main and tier 2?"); ++ return -EINVAL; ++ } ++ if (!(tier2_uuid.b[15] & 0x01)) { ++ apfs_warn(sb, "bad bit on tier 2 device - are you mixing up main and tier 2?"); ++ return -EINVAL; ++ } ++ tier2_uuid.b[15] &= ~0x01; ++ if (!uuid_equal(&main_uuid, &tier2_uuid)) { ++ apfs_warn(sb, "the devices are not part of the same fusion drive"); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_read_main_super - Find the container superblock and read it into memory ++ * @sb: superblock structure ++ * ++ * Returns a negative error code in case of failure. On success, returns 0 ++ * and sets the nx_raw and nx_xid fields of APFS_NXI(@sb). ++ */ ++static int apfs_read_main_super(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct buffer_head *bh = NULL; ++ struct buffer_head *desc_bh = NULL; ++ struct apfs_nx_superblock *msb_raw; ++ u64 xid, bno = APFS_NX_BLOCK_NUM; ++ u64 desc_base; ++ u32 desc_blocks; ++ int err = -EINVAL; ++ int i; ++ ++ mutex_lock(&nxs_mutex); ++ ++ if (nxi->nx_blocksize) { ++ /* It's already mapped */ ++ sb->s_blocksize = nxi->nx_blocksize; ++ sb->s_blocksize_bits = nxi->nx_blocksize_bits; ++ sb->s_magic = le32_to_cpu(nxi->nx_raw->nx_magic); ++ err = 0; ++ goto out; ++ } ++ ++ /* ++ * We won't know the block size until we read the backup superblock, ++ * so we can't set this up correctly yet. But we do know that the ++ * backup superblock itself is always in the main device. ++ */ ++ nxi->nx_tier2_bno = APFS_NX_BLOCK_NUM + 1; ++ ++ /* Read the superblock from the last clean unmount */ ++ bh = apfs_read_super_copy(sb); ++ if (IS_ERR(bh)) { ++ err = PTR_ERR(bh); ++ bh = NULL; ++ goto out; ++ } ++ msb_raw = (struct apfs_nx_superblock *)bh->b_data; ++ ++ /* ++ * Now that we confirmed the block size, we can set this up for real. ++ * It's important to do this early because I don't know which mount ++ * objects could get moved to tier 2. ++ */ ++ nxi->nx_tier2_bno = APFS_FUSION_TIER2_DEVICE_BYTE_ADDR >> sb->s_blocksize_bits; ++ ++ /* We want to mount the latest valid checkpoint among the descriptors */ ++ desc_base = le64_to_cpu(msb_raw->nx_xp_desc_base); ++ if (desc_base >> 63 != 0) { ++ /* The highest bit is set when checkpoints are not contiguous */ ++ apfs_err(sb, "checkpoint descriptor tree not yet supported"); ++ goto out; ++ } ++ desc_blocks = le32_to_cpu(msb_raw->nx_xp_desc_blocks); ++ if (desc_blocks > 10000) { /* Arbitrary loop limit, is it enough? */ ++ apfs_err(sb, "too many checkpoint descriptors?"); ++ err = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ /* Now we go through the checkpoints one by one */ ++ xid = le64_to_cpu(msb_raw->nx_o.o_xid); ++ for (i = 0; i < desc_blocks; ++i) { ++ struct apfs_nx_superblock *desc_raw; ++ ++ brelse(desc_bh); ++ desc_bh = apfs_sb_bread(sb, desc_base + i); ++ if (!desc_bh) { ++ apfs_err(sb, "unable to read checkpoint descriptor"); ++ goto out; ++ } ++ desc_raw = (struct apfs_nx_superblock *)desc_bh->b_data; ++ ++ if (le32_to_cpu(desc_raw->nx_magic) != APFS_NX_MAGIC) ++ continue; /* Not a superblock */ ++ if (le64_to_cpu(desc_raw->nx_o.o_xid) <= xid) ++ continue; /* Old */ ++ if (!apfs_obj_verify_csum(sb, desc_bh)) ++ continue; /* Corrupted */ ++ ++ xid = le64_to_cpu(desc_raw->nx_o.o_xid); ++ msb_raw = desc_raw; ++ bno = desc_base + i; ++ brelse(bh); ++ bh = desc_bh; ++ desc_bh = NULL; ++ } ++ ++ nxi->nx_raw = kmalloc(sb->s_blocksize, GFP_KERNEL); ++ if (!nxi->nx_raw) { ++ err = -ENOMEM; ++ goto out; ++ } ++ memcpy(nxi->nx_raw, bh->b_data, sb->s_blocksize); ++ nxi->nx_bno = bno; ++ nxi->nx_xid = xid; ++ ++ /* For now we only support blocksize < PAGE_SIZE */ ++ nxi->nx_blocksize = sb->s_blocksize; ++ nxi->nx_blocksize_bits = sb->s_blocksize_bits; ++ apfs_set_trans_buffer_limit(sb); ++ ++ err = apfs_check_nx_features(sb); ++ if (err) ++ goto out; ++ ++ /* ++ * This check is technically too late: if main and tier 2 are backwards ++ * then we have already attempted (and failed) to read the checkpoint ++ * from tier 2. This may lead to a confusing error message if tier 2 ++ * is absurdly tiny, not a big deal. ++ */ ++ err = apfs_check_fusion_uuid(sb); ++ if (err) ++ goto out; ++ ++out: ++ brelse(bh); ++ mutex_unlock(&nxs_mutex); ++ return err; ++} ++ ++/** ++ * apfs_update_software_info - Write the module info to a modified volume ++ * @sb: superblock structure ++ * ++ * Writes this module's information to index zero of the apfs_modified_by ++ * array, shifting the rest of the entries to the right. ++ */ ++static void apfs_update_software_info(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *raw = sbi->s_vsb_raw; ++ struct apfs_modified_by *mod_by; ++ ++ ASSERT(sbi->s_vsb_raw); ++ apfs_assert_in_transaction(sb, &raw->apfs_o); ++ ASSERT(strlen(APFS_MODULE_ID_STRING) < APFS_MODIFIED_NAMELEN); ++ mod_by = raw->apfs_modified_by; ++ ++ memmove(mod_by + 1, mod_by, (APFS_MAX_HIST - 1) * sizeof(*mod_by)); ++ memset(mod_by->id, 0, sizeof(mod_by->id)); ++ strscpy(mod_by->id, APFS_MODULE_ID_STRING, sizeof(mod_by->id)); ++ mod_by->timestamp = cpu_to_le64(ktime_get_real_ns()); ++ mod_by->last_xid = cpu_to_le64(APFS_NXI(sb)->nx_xid); ++} ++ ++static struct file_system_type apfs_fs_type; ++ ++/** ++ * apfs_blkdev_cleanup - Clean up after a block device ++ * @info: info struct to clean up ++ */ ++static void apfs_blkdev_cleanup(struct apfs_blkdev_info *info) ++{ ++ if (!info) ++ return; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) || RHEL_VERSION_GE(9, 5) ++ fput(info->blki_bdev_file); ++ info->blki_bdev_file = NULL; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++ bdev_release(info->blki_bdev_handle); ++ info->blki_bdev_handle = NULL; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) || RHEL_VERSION_GE(9, 4) ++ blkdev_put(info->blki_bdev, &apfs_fs_type); ++#else ++ blkdev_put(info->blki_bdev, info->blki_mode); ++#endif ++ info->blki_bdev = NULL; ++ ++ kfree(info->blki_path); ++ info->blki_path = NULL; ++ kfree(info); ++} ++ ++/** ++ * apfs_free_main_super - Clean up apfs_read_main_super() ++ * @sbi: in-memory superblock info ++ * ++ * It also cleans up after apfs_attach_nxi(), so the name is no longer accurate. ++ */ ++static inline void apfs_free_main_super(struct apfs_sb_info *sbi) ++{ ++ struct apfs_nxsb_info *nxi = sbi->s_nxi; ++ struct apfs_ephemeral_object_info *eph_list = NULL; ++ struct apfs_spaceman *sm = NULL; ++ u32 bmap_idx; ++ int i; ++ ++ mutex_lock(&nxs_mutex); ++ ++ list_del(&sbi->list); ++ if (--nxi->nx_refcnt) ++ goto out; ++ ++ /* Clean up all the ephemeral objects in memory */ ++ eph_list = nxi->nx_eph_list; ++ if (eph_list) { ++ for (i = 0; i < nxi->nx_eph_count; ++i) { ++ kfree(eph_list[i].object); ++ eph_list[i].object = NULL; ++ } ++ kfree(eph_list); ++ eph_list = nxi->nx_eph_list = NULL; ++ nxi->nx_eph_count = 0; ++ } ++ ++ kfree(nxi->nx_raw); ++ nxi->nx_raw = NULL; ++ ++ apfs_blkdev_cleanup(nxi->nx_blkdev_info); ++ nxi->nx_blkdev_info = NULL; ++ apfs_blkdev_cleanup(nxi->nx_tier2_info); ++ nxi->nx_tier2_info = NULL; ++ ++ list_del(&nxi->nx_list); ++ sm = nxi->nx_spaceman; ++ if (sm) { ++ for (bmap_idx = 0; bmap_idx < sm->sm_ip_bmaps_count; ++bmap_idx) { ++ kfree(sm->sm_ip_bmaps[bmap_idx].block); ++ sm->sm_ip_bmaps[bmap_idx].block = NULL; ++ } ++ kfree(sm); ++ nxi->nx_spaceman = sm = NULL; ++ } ++ kfree(nxi); ++out: ++ sbi->s_nxi = NULL; ++ mutex_unlock(&nxs_mutex); ++} ++ ++/** ++ * apfs_map_volume_super_bno - Map a block containing a volume superblock ++ * @sb: superblock structure ++ * @bno: block to map ++ * @check: verify the checksum? ++ */ ++int apfs_map_volume_super_bno(struct super_block *sb, u64 bno, bool check) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = NULL; ++ struct buffer_head *bh = NULL; ++ int err; ++ ++ bh = apfs_sb_bread(sb, bno); ++ if (!bh) { ++ apfs_err(sb, "unable to read volume superblock"); ++ return -EINVAL; ++ } ++ ++ vsb_raw = (struct apfs_superblock *)bh->b_data; ++ if (le32_to_cpu(vsb_raw->apfs_magic) != APFS_MAGIC) { ++ apfs_err(sb, "wrong magic in volume superblock"); ++ err = -EINVAL; ++ goto fail; ++ } ++ ++ /* ++ * XXX: apfs_omap_lookup_block() only runs this check when write ++ * is true, but it should always do it. ++ */ ++ if (check && !apfs_obj_verify_csum(sb, bh)) { ++ apfs_err(sb, "inconsistent volume superblock"); ++ err = -EFSBADCRC; ++ goto fail; ++ } ++ ++ sbi->s_vsb_raw = vsb_raw; ++ sbi->s_vobject.sb = sb; ++ sbi->s_vobject.block_nr = bno; ++ sbi->s_vobject.oid = le64_to_cpu(vsb_raw->apfs_o.o_oid); ++ brelse(sbi->s_vobject.o_bh); ++ sbi->s_vobject.o_bh = bh; ++ sbi->s_vobject.data = bh->b_data; ++ return 0; ++ ++fail: ++ brelse(bh); ++ return err; ++} ++ ++/** ++ * apfs_alloc_omap - Allocate and initialize an object map struct ++ * ++ * Returns the struct, or NULL in case of allocation failure. ++ */ ++static struct apfs_omap *apfs_alloc_omap(void) ++{ ++ struct apfs_omap *omap = NULL; ++ struct apfs_omap_cache *cache = NULL; ++ ++ omap = kzalloc(sizeof(*omap), GFP_KERNEL); ++ if (!omap) ++ return NULL; ++ cache = &omap->omap_cache; ++ spin_lock_init(&cache->lock); ++ return omap; ++} ++ ++/** ++ * apfs_map_volume_super - Find the volume superblock and map it into memory ++ * @sb: superblock structure ++ * @write: request write access? ++ * ++ * Returns a negative error code in case of failure. On success, returns 0 ++ * and sets APFS_SB(@sb)->s_vsb_raw and APFS_SB(@sb)->s_vobject. ++ */ ++int apfs_map_volume_super(struct super_block *sb, bool write) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *msb_raw = nxi->nx_raw; ++ struct apfs_omap_phys *msb_omap_raw; ++ struct apfs_omap *omap = NULL; ++ struct apfs_node *vnode; ++ struct buffer_head *bh; ++ u64 vol_id; ++ u64 vsb; ++ int err; ++ ++ ASSERT(msb_raw); ++ ++ /* Get the id for the requested volume number */ ++ if (sbi->s_vol_nr >= APFS_NX_MAX_FILE_SYSTEMS) { ++ apfs_err(sb, "volume number out of range"); ++ return -EINVAL; ++ } ++ vol_id = le64_to_cpu(msb_raw->nx_fs_oid[sbi->s_vol_nr]); ++ if (vol_id == 0) { ++ apfs_err(sb, "requested volume does not exist"); ++ return -EINVAL; ++ } ++ ++ /* Get the container's object map */ ++ bh = apfs_read_object_block(sb, le64_to_cpu(msb_raw->nx_omap_oid), ++ write, false /* preserve */); ++ if (IS_ERR(bh)) { ++ apfs_err(sb, "unable to read container object map"); ++ return PTR_ERR(bh); ++ } ++ if (write) { ++ ASSERT(buffer_trans(bh)); ++ msb_raw->nx_omap_oid = cpu_to_le64(bh->b_blocknr); ++ } ++ msb_omap_raw = (struct apfs_omap_phys *)bh->b_data; ++ ++ /* Get the root node for the container's omap */ ++ vnode = apfs_read_node(sb, le64_to_cpu(msb_omap_raw->om_tree_oid), ++ APFS_OBJ_PHYSICAL, write); ++ if (IS_ERR(vnode)) { ++ apfs_err(sb, "unable to read volume block"); ++ err = PTR_ERR(vnode); ++ goto fail; ++ } ++ if (write) { ++ ASSERT(buffer_trans(bh)); ++ msb_omap_raw->om_tree_oid = cpu_to_le64(vnode->object.block_nr); ++ } ++ msb_omap_raw = NULL; ++ brelse(bh); ++ bh = NULL; ++ ++ omap = apfs_alloc_omap(); ++ if (!omap) { ++ apfs_node_free(vnode); ++ return -ENOMEM; ++ } ++ omap->omap_root = vnode; ++ ++ err = apfs_omap_lookup_block(sb, omap, vol_id, &vsb, write); ++ apfs_node_free(vnode); ++ vnode = NULL; ++ kfree(omap); ++ omap = NULL; ++ if (err) { ++ apfs_err(sb, "volume not found, likely corruption"); ++ return err; ++ } ++ ++ /* ++ * Snapshots could get mounted during a transaction, so the fletcher ++ * checksum doesn't have to be valid. ++ */ ++ return apfs_map_volume_super_bno(sb, vsb, !write && !sbi->s_snap_name); ++ ++fail: ++ brelse(bh); ++ return err; ++} ++ ++/** ++ * apfs_unmap_volume_super - Clean up apfs_map_volume_super() ++ * @sb: filesystem superblock ++ */ ++void apfs_unmap_volume_super(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_object *obj = &sbi->s_vobject; ++ ++ obj->data = NULL; ++ brelse(obj->o_bh); ++ obj->o_bh = NULL; ++} ++ ++/** ++ * apfs_get_omap - Get a reference to the omap, if it's already read ++ * @sb: filesystem superblock ++ * ++ * Returns the omap struct, or NULL on failure. ++ */ ++static struct apfs_omap *apfs_get_omap(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_sb_info *curr = NULL; ++ struct apfs_omap *omap = NULL; ++ struct apfs_omap_cache *cache = NULL; ++ ++ lockdep_assert_held(&nxs_mutex); ++ ++ list_for_each_entry(curr, &nxi->vol_list, list) { ++ if (curr == sbi) ++ continue; ++ if (curr->s_vol_nr == sbi->s_vol_nr) { ++ omap = curr->s_omap; ++ if (!omap) { ++ /* ++ * This volume has already gone through ++ * apfs_attach_nxi(), but its omap is either ++ * not yet read or already put. ++ */ ++ continue; ++ } ++ cache = &omap->omap_cache; ++ ++omap->omap_refcnt; ++ /* Right now the cache can't be shared like this */ ++ cache->disabled = true; ++ return omap; ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * apfs_read_omap - Find and read the omap root node ++ * @sb: superblock structure ++ * @write: request write access? ++ * ++ * On success, returns 0 and sets the fields of APFS_SB(@sb)->s_omap; on failure ++ * returns a negative error code. ++ */ ++int apfs_read_omap(struct super_block *sb, bool write) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_omap_phys *omap_raw; ++ struct apfs_node *omap_root; ++ struct apfs_omap *omap = NULL; ++ struct buffer_head *bh; ++ u64 omap_blk; ++ int err; ++ ++ ASSERT(sbi->s_vsb_raw); ++ ++ ASSERT(sbi->s_omap); ++ omap = sbi->s_omap; ++ ++ /* Get the block holding the volume omap information */ ++ omap_blk = le64_to_cpu(vsb_raw->apfs_omap_oid); ++ bh = apfs_read_object_block(sb, omap_blk, write, false /* preserve */); ++ if (IS_ERR(bh)) { ++ apfs_err(sb, "unable to read the volume object map"); ++ return PTR_ERR(bh); ++ } ++ if (write) { ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ vsb_raw->apfs_omap_oid = cpu_to_le64(bh->b_blocknr); ++ } ++ omap_raw = (struct apfs_omap_phys *)bh->b_data; ++ ++ /* Get the volume's object map */ ++ omap_root = apfs_read_node(sb, le64_to_cpu(omap_raw->om_tree_oid), ++ APFS_OBJ_PHYSICAL, write); ++ if (IS_ERR(omap_root)) { ++ apfs_err(sb, "unable to read the omap root node"); ++ err = PTR_ERR(omap_root); ++ goto fail; ++ } ++ if (write) { ++ apfs_assert_in_transaction(sb, &omap_raw->om_o); ++ ASSERT(buffer_trans(bh)); ++ omap_raw->om_tree_oid = cpu_to_le64(omap_root->object.block_nr); ++ } ++ omap->omap_latest_snap = le64_to_cpu(omap_raw->om_most_recent_snap); ++ omap_raw = NULL; ++ brelse(bh); ++ ++ if (omap->omap_root) ++ apfs_node_free(omap->omap_root); ++ omap->omap_root = omap_root; ++ return 0; ++ ++fail: ++ brelse(bh); ++ return err; ++} ++ ++/** ++ * apfs_first_read_omap - Find and read the omap root node during mount ++ * @sb: superblock structure ++ * ++ * On success, returns 0 and sets APFS_SB(@sb)->s_omap; on failure returns a ++ * negative error code. ++ */ ++static int apfs_first_read_omap(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = NULL; ++ struct apfs_omap *omap = NULL; ++ int err; ++ ++ /* ++ * For each volume, the first mount that gets here is responsible ++ * for reading the omap. Other mounts (for other snapshots) just ++ * go through the container's volume list to retrieve it. This results ++ * in coarse locking as usual: with some thought it would be possible ++ * to allow other volumes to read their own omaps at the same time, ++ * but I don't see the point. ++ */ ++ mutex_lock(&nxs_mutex); ++ ++ sbi = APFS_SB(sb); ++ ++ /* The current transaction and all snapshots share a single omap */ ++ omap = apfs_get_omap(sb); ++ if (omap) { ++ sbi->s_omap = omap; ++ err = 0; ++ goto out; ++ } ++ ++ omap = apfs_alloc_omap(); ++ if (!omap) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ sbi->s_omap = omap; ++ err = apfs_read_omap(sb, false /* write */); ++ if (err) { ++ kfree(omap); ++ sbi->s_omap = NULL; ++ goto out; ++ } ++ ++ ++omap->omap_refcnt; ++ err = 0; ++out: ++ mutex_unlock(&nxs_mutex); ++ return err; ++} ++ ++/** ++ * apfs_unset_omap - Unset the object map in a superblock ++ * @sb: superblock structure ++ * ++ * Shrinks the omap reference, frees the omap if needed, and sets the field to ++ * NULL atomically in relation to apfs_first_read_omap(). So, no other mount ++ * can grab a new reference halfway through. ++ */ ++static void apfs_unset_omap(struct super_block *sb) ++{ ++ struct apfs_omap **omap_p = NULL; ++ struct apfs_omap *omap = NULL; ++ ++ omap_p = &APFS_SB(sb)->s_omap; ++ omap = *omap_p; ++ if (!omap) ++ return; ++ ++ mutex_lock(&nxs_mutex); ++ ++ if (--omap->omap_refcnt != 0) ++ goto out; ++ ++ apfs_node_free(omap->omap_root); ++ kfree(omap); ++out: ++ *omap_p = NULL; ++ mutex_unlock(&nxs_mutex); ++} ++ ++/** ++ * apfs_read_catalog - Find and read the catalog root node ++ * @sb: superblock structure ++ * @write: request write access? ++ * ++ * On success, returns 0 and sets APFS_SB(@sb)->s_cat_root; on failure returns ++ * a negative error code. ++ */ ++int apfs_read_catalog(struct super_block *sb, bool write) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_superblock *vsb_raw = sbi->s_vsb_raw; ++ struct apfs_node *root_node; ++ ++ ASSERT(sbi->s_omap && sbi->s_omap->omap_root); ++ ++ root_node = apfs_read_node(sb, le64_to_cpu(vsb_raw->apfs_root_tree_oid), ++ APFS_OBJ_VIRTUAL, write); ++ if (IS_ERR(root_node)) { ++ apfs_err(sb, "unable to read catalog root node"); ++ return PTR_ERR(root_node); ++ } ++ ++ if (sbi->s_cat_root) ++ apfs_node_free(sbi->s_cat_root); ++ sbi->s_cat_root = root_node; ++ return 0; ++} ++ ++static void apfs_put_super(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nx_transaction *trans = NULL; ++ ++ /* Cleanups won't reschedule themselves during unmount */ ++ flush_work(&sbi->s_orphan_cleanup_work); ++ ++ /* We are about to commit anyway */ ++ trans = &APFS_NXI(sb)->nx_transaction; ++ cancel_delayed_work_sync(&trans->t_work); ++ ++ /* Stop flushing orphans and update the volume as needed */ ++ if (!(sb->s_flags & SB_RDONLY)) { ++ struct apfs_superblock *vsb_raw; ++ struct buffer_head *vsb_bh; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_SYNC); ++ if (err) { ++ apfs_err(sb, "unmount transaction start failed (err:%d)", err); ++ goto fail; ++ } ++ vsb_raw = sbi->s_vsb_raw; ++ vsb_bh = sbi->s_vobject.o_bh; ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ ASSERT(buffer_trans(vsb_bh)); ++ ++ apfs_update_software_info(sb); ++ vsb_raw->apfs_unmount_time = cpu_to_le64(ktime_get_real_ns()); ++ set_buffer_csum(vsb_bh); ++ ++ /* Guarantee commit */ ++ sbi->s_nxi->nx_transaction.t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) { ++ apfs_err(sb, "unmount transaction commit failed (err:%d)", err); ++ apfs_transaction_abort(sb); ++ goto fail; ++ } ++ } ++ ++ /* ++ * Even if this particular volume/snapshot was read-only, the container ++ * may have changed and need an update here. ++ */ ++ apfs_make_super_copy(sb); ++ ++fail: ++ /* ++ * This is essentially the cleanup for apfs_fill_super(). It goes here ++ * because generic_shutdown_super() only calls ->put_super() when the ++ * root dentry has been set, that is, when apfs_fill_super() succeeded. ++ * The rest of the mount cleanup is done directly by ->kill_sb(). ++ */ ++ iput(sbi->s_private_dir); ++ sbi->s_private_dir = NULL; ++ apfs_node_free(sbi->s_cat_root); ++ sbi->s_cat_root = NULL; ++ apfs_unset_omap(sb); ++ apfs_unmap_volume_super(sb); ++} ++ ++static struct kmem_cache *apfs_inode_cachep; ++ ++static struct inode *apfs_alloc_inode(struct super_block *sb) ++{ ++ struct apfs_inode_info *ai; ++ struct apfs_dstream_info *dstream; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || RHEL_VERSION_GE(9, 1) ++ ai = alloc_inode_sb(sb, apfs_inode_cachep, GFP_KERNEL); ++#else ++ ai = kmem_cache_alloc(apfs_inode_cachep, GFP_KERNEL); ++#endif ++ if (!ai) ++ return NULL; ++ dstream = &ai->i_dstream; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) /* iversion came in 4.16 */ ++ inode_set_iversion(&ai->vfs_inode, 1); ++#else ++ ai->vfs_inode.i_version = 1; ++#endif ++ dstream->ds_sb = sb; ++ dstream->ds_inode = &ai->vfs_inode; ++ dstream->ds_cached_ext.len = 0; ++ dstream->ds_ext_dirty = false; ++ ai->i_nchildren = 0; ++ INIT_LIST_HEAD(&ai->i_list); ++ ai->i_cleaned = false; ++ return &ai->vfs_inode; ++} ++ ++static void apfs_i_callback(struct rcu_head *head) ++{ ++ struct inode *inode = container_of(head, struct inode, i_rcu); ++ ++ kmem_cache_free(apfs_inode_cachep, APFS_I(inode)); ++} ++ ++static void apfs_destroy_inode(struct inode *inode) ++{ ++ call_rcu(&inode->i_rcu, apfs_i_callback); ++} ++ ++static void init_once(void *p) ++{ ++ struct apfs_inode_info *ai = (struct apfs_inode_info *)p; ++ struct apfs_dstream_info *dstream = &ai->i_dstream; ++ ++ spin_lock_init(&dstream->ds_ext_lock); ++ inode_init_once(&ai->vfs_inode); ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) ++#define SLAB_MEM_SPREAD 0 ++#endif ++ ++static int __init init_inodecache(void) ++{ ++ apfs_inode_cachep = kmem_cache_create("apfs_inode_cache", ++ sizeof(struct apfs_inode_info), ++ 0, (SLAB_RECLAIM_ACCOUNT| ++ SLAB_MEM_SPREAD|SLAB_ACCOUNT), ++ init_once); ++ if (apfs_inode_cachep == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++static int apfs_write_inode(struct inode *inode, struct writeback_control *wbc) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_nxsb_info *nxi = APFS_SB(sb)->s_nxi; ++ int err; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_REG); ++ if (err) ++ return err; ++ err = apfs_update_inode(inode, NULL /* new_name */); ++ if (err) ++ goto fail; ++ /* Don't commit yet, or the inode will get flushed again and lock up */ ++ nxi->nx_transaction.t_state |= APFS_NX_TRANS_DEFER_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) ++ goto fail; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++static void destroy_inodecache(void) ++{ ++ /* ++ * Make sure all delayed rcu free inodes are flushed before we ++ * destroy cache. ++ */ ++ rcu_barrier(); ++ kmem_cache_destroy(apfs_inode_cachep); ++} ++ ++static int apfs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ struct super_block *sb = dentry->d_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *msb_raw; ++ struct apfs_superblock *vol; ++ u64 fsid, free_blocks; ++ int err; ++ ++ down_read(&nxi->nx_big_sem); ++ msb_raw = nxi->nx_raw; ++ vol = sbi->s_vsb_raw; ++ ++ buf->f_type = APFS_NX_MAGIC; ++ /* Nodes are assumed to fit in a page, for now */ ++ buf->f_bsize = sb->s_blocksize; ++ ++ /* Volumes share the whole disk space */ ++ buf->f_blocks = le64_to_cpu(msb_raw->nx_block_count); ++ /* ++ * It takes some work to retrieve the free block count because we ++ * can't assume that the spaceman has been read yet. It would be ++ * cleaner if we always did that on first mount (TODO). ++ */ ++ err = apfs_spaceman_get_free_blkcnt(sb, &free_blocks); ++ if (err) ++ goto fail; ++ buf->f_bfree = free_blocks; ++ buf->f_bavail = free_blocks; ++ ++ /* The file count is only for the mounted volume */ ++ buf->f_files = le64_to_cpu(vol->apfs_num_files) + ++ le64_to_cpu(vol->apfs_num_directories) + ++ le64_to_cpu(vol->apfs_num_symlinks) + ++ le64_to_cpu(vol->apfs_num_other_fsobjects); ++ ++ /* ++ * buf->f_ffree is left undefined for now. Maybe it should report the ++ * number of available cnids, like hfsplus attempts to do. ++ */ ++ ++ buf->f_namelen = APFS_NAME_LEN; ++ ++ /* There are no clear rules for the fsid, so we follow ext2 here */ ++ fsid = le64_to_cpup((void *)vol->apfs_vol_uuid) ^ ++ le64_to_cpup((void *)vol->apfs_vol_uuid + sizeof(u64)); ++ buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; ++ buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; ++ ++fail: ++ up_read(&nxi->nx_big_sem); ++ return err; ++} ++ ++static int apfs_show_options(struct seq_file *seq, struct dentry *root) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(root->d_sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(root->d_sb); ++ ++ if (sbi->s_vol_nr != 0) ++ seq_printf(seq, ",vol=%u", sbi->s_vol_nr); ++ if (sbi->s_snap_name) ++ seq_printf(seq, ",snap=%s", sbi->s_snap_name); ++ if (uid_valid(sbi->s_uid)) ++ seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, ++ sbi->s_uid)); ++ if (gid_valid(sbi->s_gid)) ++ seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, ++ sbi->s_gid)); ++ if (nxi->nx_flags & APFS_CHECK_NODES) ++ seq_puts(seq, ",cknodes"); ++ if (nxi->nx_tier2_info) ++ seq_printf(seq, ",tier2=%s", nxi->nx_tier2_info->blki_path); ++ ++ return 0; ++} ++ ++int apfs_sync_fs(struct super_block *sb, int wait) ++{ ++ int err; ++ ++ /* TODO: actually start the commit and return without waiting? */ ++ if (wait == 0) ++ return 0; ++ ++ err = apfs_transaction_start(sb, APFS_TRANS_SYNC); ++ if (err) ++ return err; ++ APFS_SB(sb)->s_nxi->nx_transaction.t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/* Only supports read-only remounts, everything else is silently ignored */ ++static int apfs_remount(struct super_block *sb, int *flags, char *data) ++{ ++ int err = 0; ++ ++ err = sync_filesystem(sb); ++ if (err) ++ return err; ++ ++ /* TODO: race? Could a new transaction have started already? */ ++ if (*flags & SB_RDONLY) ++ sb->s_flags |= SB_RDONLY; ++ ++ /* ++ * TODO: readwrite remounts seem simple enough, but I worry about ++ * remounting aborted transactions. I would probably also need a ++ * dry-run version of parse_options(). ++ */ ++ apfs_notice(sb, "all remounts can do is turn a volume read-only"); ++ return 0; ++} ++ ++static const struct super_operations apfs_sops = { ++ .alloc_inode = apfs_alloc_inode, ++ .destroy_inode = apfs_destroy_inode, ++ .write_inode = apfs_write_inode, ++ .evict_inode = apfs_evict_inode, ++ .put_super = apfs_put_super, ++ .sync_fs = apfs_sync_fs, ++ .statfs = apfs_statfs, ++ .remount_fs = apfs_remount, ++ .show_options = apfs_show_options, ++}; ++ ++enum { ++ Opt_readwrite, Opt_cknodes, Opt_uid, Opt_gid, Opt_vol, Opt_snap, Opt_tier2, Opt_err, ++}; ++ ++static const match_table_t tokens = { ++ {Opt_readwrite, "readwrite"}, ++ {Opt_cknodes, "cknodes"}, ++ {Opt_uid, "uid=%u"}, ++ {Opt_gid, "gid=%u"}, ++ {Opt_vol, "vol=%u"}, ++ {Opt_snap, "snap=%s"}, ++ {Opt_tier2, "tier2=%s"}, ++ {Opt_err, NULL} ++}; ++ ++/** ++ * apfs_set_nx_flags - Set the mount flags for the container, if allowed ++ * @sb: superblock structure ++ * @flags: flags to set ++ */ ++static void apfs_set_nx_flags(struct super_block *sb, unsigned int flags) ++{ ++ struct apfs_nxsb_info *nxi = APFS_SB(sb)->s_nxi; ++ ++ mutex_lock(&nxs_mutex); ++ ++ /* The first mount thet gets here decides the flags for its container */ ++ flags |= APFS_FLAGS_SET; ++ if (!(nxi->nx_flags & APFS_FLAGS_SET)) ++ nxi->nx_flags = flags; ++ else if (flags != nxi->nx_flags) ++ apfs_warn(sb, "ignoring mount flags - container already mounted"); ++ ++ mutex_unlock(&nxs_mutex); ++} ++ ++/* ++ * Many of the parse_options() functions in other file systems return 0 ++ * on error. This one returns an error code, and 0 on success. ++ */ ++static int parse_options(struct super_block *sb, char *options) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = sbi->s_nxi; ++ char *p; ++ substring_t args[MAX_OPT_ARGS]; ++ int option; ++ int err = 0; ++ unsigned int nx_flags; ++ ++ /* Set default values before parsing */ ++ nx_flags = 0; ++ ++#ifdef CONFIG_APFS_RW_ALWAYS ++ /* Still risky, but some packagers want writable mounts by default */ ++ nx_flags |= APFS_READWRITE; ++#endif ++ ++ if (!options) ++ goto out; ++ ++ while ((p = strsep(&options, ",")) != NULL) { ++ int token; ++ ++ if (!*p) ++ continue; ++ token = match_token(p, tokens, args); ++ switch (token) { ++ case Opt_readwrite: ++ /* ++ * Write support is not safe yet, so keep it disabled ++ * unless the user requests it explicitly. ++ */ ++ nx_flags |= APFS_READWRITE; ++ break; ++ case Opt_cknodes: ++ /* ++ * Right now, node checksums are too costly to enable ++ * by default. TODO: try to improve this. ++ */ ++ nx_flags |= APFS_CHECK_NODES; ++ break; ++ case Opt_uid: ++ err = match_int(&args[0], &option); ++ if (err) ++ return err; ++ sbi->s_uid = make_kuid(current_user_ns(), option); ++ if (!uid_valid(sbi->s_uid)) { ++ apfs_err(sb, "invalid uid"); ++ return -EINVAL; ++ } ++ break; ++ case Opt_gid: ++ err = match_int(&args[0], &option); ++ if (err) ++ return err; ++ sbi->s_gid = make_kgid(current_user_ns(), option); ++ if (!gid_valid(sbi->s_gid)) { ++ apfs_err(sb, "invalid gid"); ++ return -EINVAL; ++ } ++ break; ++ case Opt_vol: ++ case Opt_snap: ++ case Opt_tier2: ++ /* Already read early on mount */ ++ break; ++ default: ++ /* ++ * We should have already checked the mount options in ++ * apfs_preparse_options(), so this is a bug. ++ */ ++ apfs_alert(sb, "invalid mount option %s", p); ++ return -EINVAL; ++ } ++ } ++ ++out: ++ apfs_set_nx_flags(sb, nx_flags); ++ if (!(sb->s_flags & SB_RDONLY)) { ++ if (nxi->nx_flags & APFS_READWRITE) { ++ apfs_notice(sb, "experimental write support is enabled"); ++ } else { ++ apfs_warn(sb, "experimental writes disabled to avoid data loss"); ++ apfs_warn(sb, "if you really want them, check the README"); ++ sb->s_flags |= SB_RDONLY; ++ } ++ } ++ return 0; ++} ++ ++/** ++ * apfs_check_nx_features - Check for unsupported features in the container ++ * @sb: superblock structure ++ * ++ * Returns -EINVAL if unsupported incompatible features are found, otherwise ++ * returns 0. ++ */ ++static int apfs_check_nx_features(struct super_block *sb) ++{ ++ struct apfs_nx_superblock *msb_raw = NULL; ++ u64 features; ++ bool fusion; ++ ++ msb_raw = APFS_NXI(sb)->nx_raw; ++ if (!msb_raw) { ++ apfs_alert(sb, "feature checks are misplaced"); ++ return -EINVAL; ++ } ++ ++ features = le64_to_cpu(msb_raw->nx_incompatible_features); ++ if (features & ~APFS_NX_SUPPORTED_INCOMPAT_MASK) { ++ apfs_warn(sb, "unknown incompatible container features (0x%llx)", features); ++ return -EINVAL; ++ } ++ ++ fusion = features & APFS_NX_INCOMPAT_FUSION; ++ if (fusion && !APFS_NXI(sb)->nx_tier2_info) { ++ apfs_warn(sb, "fusion drive - please use the \"tier2\" mount option"); ++ return -EINVAL; ++ } ++ if (!fusion && APFS_NXI(sb)->nx_tier2_info) { ++ apfs_warn(sb, "not a fusion drive - what's the second disk for?"); ++ return -EINVAL; ++ } ++ if (fusion) { ++ if (!sb_rdonly(sb)) { ++ apfs_warn(sb, "writes to fusion drives not yet supported"); ++ sb->s_flags |= SB_RDONLY; ++ } ++ } ++ ++ features = le64_to_cpu(msb_raw->nx_readonly_compatible_features); ++ if (features & ~APFS_NX_SUPPORTED_ROCOMPAT_MASK) { ++ apfs_warn(sb, "unknown read-only compatible container features (0x%llx)", features); ++ if (!sb_rdonly(sb)) { ++ apfs_warn(sb, "container can't be mounted read-write"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/** ++ * apfs_check_vol_features - Check for unsupported features in the volume ++ * @sb: superblock structure ++ * ++ * Returns -EINVAL if unsupported incompatible features are found, otherwise ++ * returns 0. ++ */ ++static int apfs_check_vol_features(struct super_block *sb) ++{ ++ struct apfs_superblock *vsb_raw = NULL; ++ u64 features; ++ ++ vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ if (!vsb_raw) { ++ apfs_alert(sb, "feature checks are misplaced"); ++ return -EINVAL; ++ } ++ ++ features = le64_to_cpu(vsb_raw->apfs_incompatible_features); ++ if (features & ~APFS_SUPPORTED_INCOMPAT_MASK) { ++ apfs_warn(sb, "unknown incompatible volume features (0x%llx)", features); ++ return -EINVAL; ++ } ++ if (features & APFS_INCOMPAT_DATALESS_SNAPS) { ++ /* ++ * I haven't encountered dataless snapshots myself yet (TODO). ++ * I'm not even sure what they are, so be safe. ++ */ ++ if (!sb_rdonly(sb)) { ++ apfs_warn(sb, "writes to volumes with dataless snapshots not yet supported"); ++ return -EINVAL; ++ } ++ apfs_warn(sb, "volume has dataless snapshots"); ++ } ++ if (features & APFS_INCOMPAT_ENC_ROLLED) { ++ apfs_warn(sb, "encrypted volumes are not supported"); ++ return -EINVAL; ++ } ++ if (features & APFS_INCOMPAT_INCOMPLETE_RESTORE) { ++ apfs_warn(sb, "incomplete restore is not supported"); ++ return -EINVAL; ++ } ++ if (features & APFS_INCOMPAT_PFK) { ++ apfs_warn(sb, "PFK is not supported"); ++ return -EINVAL; ++ } ++ if (features & APFS_INCOMPAT_SECONDARY_FSROOT) { ++ apfs_warn(sb, "secondary fsroot is not supported"); ++ return -EINVAL; ++ } ++ if (features & APFS_INCOMPAT_SEALED_VOLUME) { ++ if (!sb_rdonly(sb)) { ++ apfs_warn(sb, "writes to sealed volumes are not yet supported"); ++ return -EINVAL; ++ } ++ apfs_info(sb, "volume is sealed"); ++ } ++ /* ++ * As far as I can see, all this feature seems to do is define a new ++ * flag (which I call APFS_FILE_EXTENT_PREALLOCATED) for extents that ++ * are fully after the end of their file. I don't get why this change ++ * is incompatible instead of read-only compatible, so I fear I might ++ * be missing something. I will never be certain though, so for now ++ * allow the mount and hope for the best. ++ */ ++ if (features & APFS_INCOMPAT_EXTENT_PREALLOC_FLAG) ++ apfs_warn(sb, "extent prealloc flag is set"); ++ ++ features = le64_to_cpu(vsb_raw->apfs_fs_flags); ++ /* Some encrypted volumes are readable anyway */ ++ if (!(features & APFS_FS_UNENCRYPTED)) ++ apfs_warn(sb, "volume is encrypted, may not be read correctly"); ++ ++ features = le64_to_cpu(vsb_raw->apfs_readonly_compatible_features); ++ if (features & ~APFS_SUPPORTED_ROCOMPAT_MASK) { ++ apfs_warn(sb, "unknown read-only compatible volume features (0x%llx)", features); ++ if (!sb_rdonly(sb)) { ++ apfs_warn(sb, "volume can't be mounted read-write"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) ++ ++/** ++ * apfs_setup_bdi - Set up the bdi for the superblock ++ * @sb: superblock structure ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_setup_bdi(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_blkdev_info *bd_info = NULL; ++ struct backing_dev_info *bdi_dev = NULL, *bdi_sb = NULL; ++ int err; ++ ++ bd_info = nxi->nx_blkdev_info; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) || RHEL_VERSION_GE(9, 0) ++ bdi_dev = bd_info->blki_bdev->bd_disk->bdi; ++#else ++ bdi_dev = bd_info->blki_bdev->bd_bdi; ++#endif ++ ++ err = super_setup_bdi(sb); ++ if (err) ++ return err; ++ bdi_sb = sb->s_bdi; ++ ++ bdi_sb->ra_pages = bdi_dev->ra_pages; ++ bdi_sb->io_pages = bdi_dev->io_pages; ++ ++ bdi_sb->capabilities = bdi_dev->capabilities; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) ++ bdi_sb->capabilities &= ~BDI_CAP_WRITEBACK; ++#else ++ bdi_sb->capabilities |= BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY; ++#endif ++ ++ return 0; ++} ++ ++#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ ++ ++/* This is needed for readahead, so old kernels will be slower */ ++static int apfs_setup_bdi(struct super_block *sb) ++{ ++ return 0; ++} ++ ++#endif ++ ++static void apfs_set_trans_buffer_limit(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ unsigned long memsize_in_blocks; ++ struct sysinfo info = {0}; ++ ++ si_meminfo(&info); ++ memsize_in_blocks = info.totalram << (PAGE_SHIFT - sb->s_blocksize_bits); ++ ++ /* ++ * Buffer heads are not reclaimed while they are part of the current ++ * transaction, so systems with little memory will crash if we don't ++ * commit often enough. This hack should make that happen in general, ++ * but I still need to get the reclaim to work eventually (TODO). ++ */ ++ if (memsize_in_blocks >= 16 * APFS_TRANS_BUFFERS_MAX) ++ nxi->nx_trans_buffers_max = APFS_TRANS_BUFFERS_MAX; ++ else ++ nxi->nx_trans_buffers_max = memsize_in_blocks / 16; ++} ++ ++static int apfs_fill_super(struct super_block *sb, void *data, int silent) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct inode *root = NULL, *priv = NULL; ++ int err; ++ ++ /* ++ * This function doesn't write anything to disk, that happens later ++ * when an actual transaction begins. So, it's not generally a problem ++ * if other mounts for the same container fill their own supers at the ++ * same time (the few critical sections will be protected by ++ * nxs_mutex), nor is it a problem if other mounted volumes want to ++ * make reads while the mount is taking place. But we definitely don't ++ * want any writes, or else we could find ourselves reading stale ++ * blocks after CoW, among other issues. ++ */ ++ down_read(&APFS_NXI(sb)->nx_big_sem); ++ ++ err = apfs_setup_bdi(sb); ++ if (err) ++ goto failed_volume; ++ ++ sbi->s_uid = INVALID_UID; ++ sbi->s_gid = INVALID_GID; ++ err = parse_options(sb, data); ++ if (err) ++ goto failed_volume; ++ ++ err = apfs_map_volume_super(sb, false /* write */); ++ if (err) ++ goto failed_volume; ++ ++ err = apfs_check_vol_features(sb); ++ if (err) ++ goto failed_omap; ++ ++ /* ++ * The omap needs to be set before the call to apfs_read_catalog(). ++ * It's also shared with all the snapshots, so it needs to be read ++ * before we switch to the old superblock. ++ */ ++ err = apfs_first_read_omap(sb); ++ if (err) ++ goto failed_omap; ++ ++ if (sbi->s_snap_name) { ++ err = apfs_switch_to_snapshot(sb); ++ if (err) ++ goto failed_cat; ++ } ++ ++ err = apfs_read_catalog(sb, false /* write */); ++ if (err) ++ goto failed_cat; ++ ++ sb->s_op = &apfs_sops; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) ++ set_default_d_op(sb, &apfs_dentry_operations); ++#else ++ sb->s_d_op = &apfs_dentry_operations; ++#endif ++ sb->s_xattr = apfs_xattr_handlers; ++ sb->s_maxbytes = MAX_LFS_FILESIZE; ++ sb->s_time_gran = 1; /* Nanosecond granularity */ ++ ++ /* ++ * At this point everything is already set up for the inode reads, ++ * which take care of their own locking as always. ++ */ ++ up_read(&APFS_NXI(sb)->nx_big_sem); ++ ++ sbi->s_private_dir = apfs_iget(sb, APFS_PRIV_DIR_INO_NUM); ++ if (IS_ERR(sbi->s_private_dir)) { ++ apfs_err(sb, "unable to get private-dir inode"); ++ err = PTR_ERR(sbi->s_private_dir); ++ goto failed_private_dir; ++ } ++ ++ root = apfs_iget(sb, APFS_ROOT_DIR_INO_NUM); ++ if (IS_ERR(root)) { ++ apfs_err(sb, "unable to get root inode"); ++ err = PTR_ERR(root); ++ goto failed_mount; ++ } ++ ++ sb->s_root = d_make_root(root); ++ if (!sb->s_root) { ++ apfs_err(sb, "unable to get root dentry"); ++ err = -ENOMEM; ++ goto failed_mount; ++ } ++ ++ INIT_WORK(&sbi->s_orphan_cleanup_work, apfs_orphan_cleanup_work); ++ if (!(sb->s_flags & SB_RDONLY)) { ++ priv = sbi->s_private_dir; ++ if (APFS_I(priv)->i_nchildren) ++ schedule_work(&sbi->s_orphan_cleanup_work); ++ } ++ return 0; ++ ++failed_mount: ++ iput(sbi->s_private_dir); ++failed_private_dir: ++ sbi->s_private_dir = NULL; ++ down_read(&APFS_NXI(sb)->nx_big_sem); ++ apfs_node_free(sbi->s_cat_root); ++failed_cat: ++ apfs_unset_omap(sb); ++failed_omap: ++ apfs_unmap_volume_super(sb); ++failed_volume: ++ up_read(&APFS_NXI(sb)->nx_big_sem); ++ return err; ++} ++ ++/** ++ * apfs_strings_are_equal - Compare two possible NULL strings ++ * @str1: the first string ++ * @str2: the second string ++ */ ++static bool apfs_strings_are_equal(const char *str1, const char *str2) ++{ ++ if (str1 == str2) /* Both are NULL */ ++ return true; ++ if (!str1 || !str2) /* One is NULL */ ++ return false; ++ return strcmp(str1, str2) == 0; ++} ++ ++/** ++ * apfs_test_super - Check if two volume superblocks are for the same volume ++ * @sb: superblock structure for a currently mounted volume ++ * @data: superblock info for the volume being mounted ++ */ ++static int apfs_test_super(struct super_block *sb, void *data) ++{ ++ struct apfs_sb_info *sbi_1 = data; ++ struct apfs_sb_info *sbi_2 = APFS_SB(sb); ++ ++ if (sbi_1->s_nxi != sbi_2->s_nxi) ++ return false; ++ if (sbi_1->s_vol_nr != sbi_2->s_vol_nr) ++ return false; ++ return apfs_strings_are_equal(sbi_1->s_snap_name, sbi_2->s_snap_name); ++} ++ ++/** ++ * apfs_set_super - Assign the device and an info struct to a superblock ++ * @sb: superblock structure to set ++ * @data: superblock info for the volume being mounted ++ */ ++static int apfs_set_super(struct super_block *sb, void *data) ++{ ++ struct apfs_sb_info *sbi = data; ++ struct apfs_nxsb_info *nxi = sbi->s_nxi; ++ int err; ++ ++ /* ++ * This fake device number will be unique to this volume-snapshot ++ * combination. It gets reported by stat(), so that userland tools can ++ * use it to tell different mountpoints apart. ++ */ ++ err = get_anon_bdev(&sbi->s_anon_dev); ++ if (err) ++ return err; ++ ++ /* ++ * This is the actual device number, shared by all volumes and ++ * snapshots. It gets reported by the mountinfo file, and it seems that ++ * udisks uses it to decide if a device is mounted, so it must be set. ++ * ++ * TODO: does this work for fusion drives? ++ */ ++ sb->s_dev = nxi->nx_blkdev_info->blki_bdev->bd_dev; ++ ++ sb->s_fs_info = sbi; ++ return 0; ++} ++ ++/* ++ * Wrapper for lookup_bdev() that supports older kernels. ++ */ ++static int apfs_lookup_bdev(const char *pathname, dev_t *dev) ++{ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) ++ struct block_device *bdev; ++ ++ bdev = lookup_bdev(pathname); ++ if (IS_ERR(bdev)) ++ return PTR_ERR(bdev); ++ ++ *dev = bdev->bd_dev; ++ bdput(bdev); ++ return 0; ++#else ++ return lookup_bdev(pathname, dev); ++#endif ++} ++ ++/** ++ * apfs_blkdev_setup - Open a block device and set its info struct ++ * @info_p: info struct to set ++ * @dev_name: path name for the block device to open ++ * @mode: FMODE_* mask ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) ++static int apfs_blkdev_setup(struct apfs_blkdev_info **info_p, const char *dev_name, blk_mode_t mode) ++#else ++static int apfs_blkdev_setup(struct apfs_blkdev_info **info_p, const char *dev_name, fmode_t mode) ++#endif ++{ ++ struct apfs_blkdev_info *info = NULL; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) || RHEL_VERSION_GE(9, 5) ++ struct file *file = NULL; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++ struct bdev_handle *handle = NULL; ++#endif ++ struct block_device *bdev = NULL; ++ int ret; ++ ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ info->blki_path = kstrdup(dev_name, GFP_KERNEL); ++ if (!info->blki_path) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) || RHEL_VERSION_GE(9, 5) ++ file = bdev_file_open_by_path(dev_name, mode, &apfs_fs_type, NULL); ++ if (IS_ERR(file)) { ++ ret = PTR_ERR(file); ++ goto fail; ++ } ++ info->blki_bdev_file = file; ++ bdev = file_bdev(file); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0) ++ handle = bdev_open_by_path(dev_name, mode, &apfs_fs_type, NULL); ++ if (IS_ERR(handle)) { ++ ret = PTR_ERR(handle); ++ goto fail; ++ } ++ info->blki_bdev_handle = handle; ++ bdev = handle->bdev; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) || RHEL_VERSION_GE(9, 4) ++ bdev = blkdev_get_by_path(dev_name, mode, &apfs_fs_type, NULL); ++#else ++ bdev = blkdev_get_by_path(dev_name, mode, &apfs_fs_type); ++#endif ++ ++ if (IS_ERR(bdev)) { ++ ret = PTR_ERR(bdev); ++ goto fail; ++ } ++ info->blki_bdev = bdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) && !RHEL_VERSION_GE(9, 4) ++ info->blki_mode = mode; ++#endif ++ *info_p = info; ++ return 0; ++ ++fail: ++ kfree(info->blki_path); ++ info->blki_path = NULL; ++ kfree(info); ++ info = NULL; ++ return ret; ++} ++ ++/** ++ * apfs_attach_nxi - Attach container sb info to a volume's sb info ++ * @sbi: new superblock info structure for the volume to be mounted ++ * @dev_name: path name for the container's block device ++ * @mode: FMODE_* mask ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) ++static int apfs_attach_nxi(struct apfs_sb_info *sbi, const char *dev_name, blk_mode_t mode) ++#else ++static int apfs_attach_nxi(struct apfs_sb_info *sbi, const char *dev_name, fmode_t mode) ++#endif ++{ ++ struct apfs_nxsb_info *nxi = NULL; ++ dev_t dev = 0; ++ int ret; ++ ++ mutex_lock(&nxs_mutex); ++ ++ ret = apfs_lookup_bdev(dev_name, &dev); ++ if (ret) ++ goto out; ++ ++ nxi = apfs_nx_find_by_dev(dev); ++ if (!nxi) { ++ nxi = kzalloc(sizeof(*nxi), GFP_KERNEL); ++ if (!nxi) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ ret = apfs_blkdev_setup(&nxi->nx_blkdev_info, dev_name, mode); ++ if (ret) ++ goto out; ++ ++ if (sbi->s_tier2_path) { ++ ret = apfs_blkdev_setup(&nxi->nx_tier2_info, sbi->s_tier2_path, mode); ++ if (ret) { ++ apfs_blkdev_cleanup(nxi->nx_blkdev_info); ++ nxi->nx_blkdev_info = NULL; ++ goto out; ++ } ++ /* We won't need this anymore, so why waste memory? */ ++ kfree(sbi->s_tier2_path); ++ sbi->s_tier2_path = NULL; ++ } ++ ++ init_rwsem(&nxi->nx_big_sem); ++ list_add(&nxi->nx_list, &nxs); ++ INIT_LIST_HEAD(&nxi->vol_list); ++ apfs_transaction_init(&nxi->nx_transaction); ++ } ++ ++ list_add(&sbi->list, &nxi->vol_list); ++ sbi->s_nxi = nxi; ++ ++nxi->nx_refcnt; ++ ret = 0; ++out: ++ if (ret) { ++ kfree(nxi); ++ nxi = NULL; ++ } ++ mutex_unlock(&nxs_mutex); ++ return ret; ++} ++ ++/** ++ * apfs_preparse_options - Parse the options used to identify a superblock ++ * @sbi: superblock info ++ * @options: options string to parse ++ * ++ * Returns 0 on success, or a negative error code in case of failure. Even on ++ * failure, the caller is responsible for freeing all superblock fields. ++ */ ++static int apfs_preparse_options(struct apfs_sb_info *sbi, char *options) ++{ ++ char *tofree = NULL; ++ char *p; ++ substring_t args[MAX_OPT_ARGS]; ++ int err = 0; ++ ++ /* Set default values before parsing */ ++ sbi->s_vol_nr = 0; ++ sbi->s_snap_name = NULL; ++ sbi->s_tier2_path = NULL; ++ ++ if (!options) ++ return 0; ++ ++ /* Later parse_options() will need the unmodified options string */ ++ options = kstrdup(options, GFP_KERNEL); ++ if (!options) ++ return -ENOMEM; ++ tofree = options; ++ ++ while ((p = strsep(&options, ",")) != NULL) { ++ int token; ++ ++ if (!*p) ++ continue; ++ token = match_token(p, tokens, args); ++ switch (token) { ++ case Opt_vol: ++ err = match_int(&args[0], &sbi->s_vol_nr); ++ if (err) ++ goto out; ++ break; ++ case Opt_snap: ++ kfree(sbi->s_snap_name); ++ sbi->s_snap_name = match_strdup(&args[0]); ++ if (!sbi->s_snap_name) { ++ err = -ENOMEM; ++ goto out; ++ } ++ break; ++ case Opt_tier2: ++ kfree(sbi->s_tier2_path); ++ sbi->s_tier2_path = match_strdup(&args[0]); ++ if (!sbi->s_tier2_path) { ++ err = -ENOMEM; ++ goto out; ++ } ++ break; ++ case Opt_readwrite: ++ case Opt_cknodes: ++ case Opt_uid: ++ case Opt_gid: ++ /* Not needed for sget(), will be read later */ ++ break; ++ default: ++ apfs_warn(NULL, "invalid mount option %s", p); ++ err = -EINVAL; ++ goto out; ++ } ++ } ++ err = 0; ++out: ++ kfree(tofree); ++ return err; ++} ++ ++/* ++ * This function is a copy of mount_bdev() that allows multiple mounts. ++ */ ++static struct dentry *apfs_mount(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data) ++{ ++ struct super_block *sb; ++ struct apfs_sb_info *sbi; ++ struct apfs_blkdev_info *bd_info = NULL, *tier2_info = NULL; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) || RHEL_VERSION_GE(9, 4) ++ blk_mode_t mode = sb_open_mode(flags); ++#else ++ fmode_t mode = FMODE_READ | FMODE_EXCL; ++#endif ++ int error = 0; ++ ++ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); ++ if (!sbi) ++ return ERR_PTR(-ENOMEM); ++ /* Set up the fields that sget() will need to id the superblock */ ++ error = apfs_preparse_options(sbi, data); ++ if (error) ++ goto out_free_sbi; ++ ++ /* Make sure that snapshots are mounted read-only */ ++ if (sbi->s_snap_name) ++ flags |= SB_RDONLY; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) && !RHEL_VERSION_GE(9, 4) ++ if (!(flags & SB_RDONLY)) ++ mode |= FMODE_WRITE; ++#endif ++ ++ error = apfs_attach_nxi(sbi, dev_name, mode); ++ if (error) ++ goto out_free_sbi; ++ ++ /* TODO: lockfs stuff? Btrfs doesn't seem to care */ ++ sb = sget(fs_type, apfs_test_super, apfs_set_super, flags | SB_NOSEC, sbi); ++ if (IS_ERR(sb)) { ++ error = PTR_ERR(sb); ++ goto out_unmap_super; ++ } ++ ++ bd_info = APFS_NXI(sb)->nx_blkdev_info; ++ tier2_info = APFS_NXI(sb)->nx_tier2_info; ++ ++ /* ++ * I'm doing something hacky with s_dev inside ->kill_sb(), so I want ++ * to find out as soon as possible if I messed it up. ++ */ ++ WARN_ON(sb->s_dev != bd_info->blki_bdev->bd_dev); ++ ++ if (sb->s_root) { ++ if ((flags ^ sb->s_flags) & SB_RDONLY) { ++ error = -EBUSY; ++ deactivate_locked_super(sb); ++ goto out_unmap_super; ++ } ++ /* Only one superblock per volume */ ++ apfs_free_main_super(sbi); ++ kfree(sbi->s_snap_name); ++ sbi->s_snap_name = NULL; ++ kfree(sbi->s_tier2_path); ++ sbi->s_tier2_path = NULL; ++ kfree(sbi); ++ sbi = NULL; ++ } else { ++ if (!sbi->s_snap_name && !tier2_info) ++ snprintf(sb->s_id, sizeof(sb->s_id), "%pg:%u", bd_info->blki_bdev, sbi->s_vol_nr); ++ else if (!tier2_info) ++ snprintf(sb->s_id, sizeof(sb->s_id), "%pg:%u:%s", bd_info->blki_bdev, sbi->s_vol_nr, sbi->s_snap_name); ++ else if (!sbi->s_snap_name) ++ snprintf(sb->s_id, sizeof(sb->s_id), "%pg+%pg:%u", bd_info->blki_bdev, tier2_info->blki_bdev, sbi->s_vol_nr); ++ else ++ snprintf(sb->s_id, sizeof(sb->s_id), "%pg+%pg:%u:%s", bd_info->blki_bdev, tier2_info->blki_bdev, sbi->s_vol_nr, sbi->s_snap_name); ++ error = apfs_read_main_super(sb); ++ if (error) { ++ deactivate_locked_super(sb); ++ return ERR_PTR(error); ++ } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) && !RHEL_VERSION_GE(9, 4) ++ sb->s_mode = mode; ++#endif ++ error = apfs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0); ++ if (error) { ++ deactivate_locked_super(sb); ++ return ERR_PTR(error); ++ } ++ sb->s_flags |= SB_ACTIVE; ++ } ++ ++ return dget(sb->s_root); ++ ++out_unmap_super: ++ apfs_free_main_super(sbi); ++out_free_sbi: ++ kfree(sbi->s_snap_name); ++ kfree(sbi->s_tier2_path); ++ kfree(sbi); ++ return ERR_PTR(error); ++} ++ ++/** ++ * apfs_free_sb_info - Free the sb info and release all remaining fields ++ * @sb: superblock structure ++ * ++ * This function does not include the cleanup for apfs_fill_super(), which ++ * already took place inside ->put_super() (or maybe inside apfs_fill_super() ++ * itself if the mount failed). ++ */ ++static void apfs_free_sb_info(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = NULL; ++ ++ sbi = APFS_SB(sb); ++ apfs_free_main_super(sbi); ++ sb->s_fs_info = NULL; ++ ++ kfree(sbi->s_snap_name); ++ sbi->s_snap_name = NULL; ++ kfree(sbi->s_tier2_path); ++ sbi->s_tier2_path = NULL; ++ if (sbi->s_dflt_pfk) ++ kfree(sbi->s_dflt_pfk); ++ kfree(sbi); ++ sbi = NULL; ++} ++ ++static void apfs_kill_sb(struct super_block *sb) ++{ ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ ++ /* ++ * We need to delist the superblock before freeing its info to avoid a ++ * race with apfs_test_super(), but we can't call kill_super_notify() ++ * from the driver. The available wrapper is kill_anon_super(), but our ++ * s_dev is set to the actual device (that gets freed later along with ++ * the container), not to the anon device that we keep on the sbi. So, ++ * we change that before the call; this is safe because other mounters ++ * won't revive this super, even if apfs_test_super() succeeds. ++ */ ++ sb->s_dev = sbi->s_anon_dev; ++ kill_anon_super(sb); ++ ++ apfs_free_sb_info(sb); ++} ++ ++static struct file_system_type apfs_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "apfs", ++ .mount = apfs_mount, ++ .kill_sb = apfs_kill_sb, ++ .fs_flags = FS_REQUIRES_DEV, ++}; ++MODULE_ALIAS_FS("apfs"); ++ ++static int __init init_apfs_fs(void) ++{ ++ int err = 0; ++ ++ err = init_inodecache(); ++ if (err) ++ return err; ++ err = register_filesystem(&apfs_fs_type); ++ if (err) ++ destroy_inodecache(); ++ return err; ++} ++ ++static void __exit exit_apfs_fs(void) ++{ ++ unregister_filesystem(&apfs_fs_type); ++ destroy_inodecache(); ++} ++ ++MODULE_AUTHOR("Ernesto A. Fernández"); ++MODULE_DESCRIPTION("Apple File System"); ++MODULE_VERSION(GIT_COMMIT); ++MODULE_LICENSE("GPL"); ++module_init(init_apfs_fs) ++module_exit(exit_apfs_fs) +diff --git a/fs/apfs/symlink.c b/fs/apfs/symlink.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/symlink.c +@@ -0,0 +1,80 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_get_link - Follow a symbolic link ++ * @dentry: dentry for the link ++ * @inode: inode for the link ++ * @done: delayed call to free the returned buffer after use ++ * ++ * Returns a pointer to a buffer containing the target path, or an appropriate ++ * error pointer in case of failure. ++ */ ++static const char *apfs_get_link(struct dentry *dentry, struct inode *inode, ++ struct delayed_call *done) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ char *target = NULL; ++ int err; ++ int size; ++ ++ down_read(&nxi->nx_big_sem); ++ ++ if (!dentry) { ++ err = -ECHILD; ++ goto fail; ++ } ++ ++ size = __apfs_xattr_get(inode, APFS_XATTR_NAME_SYMLINK, ++ NULL /* buffer */, 0 /* size */); ++ if (size < 0) { /* TODO: return a better error code */ ++ apfs_err(sb, "symlink size read failed"); ++ err = size; ++ goto fail; ++ } ++ ++ target = kmalloc(size, GFP_KERNEL); ++ if (!target) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ size = __apfs_xattr_get(inode, APFS_XATTR_NAME_SYMLINK, target, size); ++ if (size < 0) { ++ apfs_err(sb, "symlink read failed"); ++ err = size; ++ goto fail; ++ } ++ if (size == 0 || *(target + size - 1) != 0) { ++ /* Target path must be NULL-terminated */ ++ apfs_err(sb, "bad link target in inode 0x%llx", apfs_ino(inode)); ++ err = -EFSCORRUPTED; ++ goto fail; ++ } ++ ++ up_read(&nxi->nx_big_sem); ++ set_delayed_call(done, kfree_link, target); ++ return target; ++ ++fail: ++ kfree(target); ++ up_read(&nxi->nx_big_sem); ++ return ERR_PTR(err); ++} ++ ++const struct inode_operations apfs_symlink_inode_operations = { ++ .get_link = apfs_get_link, ++ .getattr = apfs_getattr, ++ .listxattr = apfs_listxattr, ++ .update_time = apfs_update_time, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) /* Now this is the default */ ++ .readlink = generic_readlink, ++#endif ++}; +diff --git a/fs/apfs/transaction.c b/fs/apfs/transaction.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/transaction.c +@@ -0,0 +1,1034 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2019 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_checkpoint_end - End the new checkpoint ++ * @sb: filesystem superblock ++ * ++ * Flushes all changes to disk, and commits the new checkpoint by setting the ++ * fletcher checksum on its superblock. Returns 0 on success, or a negative ++ * error code in case of failure. ++ */ ++static int apfs_checkpoint_end(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_obj_phys *obj = &nxi->nx_raw->nx_o; ++ struct buffer_head *bh = NULL; ++ struct apfs_blkdev_info *bd_info = nxi->nx_blkdev_info; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0) ++ struct address_space *bdev_map = bd_info->blki_bdev->bd_mapping; ++#else ++ struct inode *bdev_inode = bd_info->blki_bdev->bd_inode; ++ struct address_space *bdev_map = bdev_inode->i_mapping; ++#endif ++ int err; ++ ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ ++ bh = apfs_getblk(sb, nxi->nx_bno); ++ if (!bh) { ++ apfs_err(sb, "failed to map new checkpoint superblock"); ++ return -EIO; ++ } ++ obj->o_xid = cpu_to_le64(nxi->nx_xid); ++ apfs_obj_set_csum(sb, obj); ++ memcpy(bh->b_data, obj, sb->s_blocksize); ++ ++ err = filemap_write_and_wait(bdev_map); ++ if (err) ++ goto out; ++ ++ mark_buffer_dirty(bh); ++ err = sync_dirty_buffer(bh); ++ if (err) ++ goto out; ++ ++ err = filemap_write_and_wait(bdev_map); ++out: ++ brelse(bh); ++ bh = NULL; ++ return err; ++} ++ ++/** ++ * apfs_transaction_has_room - Is there enough free space for this transaction? ++ * @sb: superblock structure ++ * @kind: transaction kind for space preallocation ++ */ ++static bool apfs_transaction_has_room(struct super_block *sb, enum apfs_trans_kind kind) ++{ ++ struct apfs_nx_transaction *trans = NULL; ++ struct apfs_spaceman *sm = NULL; ++ u64 max_blks; ++ ++ trans = &APFS_NXI(sb)->nx_transaction; ++ sm = APFS_SM(sb); ++ ++ /* ++ * It's hard to keep track of the maximum number of blocks that each ++ * operation could need because of the complexities of apfs btrees, ++ * plus snapshots and clones. I try to keep things simple here. ++ */ ++ switch (kind) { ++ case APFS_TRANS_REG: ++ /* ++ * For transactions that are expected to reduce free space, we ++ * use a very coarse bound (512 KiB) that is certain to be much ++ * more than enough, and will always leave room for deletions. ++ */ ++ max_blks = APFS_REG_ROOM; ++ break; ++ case APFS_TRANS_DEL: ++ /* ++ * For transactions that are likely to increase free space, we ++ * use a much tighter bound (80 KiB), so that users have the ++ * opportunity to fix their ENOSPC situation. ++ * ++ * For huge filesystems with huge numbers of records, there is ++ * a tiny chance that this might be too permissive, in which ++ * case the transaction will later abort. I think that's ++ * acceptable. ++ */ ++ max_blks = APFS_DEL_ROOM; ++ break; ++ case APFS_TRANS_SYNC: ++ /* ++ * We try to allow sync as much as possible, for the user's ++ * peace of mind and because flushing the free queues could ++ * make some room. ++ * ++ * Even if we do nothing the transaction still allocates a new ++ * volume superblock, and new roots for the omap and catalog, ++ * which consumes 6 blocks in total. This could be avoided... ++ */ ++ if (trans->t_starts_count == 0) ++ max_blks = APFS_SYNC_ROOM; ++ else ++ max_blks = 0; ++ break; ++ default: ++ apfs_alert(sb, "invalid transaction kind %u - bug!", kind); ++ return false; ++ } ++ ++ return max_blks <= sm->sm_free_count; ++} ++ ++/** ++ * apfs_read_single_ephemeral_object - Read a single ephemeral object to memory ++ * @sb: filesystem superblock ++ * @map: checkpoint mapping for the object ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_read_single_ephemeral_object(struct super_block *sb, struct apfs_checkpoint_mapping *map) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = NULL; ++ struct apfs_ephemeral_object_info *list = NULL; ++ struct buffer_head *bh = NULL; ++ char *object = NULL; ++ int count; ++ u32 data_blks, size; ++ u64 data_base, bno, oid; ++ int err, i, data_idx; ++ ++ raw_sb = nxi->nx_raw; ++ data_base = le64_to_cpu(raw_sb->nx_xp_data_base); ++ data_blks = le32_to_cpu(raw_sb->nx_xp_data_blocks); ++ ++ list = nxi->nx_eph_list; ++ count = nxi->nx_eph_count; ++ if (count >= APFS_EPHEMERAL_LIST_LIMIT) { ++ apfs_err(sb, "too many ephemeral objects?"); ++ return -EOPNOTSUPP; ++ } ++ ++ bno = le64_to_cpu(map->cpm_paddr); ++ oid = le64_to_cpu(map->cpm_oid); ++ size = le32_to_cpu(map->cpm_size); ++ if (size > sb->s_blocksize << 1) { ++ /* ++ * No reason not to support bigger objects, but there has to be ++ * a limit somewhere and this is all I've seen so far. ++ */ ++ apfs_warn(sb, "ephemeral object has more than 2 blocks"); ++ return -EOPNOTSUPP; ++ } ++ if (!size || (size & (sb->s_blocksize - 1))) { ++ apfs_err(sb, "invalid object size (0x%x)", size); ++ return -EFSCORRUPTED; ++ } ++ object = kmalloc(size, GFP_KERNEL); ++ if (!object) ++ return -ENOMEM; ++ ++ data_idx = bno - data_base; ++ for (i = 0; i < size >> sb->s_blocksize_bits; ++i) { ++ bh = apfs_sb_bread(sb, data_base + data_idx); ++ if (!bh) { ++ apfs_err(sb, "failed to read ephemeral block"); ++ err = -EIO; ++ goto fail; ++ } ++ memcpy(object + (i << sb->s_blocksize_bits), bh->b_data, sb->s_blocksize); ++ brelse(bh); ++ bh = NULL; ++ /* Somewhat surprisingly, objects can wrap around */ ++ if (++data_idx == data_blks) ++ data_idx = 0; ++ } ++ ++ /* ++ * The official reference requires that we always verify ephemeral ++ * checksums on mount, so do it even if the user didn't ask. We should ++ * actually try to mount an older checkpoint when this fails (TODO), ++ * which I guess means that the official driver writes all checkpoint ++ * blocks at once, instead of leaving the superblock for last like we ++ * do. ++ */ ++ if (!apfs_multiblock_verify_csum(object, size)) { ++ apfs_err(sb, "bad checksum for ephemeral object 0x%llx", oid); ++ err = -EFSBADCRC; ++ goto fail; ++ } ++ ++ list[count].oid = oid; ++ list[count].size = size; ++ list[count].object = object; ++ object = NULL; ++ nxi->nx_eph_count = count + 1; ++ return 0; ++ ++fail: ++ kfree(object); ++ object = NULL; ++ return err; ++} ++ ++/** ++ * apfs_read_single_cpm_block - Read all ephemeral objects in a cpm block ++ * @sb: filesystem superblock ++ * @cpm_bno: block number for the cpm block ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_read_single_cpm_block(struct super_block *sb, u64 cpm_bno) ++{ ++ struct buffer_head *bh = NULL; ++ struct apfs_checkpoint_map_phys *cpm = NULL; ++ u32 map_count; ++ int err, i; ++ ++ bh = apfs_sb_bread(sb, cpm_bno); ++ if (!bh) { ++ apfs_err(sb, "failed to read cpm block"); ++ return -EIO; ++ } ++ if (!apfs_obj_verify_csum(sb, bh)) { ++ /* ++ * The reference seems to imply that we need to check these on ++ * mount, and retry an older checkpoint on failure (TODO). ++ */ ++ apfs_err(sb, "bad checksum for cpm block at 0x%llx", cpm_bno); ++ err = -EFSBADCRC; ++ goto out; ++ } ++ cpm = (struct apfs_checkpoint_map_phys *)bh->b_data; ++ ++ map_count = le32_to_cpu(cpm->cpm_count); ++ if (map_count > apfs_max_maps_per_block(sb)) { ++ apfs_err(sb, "block has too many maps (%d)", map_count); ++ err = -EFSCORRUPTED; ++ goto out; ++ } ++ ++ for (i = 0; i < map_count; ++i) { ++ err = apfs_read_single_ephemeral_object(sb, &cpm->cpm_map[i]); ++ if (err) { ++ apfs_err(sb, "failed to read ephemeral object %u", i); ++ goto out; ++ } ++ } ++ ++out: ++ brelse(bh); ++ cpm = NULL; ++ return err; ++} ++ ++static void apfs_force_readonly(struct apfs_nxsb_info *nxi); ++ ++/** ++ * apfs_read_ephemeral_objects - Read all ephemeral objects to memory ++ * @sb: superblock structure ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_read_ephemeral_objects(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = nxi->nx_raw; ++ u64 desc_base; ++ u32 desc_index, desc_blks, desc_len, i; ++ int err; ++ ++ if (nxi->nx_eph_list) { ++ apfs_alert(sb, "attempt to reread ephemeral object list"); ++ return -EFSCORRUPTED; ++ } ++ nxi->nx_eph_list = kzalloc(APFS_EPHEMERAL_LIST_SIZE, GFP_KERNEL); ++ if (!nxi->nx_eph_list) ++ return -ENOMEM; ++ nxi->nx_eph_count = 0; ++ ++ desc_base = le64_to_cpu(raw_sb->nx_xp_desc_base); ++ desc_index = le32_to_cpu(raw_sb->nx_xp_desc_index); ++ desc_blks = le32_to_cpu(raw_sb->nx_xp_desc_blocks); ++ desc_len = le32_to_cpu(raw_sb->nx_xp_desc_len); ++ ++ /* Last block in the area is superblock; the rest are mapping blocks */ ++ for (i = 0; i < desc_len - 1; ++i) { ++ u64 cpm_bno = desc_base + (desc_index + i) % desc_blks; ++ ++ err = apfs_read_single_cpm_block(sb, cpm_bno); ++ if (err) { ++ apfs_err(sb, "failed to read cpm block %u", i); ++ /* No transaction to abort yet */ ++ apfs_force_readonly(nxi); ++ return err; ++ } ++ } ++ return 0; ++} ++ ++static void apfs_trans_commit_work(struct work_struct *work) ++{ ++ struct super_block *sb = NULL; ++ struct apfs_nxsb_info *nxi = NULL; ++ struct apfs_nx_transaction *trans = NULL; ++ int err; ++ ++ trans = container_of(to_delayed_work(work), struct apfs_nx_transaction, t_work); ++ nxi = container_of(trans, struct apfs_nxsb_info, nx_transaction); ++ sb = trans->t_work_sb; ++ ++ /* ++ * If sb is set then the transaction already started, there is no need ++ * for apfs_transaction_start() here. It would be cleaner to call it ++ * anyway (and check in there if sb is set), but maxops is a problem ++ * because we don't need any space. I really need to rethink that stuff ++ * (TODO). ++ */ ++ down_write(&nxi->nx_big_sem); ++ if (!sb || sb->s_flags & SB_RDONLY) { ++ /* The commit already took place, or there was an abort */ ++ up_write(&nxi->nx_big_sem); ++ return; ++ } ++ ++ trans->t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) { ++ apfs_err(sb, "queued commit failed (err:%d)", err); ++ apfs_transaction_abort(sb); ++ } ++} ++ ++/** ++ * apfs_transaction_init - Initialize the transaction struct for the container ++ * @trans: the transaction structure ++ */ ++void apfs_transaction_init(struct apfs_nx_transaction *trans) ++{ ++ trans->t_state = 0; ++ INIT_DELAYED_WORK(&trans->t_work, apfs_trans_commit_work); ++ INIT_LIST_HEAD(&trans->t_inodes); ++ INIT_LIST_HEAD(&trans->t_buffers); ++ trans->t_buffers_count = 0; ++ trans->t_starts_count = 0; ++} ++ ++/** ++ * apfs_transaction_start - Begin a new transaction ++ * @sb: superblock structure ++ * @kind: transaction kind for space preallocation ++ * ++ * Also locks the filesystem for writing; returns 0 on success or a negative ++ * error code in case of failure. ++ */ ++int apfs_transaction_start(struct super_block *sb, enum apfs_trans_kind kind) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ int err; ++ ++ down_write(&nxi->nx_big_sem); ++ ++ if (sb->s_flags & SB_RDONLY) { ++ /* A previous transaction has failed; this should be rare */ ++ up_write(&nxi->nx_big_sem); ++ return -EROFS; ++ } ++ ++ /* ++ * Ephemeral objects are read only once, kept in memory, and committed ++ * to disk along with each transaction. ++ */ ++ if (!nxi->nx_eph_list) { ++ err = apfs_read_ephemeral_objects(sb); ++ if (err) { ++ up_write(&nxi->nx_big_sem); ++ apfs_err(sb, "failed to read the ephemeral objects"); ++ return err; ++ } ++ } ++ ++ if (nx_trans->t_starts_count == 0) { ++ ++nxi->nx_xid; ++ nxi->nx_raw->nx_next_xid = cpu_to_le64(nxi->nx_xid + 1); ++ ++ err = apfs_read_spaceman(sb); ++ if (err) { ++ apfs_err(sb, "failed to read the spaceman"); ++ goto fail; ++ } ++ } ++ ++ /* Don't start transactions unless we are sure they fit in disk */ ++ if (!apfs_transaction_has_room(sb, kind)) { ++ /* Commit what we have so far to flush the queues */ ++ nx_trans->t_state |= APFS_NX_TRANS_FORCE_COMMIT; ++ err = apfs_transaction_commit(sb); ++ if (err) { ++ apfs_err(sb, "commit failed"); ++ goto fail; ++ } ++ return -ENOSPC; ++ } ++ ++ if (nx_trans->t_starts_count == 0) { ++ err = apfs_map_volume_super(sb, true /* write */); ++ if (err) { ++ apfs_err(sb, "CoW failed for volume super"); ++ goto fail; ++ } ++ ++ /* TODO: don't copy these nodes for transactions that don't use them */ ++ err = apfs_read_omap(sb, true /* write */); ++ if (err) { ++ apfs_err(sb, "CoW failed for omap"); ++ goto fail; ++ } ++ err = apfs_read_catalog(sb, true /* write */); ++ if (err) { ++ apfs_err(sb, "Cow failed for catalog"); ++ goto fail; ++ } ++ } ++ ++ nx_trans->t_starts_count++; ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++/** ++ * apfs_transaction_flush_all_inodes - Flush inode metadata to the buffer heads ++ * @sb: superblock structure ++ * ++ * This messes a lot with the disk layout, so it must be called ahead of time ++ * if we need it to be stable for the rest or the transaction (for example, if ++ * we are setting up a snapshot). ++ */ ++int apfs_transaction_flush_all_inodes(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ int err = 0, curr_err; ++ ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ ++ while (!list_empty(&nx_trans->t_inodes)) { ++ struct apfs_inode_info *ai = NULL; ++ struct inode *inode = NULL; ++ ++ ai = list_first_entry(&nx_trans->t_inodes, struct apfs_inode_info, i_list); ++ inode = &ai->vfs_inode; ++ ++ /* This is a bit wasteful if the inode will get deleted */ ++ curr_err = apfs_update_inode(inode, NULL /* new_name */); ++ if (curr_err) ++ err = curr_err; ++ inode->i_state &= ~I_DIRTY_ALL; ++ ++ /* ++ * The same inode may get dirtied again as soon as we release ++ * the lock, and we don't want to miss that. ++ */ ++ list_del_init(&ai->i_list); ++ ++ nx_trans->t_state |= APFS_NX_TRANS_COMMITTING; ++ up_write(&nxi->nx_big_sem); ++ ++ /* Unlocked, so it may call evict() and wait for writeback */ ++ iput(inode); ++ ++ down_write(&nxi->nx_big_sem); ++ nx_trans->t_state = 0; ++ ++ /* Transaction aborted during writeback, error code is lost */ ++ if (sb->s_flags & SB_RDONLY) { ++ apfs_err(sb, "abort during inode writeback"); ++ return -EROFS; ++ } ++ } ++ ++ return err; ++} ++ ++/** ++ * apfs_write_single_ephemeral_object - Write a single ephemeral object to bh's ++ * @sb: filesystem superblock ++ * @obj_raw: contents of the object ++ * @map: checkpoint mapping for the object, already updated ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_write_single_ephemeral_object(struct super_block *sb, struct apfs_obj_phys *obj_raw, const struct apfs_checkpoint_mapping *map) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = NULL; ++ struct buffer_head *bh = NULL; ++ u64 data_base, bno; ++ u32 data_blks, size; ++ int err, i, data_idx; ++ ++ raw_sb = nxi->nx_raw; ++ data_base = le64_to_cpu(raw_sb->nx_xp_data_base); ++ data_blks = le32_to_cpu(raw_sb->nx_xp_data_blocks); ++ ++ bno = le64_to_cpu(map->cpm_paddr); ++ size = le32_to_cpu(map->cpm_size); ++ obj_raw->o_xid = cpu_to_le64(nxi->nx_xid); ++ apfs_multiblock_set_csum((char *)obj_raw, size); ++ ++ data_idx = bno - data_base; ++ for (i = 0; i < size >> sb->s_blocksize_bits; ++i) { ++ bh = apfs_getblk(sb, data_base + data_idx); ++ if (!bh) { ++ apfs_err(sb, "failed to map ephemeral block"); ++ return -EIO; ++ } ++ err = apfs_transaction_join(sb, bh); ++ if (err) { ++ brelse(bh); ++ bh = NULL; ++ return err; ++ } ++ memcpy(bh->b_data, (char *)obj_raw + (i << sb->s_blocksize_bits), sb->s_blocksize); ++ brelse(bh); ++ bh = NULL; ++ /* Somewhat surprisingly, objects can wrap around */ ++ if (++data_idx == data_blks) ++ data_idx = 0; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_write_ephemeral_objects - Write all ephemeral objects to bh's ++ * @sb: filesystem superblock ++ * ++ * Returns 0 on sucess, or a negative error code in case of failure. ++ */ ++static int apfs_write_ephemeral_objects(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_superblock *raw_sb = nxi->nx_raw; ++ struct apfs_checkpoint_map_phys *cpm = NULL; ++ struct buffer_head *cpm_bh = NULL; ++ struct apfs_ephemeral_object_info *eph_info = NULL; ++ u64 cpm_bno; ++ u64 desc_base, data_base; ++ u32 desc_index, desc_blks, desc_len, desc_next; ++ u32 data_index, data_blks, data_len, data_next; ++ u32 desc_limit, data_limit; ++ u32 obj_blkcnt; ++ int err, i, cpm_start; ++ ++ if (!nxi->nx_eph_list) { ++ apfs_alert(sb, "missing ephemeral object list"); ++ return -EFSCORRUPTED; ++ } ++ ++ desc_next = le32_to_cpu(raw_sb->nx_xp_desc_next); ++ desc_base = le64_to_cpu(raw_sb->nx_xp_desc_base); ++ desc_index = desc_next; /* New checkpoint */ ++ desc_blks = le32_to_cpu(raw_sb->nx_xp_desc_blocks); ++ desc_len = 0; /* For now */ ++ ++ data_next = le32_to_cpu(raw_sb->nx_xp_data_next); ++ data_base = le64_to_cpu(raw_sb->nx_xp_data_base); ++ data_index = data_next; /* New checkpoint */ ++ data_blks = le32_to_cpu(raw_sb->nx_xp_data_blocks); ++ data_len = 0; /* For now */ ++ ++ /* ++ * The reference doesn't mention anything about this, but I need to ++ * put some sort of a limit or else the rings could wrap around and ++ * corrupt themselves. ++ */ ++ desc_limit = desc_blks >> 2; ++ data_limit = data_blks >> 2; ++ ++ for (i = 0; i < nxi->nx_eph_count; ++i) { ++ if (data_len == data_limit) { ++ apfs_err(sb, "too many checkpoint data blocks"); ++ return -EFSCORRUPTED; ++ } ++ ++ if (!cpm) { ++ cpm_start = i; ++ if (desc_len == desc_limit) { ++ apfs_err(sb, "too many checkpoint descriptor blocks"); ++ return -EFSCORRUPTED; ++ } ++ cpm_bno = desc_base + (desc_index + desc_len) % desc_blks; ++ err = apfs_create_cpm_block(sb, cpm_bno, &cpm_bh); ++ if (err) { ++ apfs_err(sb, "failed to create cpm block"); ++ return err; ++ } ++ cpm = (void *)cpm_bh->b_data; ++ desc_len += 1; ++ } ++ ++ eph_info = &nxi->nx_eph_list[i]; ++ data_next = (data_index + data_len) % data_blks; ++ obj_blkcnt = eph_info->size >> sb->s_blocksize_bits; ++ ++ err = apfs_create_cpoint_map(sb, cpm, eph_info->object, data_base + data_next, eph_info->size); ++ if (err) { ++ if (err == -ENOSPC) ++ cpm->cpm_flags = 0; /* No longer the last */ ++ brelse(cpm_bh); ++ cpm = NULL; ++ cpm_bh = NULL; ++ if (err == -ENOSPC) { ++ --i; ++ continue; ++ } ++ apfs_err(sb, "failed to create cpm map %d", i); ++ return err; ++ } ++ err = apfs_write_single_ephemeral_object(sb, eph_info->object, &cpm->cpm_map[i - cpm_start]); ++ if (err) { ++ brelse(cpm_bh); ++ cpm = NULL; ++ cpm_bh = NULL; ++ apfs_err(sb, "failed to write ephemeral object %d", i); ++ return err; ++ } ++ data_len += obj_blkcnt; ++ } ++ ++ /* ++ * The checkpoint superblock can't be set until the very end of the ++ * transaction commit, but allocate its block here already. ++ */ ++ nxi->nx_bno = desc_base + (desc_index + desc_len) % desc_blks; ++ desc_len += 1; ++ ++ desc_next = (desc_index + desc_len) % desc_blks; ++ data_next = (data_index + data_len) % data_blks; ++ ++ raw_sb->nx_xp_desc_next = cpu_to_le32(desc_next); ++ raw_sb->nx_xp_desc_index = cpu_to_le32(desc_index); ++ raw_sb->nx_xp_desc_len = cpu_to_le32(desc_len); ++ ++ raw_sb->nx_xp_data_next = cpu_to_le32(data_next); ++ raw_sb->nx_xp_data_index = cpu_to_le32(data_index); ++ raw_sb->nx_xp_data_len = cpu_to_le32(data_len); ++ ++ return 0; ++} ++ ++/** ++ * apfs_transaction_commit_nx - Definitely commit the current transaction ++ * @sb: superblock structure ++ */ ++static int apfs_transaction_commit_nx(struct super_block *sb) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ struct apfs_bh_info *bhi, *tmp; ++ int err = 0; ++ ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ ++ /* Before committing the bhs, write all inode metadata to them */ ++ err = apfs_transaction_flush_all_inodes(sb); ++ if (err) { ++ apfs_err(sb, "failed to flush all inodes"); ++ return err; ++ } ++ ++ /* ++ * Now that nothing else will be freed, flush the last update to the ++ * free queues so that it can be committed to disk along with all the ++ * ephemeral objects. ++ */ ++ if (sm->sm_free_cache_base) { ++ err = apfs_free_queue_insert_nocache(sb, sm->sm_free_cache_base, sm->sm_free_cache_blkcnt); ++ if (err) { ++ apfs_err(sb, "fq cache flush failed (0x%llx-0x%llx)", sm->sm_free_cache_base, sm->sm_free_cache_blkcnt); ++ return err; ++ } ++ sm->sm_free_cache_base = sm->sm_free_cache_blkcnt = 0; ++ } ++ /* ++ * Writing the ip bitmaps modifies the spaceman, so it must happen ++ * before we commit the ephemeral objects. It must also happen after we ++ * flush the free queue, in case the last freed range was in the ip. ++ */ ++ err = apfs_write_ip_bitmaps(sb); ++ if (err) { ++ apfs_err(sb, "failed to commit the ip bitmaps"); ++ return err; ++ } ++ err = apfs_write_ephemeral_objects(sb); ++ if (err) ++ return err; ++ ++ list_for_each_entry(bhi, &nx_trans->t_buffers, list) { ++ struct buffer_head *bh = bhi->bh; ++ ++ ASSERT(buffer_trans(bh)); ++ ++ if (buffer_csum(bh)) ++ apfs_obj_set_csum(sb, (void *)bh->b_data); ++ ++ clear_buffer_dirty(bh); ++ get_bh(bh); ++ lock_buffer(bh); ++ bh->b_end_io = end_buffer_write_sync; ++ apfs_submit_bh(REQ_OP_WRITE, REQ_SYNC, bh); ++ } ++ list_for_each_entry_safe(bhi, tmp, &nx_trans->t_buffers, list) { ++ struct buffer_head *bh = bhi->bh; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) ++ struct folio *folio = NULL; ++#else ++ struct page *page = NULL; ++#endif ++ bool is_metadata; ++ ++ ASSERT(buffer_trans(bh)); ++ ++ wait_on_buffer(bh); ++ if (!buffer_uptodate(bh)) { ++ apfs_err(sb, "failed to write some blocks"); ++ return -EIO; ++ } ++ ++ list_del(&bhi->list); ++ clear_buffer_trans(bh); ++ nx_trans->t_buffers_count--; ++ ++ bh->b_private = NULL; ++ bhi->bh = NULL; ++ kfree(bhi); ++ bhi = NULL; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) ++ folio = page_folio(bh->b_page); ++ folio_get(folio); ++#else ++ page = bh->b_page; ++ get_page(page); ++#endif ++ ++ is_metadata = buffer_csum(bh); ++ clear_buffer_csum(bh); ++ put_bh(bh); ++ bh = NULL; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) ++ folio_lock(folio); ++ folio_mkclean(folio); ++#else ++ /* Future writes to mmapped areas should fault for CoW */ ++ lock_page(page); ++ page_mkclean(page); ++#endif ++ /* XXX: otherwise, the page cache fills up and crashes the machine */ ++ if (!is_metadata) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) ++ try_to_free_buffers(folio); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3) ++ try_to_free_buffers(page_folio(page)); ++#else ++ try_to_free_buffers(page); ++#endif ++ } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) ++ folio_unlock(folio); ++ folio_put(folio); ++#else ++ unlock_page(page); ++ put_page(page); ++#endif ++ } ++ err = apfs_checkpoint_end(sb); ++ if (err) { ++ apfs_err(sb, "failed to end the checkpoint"); ++ return err; ++ } ++ ++ nx_trans->t_starts_count = 0; ++ nx_trans->t_buffers_count = 0; ++ return 0; ++} ++ ++/** ++ * apfs_transaction_need_commit - Evaluate if a commit is required ++ * @sb: superblock structure ++ */ ++static bool apfs_transaction_need_commit(struct super_block *sb) ++{ ++ struct apfs_spaceman *sm = APFS_SM(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ ++ if (nx_trans->t_state & APFS_NX_TRANS_DEFER_COMMIT) { ++ nx_trans->t_state &= ~APFS_NX_TRANS_DEFER_COMMIT; ++ return false; ++ } ++ ++ /* Avoid nested commits on inode writeback */ ++ if (nx_trans->t_state & APFS_NX_TRANS_COMMITTING) ++ return false; ++ ++ if (nx_trans->t_state & APFS_NX_TRANS_FORCE_COMMIT) { ++ nx_trans->t_state = 0; ++ return true; ++ } ++ ++ if (sm) { ++ struct apfs_spaceman_phys *sm_raw = sm->sm_raw; ++ struct apfs_spaceman_free_queue *fq_ip = &sm_raw->sm_fq[APFS_SFQ_IP]; ++ struct apfs_spaceman_free_queue *fq_main = &sm_raw->sm_fq[APFS_SFQ_MAIN]; ++ int buffers_max = nxi->nx_trans_buffers_max; ++ int starts_max = APFS_TRANS_STARTS_MAX; ++ int mq_max = APFS_TRANS_MAIN_QUEUE_MAX; ++ int maxnodes; ++ ++ /* ++ * Try to avoid committing halfway through a data block write, ++ * otherwise the block will be put through copy-on-write again, ++ * causing unnecessary fragmentation. ++ */ ++ if (nx_trans->t_state & APFS_NX_TRANS_INCOMPLETE_BLOCK) { ++ buffers_max += 50; ++ starts_max += 50; ++ mq_max += 20; ++ } ++ ++ if (nx_trans->t_buffers_count > buffers_max) ++ return true; ++ if (nx_trans->t_starts_count > starts_max) ++ return true; ++ ++ /* ++ * The internal pool has enough blocks to map the container ++ * exactly 3 times. Don't allow large transactions if we can't ++ * be sure the bitmap changes will all fit. ++ */ ++ if (le64_to_cpu(fq_ip->sfq_count) * 3 > le64_to_cpu(sm_raw->sm_ip_block_count)) ++ return true; ++ ++ /* Don't let the main queue get too full either */ ++ if (le64_to_cpu(fq_main->sfq_count) > mq_max) ++ return true; ++ ++ /* ++ * The main free queue can become unbalanced enough to reach ++ * the node limit while being mostly empty. For now, the only ++ * way I have to rebalance it is to flush it entirely with a ++ * new transaction. We could wait longer to do it, but I don't ++ * see the point. ++ */ ++ maxnodes = le16_to_cpu(fq_main->sfq_tree_node_limit); ++ maxnodes = (maxnodes + 1) >> 1; ++ if (sm->sm_main_fq_nodes > 1 && sm->sm_main_fq_nodes >= maxnodes) ++ return true; ++ } ++ ++ return false; ++} ++ ++/** ++ * apfs_transaction_commit - Possibly commit the current transaction ++ * @sb: superblock structure ++ * ++ * On success returns 0 and releases the big filesystem lock. On failure, ++ * returns a negative error code, and the caller is responsibly for aborting ++ * the transaction. ++ */ ++int apfs_transaction_commit(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *trans = NULL; ++ int err = 0; ++ ++ trans = &nxi->nx_transaction; ++ ++ if (apfs_transaction_need_commit(sb)) { ++ err = apfs_transaction_commit_nx(sb); ++ if (err) { ++ apfs_err(sb, "transaction commit failed"); ++ return err; ++ } ++ trans->t_work_sb = NULL; ++ cancel_delayed_work(&trans->t_work); ++ } else { ++ trans->t_work_sb = sb; ++ mod_delayed_work(system_wq, &trans->t_work, msecs_to_jiffies(100)); ++ } ++ ++ up_write(&nxi->nx_big_sem); ++ return 0; ++} ++ ++/** ++ * apfs_inode_join_transaction - Add an inode to the current transaction ++ * @sb: superblock structure ++ * @inode: vfs inode to add ++ */ ++void apfs_inode_join_transaction(struct super_block *sb, struct inode *inode) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ struct apfs_inode_info *ai = APFS_I(inode); ++ ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ lockdep_assert_held_write(&nxi->nx_big_sem); ++ ++ if (!list_empty(&ai->i_list)) /* Already in the transaction */ ++ return; ++ ++ ihold(inode); ++ list_add(&ai->i_list, &nx_trans->t_inodes); ++} ++ ++/** ++ * apfs_transaction_join - Add a buffer head to the current transaction ++ * @sb: superblock structure ++ * @bh: the buffer head ++ */ ++int apfs_transaction_join(struct super_block *sb, struct buffer_head *bh) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ struct apfs_bh_info *bhi; ++ ++ ASSERT(!(sb->s_flags & SB_RDONLY)); ++ lockdep_assert_held_write(&nxi->nx_big_sem); ++ ++ if (buffer_trans(bh)) /* Already part of the only transaction */ ++ return 0; ++ ++ /* TODO: use a slab cache */ ++ bhi = kzalloc(sizeof(*bhi), GFP_NOFS); ++ if (!bhi) ++ return -ENOMEM; ++ get_bh(bh); ++ bhi->bh = bh; ++ list_add(&bhi->list, &nx_trans->t_buffers); ++ nx_trans->t_buffers_count++; ++ ++ set_buffer_trans(bh); ++ bh->b_private = bhi; ++ return 0; ++} ++ ++/** ++ * apfs_force_readonly - Set the whole container as read-only ++ * @nxi: container superblock info ++ */ ++static void apfs_force_readonly(struct apfs_nxsb_info *nxi) ++{ ++ struct apfs_sb_info *sbi = NULL; ++ struct super_block *sb = NULL; ++ ++ list_for_each_entry(sbi, &nxi->vol_list, list) { ++ sb = sbi->s_vobject.sb; ++ sb->s_flags |= SB_RDONLY; ++ } ++ nxi->nx_flags &= ~APFS_READWRITE; ++} ++ ++/** ++ * apfs_transaction_abort - Abort the current transaction ++ * @sb: superblock structure ++ * ++ * Releases the big filesystem lock and clears the in-memory transaction data; ++ * the on-disk changes are irrelevant because the superblock checksum hasn't ++ * been written yet. Leaves the filesystem in read-only state. ++ */ ++void apfs_transaction_abort(struct super_block *sb) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_nx_transaction *nx_trans = &nxi->nx_transaction; ++ struct apfs_bh_info *bhi, *tmp; ++ struct apfs_inode_info *ai, *ai_tmp; ++ ++ if (sb->s_flags & SB_RDONLY) { ++ /* Transaction already aborted, do nothing */ ++ ASSERT(list_empty(&nx_trans->t_inodes)); ++ ASSERT(list_empty(&nx_trans->t_buffers)); ++ up_write(&nxi->nx_big_sem); ++ return; ++ } ++ ++ nx_trans->t_state = 0; ++ apfs_err(sb, "aborting transaction"); ++ ++ --nxi->nx_xid; ++ list_for_each_entry_safe(bhi, tmp, &nx_trans->t_buffers, list) { ++ struct buffer_head *bh = bhi->bh; ++ ++ bh->b_private = NULL; ++ clear_buffer_dirty(bh); ++ clear_buffer_trans(bh); ++ clear_buffer_csum(bh); ++ brelse(bh); ++ bhi->bh = NULL; ++ ++ list_del(&bhi->list); ++ kfree(bhi); ++ } ++ ++ /* ++ * It's not possible to undo in-memory changes from old operations in ++ * the aborted transaction. To avoid corruption, never write again. ++ */ ++ apfs_force_readonly(nxi); ++ ++ up_write(&nxi->nx_big_sem); ++ ++ list_for_each_entry_safe(ai, ai_tmp, &nx_trans->t_inodes, i_list) { ++ list_del_init(&ai->i_list); ++ iput(&ai->vfs_inode); ++ } ++} +diff --git a/fs/apfs/unicode.c b/fs/apfs/unicode.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/unicode.c +@@ -0,0 +1,3156 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ * ++ * Routines and data for the normalization of unicode strings. ++ * Somewhat based on linux/fs/hfsplus/unicode.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "unicode.h" ++ ++/* The arrays of unicode data are defined at the bottom of the file */ ++/* TODO: would a single trie with all the data be more efficient? */ ++static u16 apfs_nfd_trie[]; ++static unicode_t apfs_nfd[]; ++static u16 apfs_cf_trie[]; ++static unicode_t apfs_cf[]; ++static u8 apfs_ccc_trie[]; ++ ++#define TRIE_HEIGHT 5 ++ ++/* A trie node has one child for each possible nibble in the key */ ++#define TRIE_CHILD_SHIFT 4 ++#define TRIE_CHILD_MASK ((1 << TRIE_CHILD_SHIFT) - 1) ++ ++/* A trie value length is stored in the last three bits of its position */ ++#define TRIE_POS_SHIFT 3 ++#define TRIE_SIZE_MASK ((1 << TRIE_POS_SHIFT) - 1) ++ ++/** ++ * apfs_trie_find - Look up a trie value ++ * @trie: trie to search ++ * @key: search key (a unicode character) ++ * @result: on return, this either holds the value (on a ccc lookup) or its ++ * position in the value array (on a cf or nfd lookup). ++ * @is_ccc: true if this a ccc (canonical combining class) lookup ++ * ++ * Returns the length of the value (0 if it doesn't exist). ++ */ ++static int apfs_trie_find(void *trie, unicode_t key, void *result, bool is_ccc) ++{ ++ int node = 0; ++ int h; ++ ++ for (h = TRIE_HEIGHT - 1; h >= 0; --h) { ++ int child = (key >> (TRIE_CHILD_SHIFT * h)) & TRIE_CHILD_MASK; ++ int child_index = (node << TRIE_CHILD_SHIFT) + child; ++ ++ if (is_ccc) ++ node = ((u8 *)trie)[child_index]; ++ else ++ node = ((u16 *)trie)[child_index]; ++ ++ if (node == 0) { ++ *(u8 *)result = 0; ++ return 0; ++ } ++ } ++ ++ if (is_ccc) { ++ /* ccc values fit in one byte, so no need for a value array */ ++ *(u8 *)result = node; ++ return 1; ++ } ++ ++ *(u16 *)result = node >> TRIE_POS_SHIFT; ++ return node & TRIE_SIZE_MASK; ++} ++ ++/** ++ * apfs_init_unicursor - Initialize an apfs_unicursor structure ++ * @cursor: cursor to initialize ++ * @utf8str: string to normalize ++ * @total_len: length of the string ++ */ ++void apfs_init_unicursor(struct apfs_unicursor *cursor, const char *utf8str, unsigned int total_len) ++{ ++ cursor->utf8curr = utf8str; ++ cursor->total_len = total_len; ++ cursor->length = -1; ++ cursor->last_pos = -1; ++ cursor->last_ccc = 0; ++} ++ ++#define HANGUL_S_BASE 0xac00 ++#define HANGUL_L_BASE 0x1100 ++#define HANGUL_V_BASE 0x1161 ++#define HANGUL_T_BASE 0x11a7 ++#define HANGUL_L_COUNT 19 ++#define HANGUL_V_COUNT 21 ++#define HANGUL_T_COUNT 28 ++#define HANGUL_N_COUNT (HANGUL_V_COUNT * HANGUL_T_COUNT) ++#define HANGUL_S_COUNT (HANGUL_L_COUNT * HANGUL_N_COUNT) ++ ++/** ++ * apfs_is_precomposed_hangul - Check if a character is a Hangul syllable ++ * @utf32char: character to check ++ * ++ * This function was adapted from sample code in section 3.12 of the ++ * Unicode Standard, version 9.0. ++ * ++ * Copyright (C) 1991-2018 Unicode, Inc. All rights reserved. Distributed ++ * under the Terms of Use in http://www.unicode.org/copyright.html. ++ */ ++static bool apfs_is_precomposed_hangul(unicode_t utf32char) ++{ ++ int index; ++ ++ index = utf32char - HANGUL_S_BASE; ++ return (index >= 0 && index < HANGUL_S_COUNT); ++} ++ ++/* Signals the end of the normalization for a single character */ ++#define NORM_END (unicode_t)(-1) ++ ++/** ++ * apfs_decompose_hangul - Decompose a Hangul syllable ++ * @utf32char: Hangul syllable to decompose ++ * @off: offset of the wanted character from the decomposition ++ * ++ * Returns the single character at offset @off in the decomposition of ++ * @utf32char, or NORM_END if this offset is past the end. ++ * ++ * This function was adapted from sample code in section 3.12 of the ++ * Unicode Standard, version 9.0. ++ * ++ * Copyright (C) 1991-2018 Unicode, Inc. All rights reserved. Distributed ++ * under the Terms of Use in http://www.unicode.org/copyright.html. ++ */ ++static unicode_t apfs_decompose_hangul(unicode_t utf32char, int off) ++{ ++ int index; ++ int l, v, t; ++ ++ index = utf32char - HANGUL_S_BASE; ++ ++ l = HANGUL_L_BASE + index / HANGUL_N_COUNT; ++ if (off == 0) ++ return l; ++ ++ v = HANGUL_V_BASE + (index % HANGUL_N_COUNT) / HANGUL_T_COUNT; ++ if (off == 1) ++ return v; ++ ++ t = HANGUL_T_BASE + index % HANGUL_T_COUNT; ++ if (off == 2 && t != HANGUL_T_BASE) ++ return t; ++ ++ return NORM_END; ++} ++ ++/** ++ * apfs_normalize_char - Normalize a unicode character ++ * @utf32char: character to normalize ++ * @off: offset of the wanted character from the normalization ++ * @case_fold: case fold the char? ++ * ++ * Returns the single character at offset @off in the normalization of ++ * @utf32char, or NORM_END if this offset is past the end. ++ */ ++static unicode_t apfs_normalize_char(unicode_t utf32char, int off, ++ bool case_fold) ++{ ++ int nfd_len; ++ unicode_t *nfd, *cf; ++ u16 pos; ++ int ret; ++ ++ if (apfs_is_precomposed_hangul(utf32char)) /* Hangul has no case */ ++ return apfs_decompose_hangul(utf32char, off); ++ ++ ret = apfs_trie_find(apfs_nfd_trie, utf32char, ++ &pos, false /* is_ccc */); ++ if (!ret) { ++ /* The decomposition is just the same character */ ++ nfd_len = 1; ++ nfd = &utf32char; ++ } else { ++ nfd_len = ret; ++ nfd = &apfs_nfd[pos]; ++ } ++ ++ if (!case_fold) { ++ if (off < nfd_len) ++ return nfd[off]; ++ return NORM_END; ++ } ++ ++ for (; nfd_len > 0; nfd++, nfd_len--) { ++ int cf_len; ++ ++ ret = apfs_trie_find(apfs_cf_trie, *nfd, ++ &pos, false /* is_ccc */); ++ if (!ret) { ++ /* The case folding is just the same character */ ++ cf_len = 1; ++ cf = nfd; ++ } else { ++ cf_len = ret; ++ cf = &apfs_cf[pos]; ++ } ++ ++ if (off < cf_len) ++ return cf[off]; ++ off -= cf_len; ++ } ++ ++ return NORM_END; ++} ++ ++/** ++ * apfs_get_normalization_length - Count the characters until the next starter ++ * @utf8str: string to normalize, may begin with several starters ++ * @total_len: length of the string to normalize ++ * @case_fold: true if the count should consider case folding ++ * ++ * Returns the number of unicode characters in the normalization of the ++ * substring that begins at @utf8str and ends at the first nonconsecutive ++ * starter. Or 0 if the substring has invalid UTF-8. ++ */ ++static int apfs_get_normalization_length(const char *utf8str, unsigned int total_len, bool case_fold) ++{ ++ int utf8len, pos, norm_len = 0; ++ bool starters_over = false; ++ unicode_t utf32char; ++ ++ while (1) { ++ if (!total_len || !*utf8str) ++ return norm_len; ++ utf8len = utf8_to_utf32(utf8str, min(total_len, 4U), &utf32char); ++ if (utf8len < 0) /* Invalid unicode; don't normalize anything */ ++ return 0; ++ ++ for (pos = 0;; pos++, norm_len++) { ++ unicode_t utf32norm; ++ u8 ccc; ++ ++ utf32norm = apfs_normalize_char(utf32char, pos, ++ case_fold); ++ if (utf32norm == NORM_END) ++ break; ++ ++ apfs_trie_find(apfs_ccc_trie, utf32norm, &ccc, ++ true /* is_ccc */); ++ ++ if (ccc != 0) ++ starters_over = true; ++ else if (starters_over) /* Reached the next starter */ ++ return norm_len; ++ } ++ utf8str += utf8len; ++ total_len -= utf8len; ++ } ++} ++ ++/** ++ * apfs_normalize_next - Return the next normalized character from a string ++ * @cursor: unicode cursor for the string ++ * @case_fold: case fold the string? ++ * ++ * Sets @cursor->length to the length of the normalized substring between ++ * @cursor->utf8curr and the first nonconsecutive starter. Returns a single ++ * normalized character, setting @cursor->last_ccc and @cursor->last_pos to ++ * its CCC and position in the substring. When the end of the substring is ++ * reached, updates @cursor->utf8curr to point to the beginning of the next ++ * one. ++ * ++ * Returns 0 if the substring has invalid UTF-8. ++ */ ++unicode_t apfs_normalize_next(struct apfs_unicursor *cursor, bool case_fold) ++{ ++ const char *utf8str = cursor->utf8curr; ++ unsigned int total_len = cursor->total_len; ++ int str_pos, min_pos = -1; ++ unicode_t utf32min = 0; ++ u8 min_ccc; ++ ++new_starter: ++ if (likely(isascii(*utf8str))) { ++ if (!total_len) ++ return 0; ++ cursor->utf8curr = utf8str + 1; ++ cursor->total_len = total_len - 1; ++ if (case_fold) ++ return tolower(*utf8str); ++ return *utf8str; ++ } ++ ++ if (cursor->length < 0) { ++ cursor->length = apfs_get_normalization_length(utf8str, total_len, case_fold); ++ if (cursor->length == 0) ++ return 0; ++ } ++ ++ str_pos = 0; ++ min_ccc = 0xFF; /* Above all possible ccc's */ ++ ++ while (1) { ++ unicode_t utf32char; ++ int utf8len, pos; ++ ++ utf8len = utf8_to_utf32(utf8str, min(total_len, 4U), &utf32char); ++ for (pos = 0;; pos++, str_pos++) { ++ unicode_t utf32norm; ++ u8 ccc; ++ ++ utf32norm = apfs_normalize_char(utf32char, pos, ++ case_fold); ++ if (utf32norm == NORM_END) ++ break; ++ ++ apfs_trie_find(apfs_ccc_trie, utf32norm, &ccc, ++ true /* is_ccc */); ++ ++ if (ccc >= min_ccc || ccc < cursor->last_ccc) ++ continue; ++ if (ccc > cursor->last_ccc || ++ str_pos > cursor->last_pos) { ++ utf32min = utf32norm; ++ min_ccc = ccc; ++ min_pos = str_pos; ++ } ++ } ++ ++ utf8str += utf8len; ++ total_len -= utf8len; ++ if (str_pos == cursor->length) { ++ /* Reached the following starter */ ++ if (min_ccc != 0xFF) { ++ /* Not done with this substring yet */ ++ cursor->last_ccc = min_ccc; ++ cursor->last_pos = min_pos; ++ return utf32min; ++ } ++ /* Continue from the next starter */ ++ apfs_init_unicursor(cursor, utf8str, total_len); ++ goto new_starter; ++ } ++ } ++} ++ ++/* ++ * The following arrays were built with data provided by the Unicode Standard, ++ * version 9.0. ++ * ++ * Copyright (C) 1991-2018 Unicode, Inc. All rights reserved. Distributed ++ * under the Terms of Use in http://www.unicode.org/copyright.html. ++ */ ++ ++static u16 apfs_nfd_trie[] = { ++ /* Node for range 0x_____ */ ++ 0x0001, 0x0002, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0____ */ ++ 0x0004, 0x0005, 0x0006, 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, ++ /* Node for range 0x1____ */ ++ 0x0000, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x0000, 0x0000, ++ /* Node for range 0x2____ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000b, ++ /* Node for range 0x00___ */ ++ 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0000, 0x0011, 0x0000, ++ 0x0000, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0000, 0x0017, ++ /* Node for range 0x01___ */ ++ 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0019, 0x0000, 0x0000, 0x001a, 0x001b, ++ /* Node for range 0x02___ */ ++ 0x001c, 0x001d, 0x001e, 0x001f, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x03___ */ ++ 0x0021, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0f___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0022, 0x0023, 0x0024, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x11___ */ ++ 0x0025, 0x0026, 0x0000, 0x0027, 0x0028, 0x0029, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1d___ */ ++ 0x0000, 0x002a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x2f___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x002b, 0x002c, 0x002d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x000__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x002e, 0x002f, 0x0030, 0x0031, ++ /* Node for range 0x001__ */ ++ 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, ++ 0x0000, 0x0000, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, ++ /* Node for range 0x002__ */ ++ 0x0040, 0x0041, 0x0042, 0x0043, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x0000, 0x0000, 0x0045, ++ 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x0000, 0x0000, ++ /* Node for range 0x004__ */ ++ 0x004c, 0x004d, 0x0000, 0x004e, 0x0000, 0x004f, 0x0000, 0x0050, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0051, 0x0052, 0x0053, 0x0054, ++ /* Node for range 0x006__ */ ++ 0x0000, 0x0000, 0x0055, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0056, 0x0057, 0x0000, 0x0000, ++ /* Node for range 0x009__ */ ++ 0x0000, 0x0000, 0x0058, 0x0059, 0x0000, 0x005a, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x005b, 0x005c, 0x0000, 0x0000, ++ /* Node for range 0x00a__ */ ++ 0x0000, 0x0000, 0x0000, 0x005d, 0x0000, 0x005e, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00b__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x005f, 0x0060, 0x0000, 0x0000, ++ 0x0000, 0x0061, 0x0000, 0x0000, 0x0062, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00c__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0063, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0064, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00d__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0065, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x0000, 0x0000, ++ /* Node for range 0x00f__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0067, 0x0068, 0x0069, 0x006a, ++ 0x006b, 0x006c, 0x006d, 0x006e, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x010__ */ ++ 0x0000, 0x0000, 0x006f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01b__ */ ++ 0x0070, 0x0071, 0x0000, 0x0072, 0x0073, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01e__ */ ++ 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, ++ 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, ++ /* Node for range 0x01f__ */ ++ 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, ++ 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, ++ /* Node for range 0x020__ */ ++ 0x0094, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x021__ */ ++ 0x0000, 0x0000, 0x0095, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0096, 0x0097, 0x0000, 0x0098, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x022__ */ ++ 0x0099, 0x0000, 0x009a, 0x0000, 0x009b, 0x0000, 0x009c, 0x009d, ++ 0x009e, 0x0000, 0x009f, 0x0000, 0x0000, 0x0000, 0x00a0, 0x0000, ++ /* Node for range 0x023__ */ ++ 0x0000, 0x0000, 0x00a1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x02a__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00a2, 0x0000, 0x0000, ++ /* Node for range 0x030__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x00a3, 0x00a4, 0x00a5, 0x00a6, ++ 0x0000, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x0000, 0x00ac, ++ /* Node for range 0x0f9__ */ ++ 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, ++ 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, ++ /* Node for range 0x0fa__ */ ++ 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, ++ 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x0000, 0x0000, ++ /* Node for range 0x0fb__ */ ++ 0x0000, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x110__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x00cf, 0x00d0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x111__ */ ++ 0x0000, 0x0000, 0x00d1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x113__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x00d2, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x114__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x00d3, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x115__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x00d4, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1d1__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d5, 0x00d6, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x00d7, 0x00d8, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x2f8__ */ ++ 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, ++ 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, ++ /* Node for range 0x2f9__ */ ++ 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, ++ 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, ++ /* Node for range 0x2fa__ */ ++ 0x00f9, 0x00fa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x000c_ */ ++ 0x0002, 0x0012, 0x0022, 0x0032, 0x0042, 0x0052, 0x0000, 0x0062, ++ 0x0072, 0x0082, 0x0092, 0x00a2, 0x00b2, 0x00c2, 0x00d2, 0x00e2, ++ /* Node for range 0x000d_ */ ++ 0x0000, 0x00f2, 0x0102, 0x0112, 0x0122, 0x0132, 0x0142, 0x0000, ++ 0x0000, 0x0152, 0x0162, 0x0172, 0x0182, 0x0192, 0x0000, 0x0000, ++ /* Node for range 0x000e_ */ ++ 0x01a2, 0x01b2, 0x01c2, 0x01d2, 0x01e2, 0x01f2, 0x0000, 0x0202, ++ 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, 0x0272, 0x0282, ++ /* Node for range 0x000f_ */ ++ 0x0000, 0x0292, 0x02a2, 0x02b2, 0x02c2, 0x02d2, 0x02e2, 0x0000, ++ 0x0000, 0x02f2, 0x0302, 0x0312, 0x0322, 0x0332, 0x0000, 0x0342, ++ /* Node for range 0x0010_ */ ++ 0x0352, 0x0362, 0x0372, 0x0382, 0x0392, 0x03a2, 0x03b2, 0x03c2, ++ 0x03d2, 0x03e2, 0x03f2, 0x0402, 0x0412, 0x0422, 0x0432, 0x0442, ++ /* Node for range 0x0011_ */ ++ 0x0000, 0x0000, 0x0452, 0x0462, 0x0472, 0x0482, 0x0492, 0x04a2, ++ 0x04b2, 0x04c2, 0x04d2, 0x04e2, 0x04f2, 0x0502, 0x0512, 0x0522, ++ /* Node for range 0x0012_ */ ++ 0x0532, 0x0542, 0x0552, 0x0562, 0x0572, 0x0582, 0x0000, 0x0000, ++ 0x0592, 0x05a2, 0x05b2, 0x05c2, 0x05d2, 0x05e2, 0x05f2, 0x0602, ++ /* Node for range 0x0013_ */ ++ 0x0612, 0x0000, 0x0000, 0x0000, 0x0622, 0x0632, 0x0642, 0x0652, ++ 0x0000, 0x0662, 0x0672, 0x0682, 0x0692, 0x06a2, 0x06b2, 0x0000, ++ /* Node for range 0x0014_ */ ++ 0x0000, 0x0000, 0x0000, 0x06c2, 0x06d2, 0x06e2, 0x06f2, 0x0702, ++ 0x0712, 0x0000, 0x0000, 0x0000, 0x0722, 0x0732, 0x0742, 0x0752, ++ /* Node for range 0x0015_ */ ++ 0x0762, 0x0772, 0x0000, 0x0000, 0x0782, 0x0792, 0x07a2, 0x07b2, ++ 0x07c2, 0x07d2, 0x07e2, 0x07f2, 0x0802, 0x0812, 0x0822, 0x0832, ++ /* Node for range 0x0016_ */ ++ 0x0842, 0x0852, 0x0862, 0x0872, 0x0882, 0x0892, 0x0000, 0x0000, ++ 0x08a2, 0x08b2, 0x08c2, 0x08d2, 0x08e2, 0x08f2, 0x0902, 0x0912, ++ /* Node for range 0x0017_ */ ++ 0x0922, 0x0932, 0x0942, 0x0952, 0x0962, 0x0972, 0x0982, 0x0992, ++ 0x09a2, 0x09b2, 0x09c2, 0x09d2, 0x09e2, 0x09f2, 0x0a02, 0x0000, ++ /* Node for range 0x001a_ */ ++ 0x0a12, 0x0a22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a32, ++ /* Node for range 0x001b_ */ ++ 0x0a42, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x001c_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a52, 0x0a62, 0x0a72, ++ /* Node for range 0x001d_ */ ++ 0x0a82, 0x0a92, 0x0aa2, 0x0ab2, 0x0ac2, 0x0ad3, 0x0aeb, 0x0b03, ++ 0x0b1b, 0x0b33, 0x0b4b, 0x0b63, 0x0b7b, 0x0000, 0x0b93, 0x0bab, ++ /* Node for range 0x001e_ */ ++ 0x0bc3, 0x0bdb, 0x0bf2, 0x0c02, 0x0000, 0x0000, 0x0c12, 0x0c22, ++ 0x0c32, 0x0c42, 0x0c52, 0x0c62, 0x0c73, 0x0c8b, 0x0ca2, 0x0cb2, ++ /* Node for range 0x001f_ */ ++ 0x0cc2, 0x0000, 0x0000, 0x0000, 0x0cd2, 0x0ce2, 0x0000, 0x0000, ++ 0x0cf2, 0x0d02, 0x0d13, 0x0d2b, 0x0d42, 0x0d52, 0x0d62, 0x0d72, ++ /* Node for range 0x0020_ */ ++ 0x0d82, 0x0d92, 0x0da2, 0x0db2, 0x0dc2, 0x0dd2, 0x0de2, 0x0df2, ++ 0x0e02, 0x0e12, 0x0e22, 0x0e32, 0x0e42, 0x0e52, 0x0e62, 0x0e72, ++ /* Node for range 0x0021_ */ ++ 0x0e82, 0x0e92, 0x0ea2, 0x0eb2, 0x0ec2, 0x0ed2, 0x0ee2, 0x0ef2, ++ 0x0f02, 0x0f12, 0x0f22, 0x0f32, 0x0000, 0x0000, 0x0f42, 0x0f52, ++ /* Node for range 0x0022_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f62, 0x0f72, ++ 0x0f82, 0x0f92, 0x0fa3, 0x0fbb, 0x0fd3, 0x0feb, 0x1002, 0x1012, ++ /* Node for range 0x0023_ */ ++ 0x1023, 0x103b, 0x1052, 0x1062, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0034_ */ ++ 0x1071, 0x1079, 0x0000, 0x1081, 0x108a, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0037_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x1099, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10a1, 0x0000, ++ /* Node for range 0x0038_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10aa, 0x10ba, 0x10c9, ++ 0x10d2, 0x10e2, 0x10f2, 0x0000, 0x1102, 0x0000, 0x1112, 0x1122, ++ /* Node for range 0x0039_ */ ++ 0x1133, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003a_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x114a, 0x115a, 0x116a, 0x117a, 0x118a, 0x119a, ++ /* Node for range 0x003b_ */ ++ 0x11ab, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003c_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x11c2, 0x11d2, 0x11e2, 0x11f2, 0x1202, 0x0000, ++ /* Node for range 0x003d_ */ ++ 0x0000, 0x0000, 0x0000, 0x1212, 0x1222, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0040_ */ ++ 0x1232, 0x1242, 0x0000, 0x1252, 0x0000, 0x0000, 0x0000, 0x1262, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x1272, 0x1282, 0x1292, 0x0000, ++ /* Node for range 0x0041_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x12a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0043_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x12b2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0045_ */ ++ 0x12c2, 0x12d2, 0x0000, 0x12e2, 0x0000, 0x0000, 0x0000, 0x12f2, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x1302, 0x1312, 0x1322, 0x0000, ++ /* Node for range 0x0047_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1332, 0x1342, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x004c_ */ ++ 0x0000, 0x1352, 0x1362, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x004d_ */ ++ 0x1372, 0x1382, 0x1392, 0x13a2, 0x0000, 0x0000, 0x13b2, 0x13c2, ++ 0x0000, 0x0000, 0x13d2, 0x13e2, 0x13f2, 0x1402, 0x1412, 0x1422, ++ /* Node for range 0x004e_ */ ++ 0x0000, 0x0000, 0x1432, 0x1442, 0x1452, 0x1462, 0x1472, 0x1482, ++ 0x0000, 0x0000, 0x1492, 0x14a2, 0x14b2, 0x14c2, 0x14d2, 0x14e2, ++ /* Node for range 0x004f_ */ ++ 0x14f2, 0x1502, 0x1512, 0x1522, 0x1532, 0x1542, 0x0000, 0x0000, ++ 0x1552, 0x1562, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0062_ */ ++ 0x0000, 0x0000, 0x1572, 0x1582, 0x1592, 0x15a2, 0x15b2, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x006c_ */ ++ 0x15c2, 0x0000, 0x15d2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x006d_ */ ++ 0x0000, 0x0000, 0x0000, 0x15e2, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0092_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x15f2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0093_ */ ++ 0x0000, 0x1602, 0x0000, 0x0000, 0x1612, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0095_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1622, 0x1632, 0x1642, 0x1652, 0x1662, 0x1672, 0x1682, 0x1692, ++ /* Node for range 0x009c_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x16a2, 0x16b2, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x009d_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x16c2, 0x16d2, 0x0000, 0x16e2, ++ /* Node for range 0x00a3_ */ ++ 0x0000, 0x0000, 0x0000, 0x16f2, 0x0000, 0x0000, 0x1702, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00a5_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x1712, 0x1722, 0x1732, 0x0000, 0x0000, 0x1742, 0x0000, ++ /* Node for range 0x00b4_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1752, 0x0000, 0x0000, 0x1762, 0x1772, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00b5_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x1782, 0x1792, 0x0000, 0x0000, ++ /* Node for range 0x00b9_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x17a2, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00bc_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x17b2, 0x17c2, 0x17d2, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00c4_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x17e2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00cc_ */ ++ 0x17f2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1802, ++ 0x1812, 0x0000, 0x1822, 0x1833, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00d4_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x184a, 0x185a, 0x186a, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00dd_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x187a, 0x0000, 0x188a, 0x189b, 0x18b2, 0x0000, ++ /* Node for range 0x00f4_ */ ++ 0x0000, 0x0000, 0x0000, 0x18c2, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18d2, 0x0000, 0x0000, ++ /* Node for range 0x00f5_ */ ++ 0x0000, 0x0000, 0x18e2, 0x0000, 0x0000, 0x0000, 0x0000, 0x18f2, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x1902, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00f6_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x1912, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00f7_ */ ++ 0x0000, 0x0000, 0x0000, 0x1922, 0x0000, 0x1932, 0x1942, 0x0000, ++ 0x1952, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00f8_ */ ++ 0x0000, 0x1962, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00f9_ */ ++ 0x0000, 0x0000, 0x0000, 0x1972, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1982, 0x0000, 0x0000, ++ /* Node for range 0x00fa_ */ ++ 0x0000, 0x0000, 0x1992, 0x0000, 0x0000, 0x0000, 0x0000, 0x19a2, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x19b2, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x00fb_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x19c2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0102_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19d2, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01b0_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19e2, 0x0000, ++ 0x19f2, 0x0000, 0x1a02, 0x0000, 0x1a12, 0x0000, 0x1a22, 0x0000, ++ /* Node for range 0x01b1_ */ ++ 0x0000, 0x0000, 0x1a32, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01b3_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x1a42, 0x0000, 0x1a52, 0x0000, 0x0000, ++ /* Node for range 0x01b4_ */ ++ 0x1a62, 0x1a72, 0x0000, 0x1a82, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01e0_ */ ++ 0x1a92, 0x1aa2, 0x1ab2, 0x1ac2, 0x1ad2, 0x1ae2, 0x1af2, 0x1b02, ++ 0x1b13, 0x1b2b, 0x1b42, 0x1b52, 0x1b62, 0x1b72, 0x1b82, 0x1b92, ++ /* Node for range 0x01e1_ */ ++ 0x1ba2, 0x1bb2, 0x1bc2, 0x1bd2, 0x1be3, 0x1bfb, 0x1c13, 0x1c2b, ++ 0x1c42, 0x1c52, 0x1c62, 0x1c72, 0x1c83, 0x1c9b, 0x1cb2, 0x1cc2, ++ /* Node for range 0x01e2_ */ ++ 0x1cd2, 0x1ce2, 0x1cf2, 0x1d02, 0x1d12, 0x1d22, 0x1d32, 0x1d42, ++ 0x1d52, 0x1d62, 0x1d72, 0x1d82, 0x1d92, 0x1da2, 0x1db3, 0x1dcb, ++ /* Node for range 0x01e3_ */ ++ 0x1de2, 0x1df2, 0x1e02, 0x1e12, 0x1e22, 0x1e32, 0x1e42, 0x1e52, ++ 0x1e63, 0x1e7b, 0x1e92, 0x1ea2, 0x1eb2, 0x1ec2, 0x1ed2, 0x1ee2, ++ /* Node for range 0x01e4_ */ ++ 0x1ef2, 0x1f02, 0x1f12, 0x1f22, 0x1f32, 0x1f42, 0x1f52, 0x1f62, ++ 0x1f72, 0x1f82, 0x1f92, 0x1fa2, 0x1fb3, 0x1fcb, 0x1fe3, 0x1ffb, ++ /* Node for range 0x01e5_ */ ++ 0x2013, 0x202b, 0x2043, 0x205b, 0x2072, 0x2082, 0x2092, 0x20a2, ++ 0x20b2, 0x20c2, 0x20d2, 0x20e2, 0x20f3, 0x210b, 0x2122, 0x2132, ++ /* Node for range 0x01e6_ */ ++ 0x2142, 0x2152, 0x2162, 0x2172, 0x2183, 0x219b, 0x21b3, 0x21cb, ++ 0x21e3, 0x21fb, 0x2212, 0x2222, 0x2232, 0x2242, 0x2252, 0x2262, ++ /* Node for range 0x01e7_ */ ++ 0x2272, 0x2282, 0x2292, 0x22a2, 0x22b2, 0x22c2, 0x22d2, 0x22e2, ++ 0x22f3, 0x230b, 0x2323, 0x233b, 0x2352, 0x2362, 0x2372, 0x2382, ++ /* Node for range 0x01e8_ */ ++ 0x2392, 0x23a2, 0x23b2, 0x23c2, 0x23d2, 0x23e2, 0x23f2, 0x2402, ++ 0x2412, 0x2422, 0x2432, 0x2442, 0x2452, 0x2462, 0x2472, 0x2482, ++ /* Node for range 0x01e9_ */ ++ 0x2492, 0x24a2, 0x24b2, 0x24c2, 0x24d2, 0x24e2, 0x24f2, 0x2502, ++ 0x2512, 0x2522, 0x0000, 0x2532, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01ea_ */ ++ 0x2542, 0x2552, 0x2562, 0x2572, 0x2583, 0x259b, 0x25b3, 0x25cb, ++ 0x25e3, 0x25fb, 0x2613, 0x262b, 0x2643, 0x265b, 0x2673, 0x268b, ++ /* Node for range 0x01eb_ */ ++ 0x26a3, 0x26bb, 0x26d3, 0x26eb, 0x2703, 0x271b, 0x2733, 0x274b, ++ 0x2762, 0x2772, 0x2782, 0x2792, 0x27a2, 0x27b2, 0x27c3, 0x27db, ++ /* Node for range 0x01ec_ */ ++ 0x27f3, 0x280b, 0x2823, 0x283b, 0x2853, 0x286b, 0x2883, 0x289b, ++ 0x28b2, 0x28c2, 0x28d2, 0x28e2, 0x28f2, 0x2902, 0x2912, 0x2922, ++ /* Node for range 0x01ed_ */ ++ 0x2933, 0x294b, 0x2963, 0x297b, 0x2993, 0x29ab, 0x29c3, 0x29db, ++ 0x29f3, 0x2a0b, 0x2a23, 0x2a3b, 0x2a53, 0x2a6b, 0x2a83, 0x2a9b, ++ /* Node for range 0x01ee_ */ ++ 0x2ab3, 0x2acb, 0x2ae3, 0x2afb, 0x2b12, 0x2b22, 0x2b32, 0x2b42, ++ 0x2b53, 0x2b6b, 0x2b83, 0x2b9b, 0x2bb3, 0x2bcb, 0x2be3, 0x2bfb, ++ /* Node for range 0x01ef_ */ ++ 0x2c13, 0x2c2b, 0x2c42, 0x2c52, 0x2c62, 0x2c72, 0x2c82, 0x2c92, ++ 0x2ca2, 0x2cb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01f0_ */ ++ 0x2cc2, 0x2cd2, 0x2ce3, 0x2cfb, 0x2d13, 0x2d2b, 0x2d43, 0x2d5b, ++ 0x2d72, 0x2d82, 0x2d93, 0x2dab, 0x2dc3, 0x2ddb, 0x2df3, 0x2e0b, ++ /* Node for range 0x01f1_ */ ++ 0x2e22, 0x2e32, 0x2e43, 0x2e5b, 0x2e73, 0x2e8b, 0x0000, 0x0000, ++ 0x2ea2, 0x2eb2, 0x2ec3, 0x2edb, 0x2ef3, 0x2f0b, 0x0000, 0x0000, ++ /* Node for range 0x01f2_ */ ++ 0x2f22, 0x2f32, 0x2f43, 0x2f5b, 0x2f73, 0x2f8b, 0x2fa3, 0x2fbb, ++ 0x2fd2, 0x2fe2, 0x2ff3, 0x300b, 0x3023, 0x303b, 0x3053, 0x306b, ++ /* Node for range 0x01f3_ */ ++ 0x3082, 0x3092, 0x30a3, 0x30bb, 0x30d3, 0x30eb, 0x3103, 0x311b, ++ 0x3132, 0x3142, 0x3153, 0x316b, 0x3183, 0x319b, 0x31b3, 0x31cb, ++ /* Node for range 0x01f4_ */ ++ 0x31e2, 0x31f2, 0x3203, 0x321b, 0x3233, 0x324b, 0x0000, 0x0000, ++ 0x3262, 0x3272, 0x3283, 0x329b, 0x32b3, 0x32cb, 0x0000, 0x0000, ++ /* Node for range 0x01f5_ */ ++ 0x32e2, 0x32f2, 0x3303, 0x331b, 0x3333, 0x334b, 0x3363, 0x337b, ++ 0x0000, 0x3392, 0x0000, 0x33a3, 0x0000, 0x33bb, 0x0000, 0x33d3, ++ /* Node for range 0x01f6_ */ ++ 0x33ea, 0x33fa, 0x340b, 0x3423, 0x343b, 0x3453, 0x346b, 0x3483, ++ 0x349a, 0x34aa, 0x34bb, 0x34d3, 0x34eb, 0x3503, 0x351b, 0x3533, ++ /* Node for range 0x01f7_ */ ++ 0x354a, 0x355a, 0x356a, 0x357a, 0x358a, 0x359a, 0x35aa, 0x35ba, ++ 0x35ca, 0x35da, 0x35ea, 0x35fa, 0x360a, 0x361a, 0x0000, 0x0000, ++ /* Node for range 0x01f8_ */ ++ 0x362b, 0x3643, 0x365c, 0x367c, 0x369c, 0x36bc, 0x36dc, 0x36fc, ++ 0x371b, 0x3733, 0x374c, 0x376c, 0x378c, 0x37ac, 0x37cc, 0x37ec, ++ /* Node for range 0x01f9_ */ ++ 0x380b, 0x3823, 0x383c, 0x385c, 0x387c, 0x389c, 0x38bc, 0x38dc, ++ 0x38fb, 0x3913, 0x392c, 0x394c, 0x396c, 0x398c, 0x39ac, 0x39cc, ++ /* Node for range 0x01fa_ */ ++ 0x39eb, 0x3a03, 0x3a1c, 0x3a3c, 0x3a5c, 0x3a7c, 0x3a9c, 0x3abc, ++ 0x3adb, 0x3af3, 0x3b0c, 0x3b2c, 0x3b4c, 0x3b6c, 0x3b8c, 0x3bac, ++ /* Node for range 0x01fb_ */ ++ 0x3bca, 0x3bda, 0x3beb, 0x3c02, 0x3c13, 0x0000, 0x3c2a, 0x3c3b, ++ 0x3c52, 0x3c62, 0x3c72, 0x3c82, 0x3c92, 0x0000, 0x3ca1, 0x0000, ++ /* Node for range 0x01fc_ */ ++ 0x0000, 0x3caa, 0x3cbb, 0x3cd2, 0x3ce3, 0x0000, 0x3cfa, 0x3d0b, ++ 0x3d22, 0x3d32, 0x3d42, 0x3d52, 0x3d62, 0x3d72, 0x3d82, 0x3d92, ++ /* Node for range 0x01fd_ */ ++ 0x3da2, 0x3db2, 0x3dc3, 0x3ddb, 0x0000, 0x0000, 0x3df2, 0x3e03, ++ 0x3e1a, 0x3e2a, 0x3e3a, 0x3e4a, 0x0000, 0x3e5a, 0x3e6a, 0x3e7a, ++ /* Node for range 0x01fe_ */ ++ 0x3e8a, 0x3e9a, 0x3eab, 0x3ec3, 0x3eda, 0x3eea, 0x3efa, 0x3f0b, ++ 0x3f22, 0x3f32, 0x3f42, 0x3f52, 0x3f62, 0x3f72, 0x3f82, 0x3f91, ++ /* Node for range 0x01ff_ */ ++ 0x0000, 0x0000, 0x3f9b, 0x3fb2, 0x3fc3, 0x0000, 0x3fda, 0x3feb, ++ 0x4002, 0x4012, 0x4022, 0x4032, 0x4042, 0x4051, 0x0000, 0x0000, ++ /* Node for range 0x0200_ */ ++ 0x4059, 0x4061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0212_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4069, 0x0000, ++ 0x0000, 0x0000, 0x4071, 0x407a, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0219_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x408a, 0x409a, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x021a_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x40aa, 0x0000, ++ /* Node for range 0x021c_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x40ba, 0x40ca, 0x40da, ++ /* Node for range 0x0220_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x40ea, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x40fa, 0x0000, 0x0000, 0x410a, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0222_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x411a, 0x0000, 0x412a, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0224_ */ ++ 0x0000, 0x413a, 0x0000, 0x0000, 0x414a, 0x0000, 0x0000, 0x415a, ++ 0x0000, 0x416a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0226_ */ ++ 0x417a, 0x0000, 0x418a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x419a, 0x41aa, 0x41ba, ++ /* Node for range 0x0227_ */ ++ 0x41ca, 0x41da, 0x0000, 0x0000, 0x41ea, 0x41fa, 0x0000, 0x0000, ++ 0x420a, 0x421a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0228_ */ ++ 0x422a, 0x423a, 0x0000, 0x0000, 0x424a, 0x425a, 0x0000, 0x0000, ++ 0x426a, 0x427a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x022a_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x428a, 0x429a, 0x42aa, 0x42ba, ++ /* Node for range 0x022e_ */ ++ 0x42ca, 0x42da, 0x42ea, 0x42fa, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x430a, 0x431a, 0x432a, 0x433a, 0x0000, 0x0000, ++ /* Node for range 0x0232_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x4349, 0x4351, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x02ad_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x435a, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0304_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x436a, 0x0000, 0x437a, 0x0000, ++ /* Node for range 0x0305_ */ ++ 0x438a, 0x0000, 0x439a, 0x0000, 0x43aa, 0x0000, 0x43ba, 0x0000, ++ 0x43ca, 0x0000, 0x43da, 0x0000, 0x43ea, 0x0000, 0x43fa, 0x0000, ++ /* Node for range 0x0306_ */ ++ 0x440a, 0x0000, 0x441a, 0x0000, 0x0000, 0x442a, 0x0000, 0x443a, ++ 0x0000, 0x444a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0307_ */ ++ 0x445a, 0x446a, 0x0000, 0x447a, 0x448a, 0x0000, 0x449a, 0x44aa, ++ 0x0000, 0x44ba, 0x44ca, 0x0000, 0x44da, 0x44ea, 0x0000, 0x0000, ++ /* Node for range 0x0309_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x44fa, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x450a, 0x0000, ++ /* Node for range 0x030a_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x451a, 0x0000, 0x452a, 0x0000, ++ /* Node for range 0x030b_ */ ++ 0x453a, 0x0000, 0x454a, 0x0000, 0x455a, 0x0000, 0x456a, 0x0000, ++ 0x457a, 0x0000, 0x458a, 0x0000, 0x459a, 0x0000, 0x45aa, 0x0000, ++ /* Node for range 0x030c_ */ ++ 0x45ba, 0x0000, 0x45ca, 0x0000, 0x0000, 0x45da, 0x0000, 0x45ea, ++ 0x0000, 0x45fa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x030d_ */ ++ 0x460a, 0x461a, 0x0000, 0x462a, 0x463a, 0x0000, 0x464a, 0x465a, ++ 0x0000, 0x466a, 0x467a, 0x0000, 0x468a, 0x469a, 0x0000, 0x0000, ++ /* Node for range 0x030f_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x46aa, 0x0000, 0x0000, 0x46ba, ++ 0x46ca, 0x46da, 0x46ea, 0x0000, 0x0000, 0x0000, 0x46fa, 0x0000, ++ /* Node for range 0x0f90_ */ ++ 0x4709, 0x4711, 0x4719, 0x4721, 0x4729, 0x4731, 0x4739, 0x4741, ++ 0x4749, 0x4751, 0x4759, 0x4761, 0x4769, 0x4771, 0x4779, 0x4781, ++ /* Node for range 0x0f91_ */ ++ 0x4789, 0x4791, 0x4799, 0x47a1, 0x47a9, 0x47b1, 0x47b9, 0x47c1, ++ 0x47c9, 0x47d1, 0x47d9, 0x47e1, 0x47e9, 0x47f1, 0x47f9, 0x4801, ++ /* Node for range 0x0f92_ */ ++ 0x4809, 0x4811, 0x4819, 0x4821, 0x4829, 0x4831, 0x4839, 0x4841, ++ 0x4849, 0x4851, 0x4859, 0x4861, 0x4869, 0x4871, 0x4879, 0x4881, ++ /* Node for range 0x0f93_ */ ++ 0x4889, 0x4891, 0x4899, 0x48a1, 0x48a9, 0x48b1, 0x48b9, 0x48c1, ++ 0x48c9, 0x48d1, 0x48d9, 0x48e1, 0x48e9, 0x48f1, 0x48f9, 0x4901, ++ /* Node for range 0x0f94_ */ ++ 0x4909, 0x4911, 0x4919, 0x4921, 0x4929, 0x4931, 0x4939, 0x4941, ++ 0x4949, 0x4951, 0x4959, 0x4961, 0x4969, 0x4971, 0x4979, 0x4981, ++ /* Node for range 0x0f95_ */ ++ 0x4989, 0x4991, 0x4999, 0x49a1, 0x49a9, 0x49b1, 0x49b9, 0x49c1, ++ 0x49c9, 0x49d1, 0x49d9, 0x49e1, 0x49e9, 0x49f1, 0x49f9, 0x4a01, ++ /* Node for range 0x0f96_ */ ++ 0x4a09, 0x4a11, 0x4a19, 0x4a21, 0x4a29, 0x4a31, 0x4a39, 0x4a41, ++ 0x4a49, 0x4a51, 0x4a59, 0x4a61, 0x4a69, 0x4a71, 0x4a79, 0x4a81, ++ /* Node for range 0x0f97_ */ ++ 0x4a89, 0x4a91, 0x4a99, 0x4aa1, 0x4aa9, 0x4ab1, 0x4ab9, 0x4ac1, ++ 0x4ac9, 0x4ad1, 0x4ad9, 0x4ae1, 0x4ae9, 0x4af1, 0x4af9, 0x4b01, ++ /* Node for range 0x0f98_ */ ++ 0x4b09, 0x4b11, 0x4b19, 0x4b21, 0x4b29, 0x4b31, 0x4b39, 0x4b41, ++ 0x4b49, 0x4b51, 0x4b59, 0x4b61, 0x4b69, 0x4b71, 0x4b79, 0x4b81, ++ /* Node for range 0x0f99_ */ ++ 0x4b89, 0x4b91, 0x4b99, 0x4ba1, 0x4ba9, 0x4bb1, 0x4bb9, 0x4bc1, ++ 0x4bc9, 0x4bd1, 0x4bd9, 0x4be1, 0x4be9, 0x4bf1, 0x4bf9, 0x4c01, ++ /* Node for range 0x0f9a_ */ ++ 0x4c09, 0x4c11, 0x4c19, 0x4c21, 0x4c29, 0x4c31, 0x4c39, 0x4c41, ++ 0x4c49, 0x4c51, 0x4c59, 0x4c61, 0x4c69, 0x4c71, 0x4c79, 0x4c81, ++ /* Node for range 0x0f9b_ */ ++ 0x4c89, 0x4c91, 0x4c99, 0x4ca1, 0x4ca9, 0x4cb1, 0x4cb9, 0x4cc1, ++ 0x4cc9, 0x4cd1, 0x4cd9, 0x4ce1, 0x4ce9, 0x4cf1, 0x4cf9, 0x4d01, ++ /* Node for range 0x0f9c_ */ ++ 0x4d09, 0x4d11, 0x4d19, 0x4d21, 0x4d29, 0x4d31, 0x4d39, 0x4d41, ++ 0x4d49, 0x4d51, 0x4d59, 0x4d61, 0x4d69, 0x4d71, 0x4d79, 0x4d81, ++ /* Node for range 0x0f9d_ */ ++ 0x4d89, 0x4d91, 0x4d99, 0x4da1, 0x4da9, 0x4db1, 0x4db9, 0x4dc1, ++ 0x4dc9, 0x4dd1, 0x4dd9, 0x4de1, 0x4de9, 0x4df1, 0x4df9, 0x4e01, ++ /* Node for range 0x0f9e_ */ ++ 0x4e09, 0x4e11, 0x4e19, 0x4e21, 0x4e29, 0x4e31, 0x4e39, 0x4e41, ++ 0x4e49, 0x4e51, 0x4e59, 0x4e61, 0x4e69, 0x4e71, 0x4e79, 0x4e81, ++ /* Node for range 0x0f9f_ */ ++ 0x4e89, 0x4e91, 0x4e99, 0x4ea1, 0x4ea9, 0x4eb1, 0x4eb9, 0x4ec1, ++ 0x4ec9, 0x4ed1, 0x4ed9, 0x4ee1, 0x4ee9, 0x4ef1, 0x4ef9, 0x4f01, ++ /* Node for range 0x0fa0_ */ ++ 0x4f09, 0x4f11, 0x4f19, 0x4f21, 0x4f29, 0x4f31, 0x4f39, 0x4f41, ++ 0x4f49, 0x4f51, 0x4f59, 0x4f61, 0x4f69, 0x4f71, 0x0000, 0x0000, ++ /* Node for range 0x0fa1_ */ ++ 0x4f79, 0x0000, 0x4f81, 0x0000, 0x0000, 0x4f89, 0x4f91, 0x4f99, ++ 0x4fa1, 0x4fa9, 0x4fb1, 0x4fb9, 0x4fc1, 0x4fc9, 0x4fd1, 0x0000, ++ /* Node for range 0x0fa2_ */ ++ 0x4fd9, 0x0000, 0x4fe1, 0x0000, 0x0000, 0x4fe9, 0x4ff1, 0x0000, ++ 0x0000, 0x0000, 0x4ff9, 0x5001, 0x5009, 0x5011, 0x5019, 0x5021, ++ /* Node for range 0x0fa3_ */ ++ 0x5029, 0x5031, 0x5039, 0x5041, 0x5049, 0x5051, 0x5059, 0x5061, ++ 0x5069, 0x5071, 0x5079, 0x5081, 0x5089, 0x5091, 0x5099, 0x50a1, ++ /* Node for range 0x0fa4_ */ ++ 0x50a9, 0x50b1, 0x50b9, 0x50c1, 0x50c9, 0x50d1, 0x50d9, 0x50e1, ++ 0x50e9, 0x50f1, 0x50f9, 0x5101, 0x5109, 0x5111, 0x5119, 0x5121, ++ /* Node for range 0x0fa5_ */ ++ 0x5129, 0x5131, 0x5139, 0x5141, 0x5149, 0x5151, 0x5159, 0x5161, ++ 0x5169, 0x5171, 0x5179, 0x5181, 0x5189, 0x5191, 0x5199, 0x51a1, ++ /* Node for range 0x0fa6_ */ ++ 0x51a9, 0x51b1, 0x51b9, 0x51c1, 0x51c9, 0x51d1, 0x51d9, 0x51e1, ++ 0x51e9, 0x51f1, 0x51f9, 0x5201, 0x5209, 0x5211, 0x0000, 0x0000, ++ /* Node for range 0x0fa7_ */ ++ 0x5219, 0x5221, 0x5229, 0x5231, 0x5239, 0x5241, 0x5249, 0x5251, ++ 0x5259, 0x5261, 0x5269, 0x5271, 0x5279, 0x5281, 0x5289, 0x5291, ++ /* Node for range 0x0fa8_ */ ++ 0x5299, 0x52a1, 0x52a9, 0x52b1, 0x52b9, 0x52c1, 0x52c9, 0x52d1, ++ 0x52d9, 0x52e1, 0x52e9, 0x52f1, 0x52f9, 0x5301, 0x5309, 0x5311, ++ /* Node for range 0x0fa9_ */ ++ 0x5319, 0x5321, 0x5329, 0x5331, 0x5339, 0x5341, 0x5349, 0x5351, ++ 0x5359, 0x5361, 0x5369, 0x5371, 0x5379, 0x5381, 0x5389, 0x5391, ++ /* Node for range 0x0faa_ */ ++ 0x5399, 0x53a1, 0x53a9, 0x53b1, 0x53b9, 0x53c1, 0x53c9, 0x53d1, ++ 0x53d9, 0x53e1, 0x53e9, 0x53f1, 0x53f9, 0x5401, 0x5409, 0x5411, ++ /* Node for range 0x0fab_ */ ++ 0x5419, 0x5421, 0x5429, 0x5431, 0x5439, 0x5441, 0x5449, 0x5451, ++ 0x5459, 0x5461, 0x5469, 0x5471, 0x5479, 0x5481, 0x5489, 0x5491, ++ /* Node for range 0x0fac_ */ ++ 0x5499, 0x54a1, 0x54a9, 0x54b1, 0x54b9, 0x54c1, 0x54c9, 0x54d1, ++ 0x54d9, 0x54e1, 0x54e9, 0x54f1, 0x54f9, 0x5501, 0x5509, 0x5511, ++ /* Node for range 0x0fad_ */ ++ 0x5519, 0x5521, 0x5529, 0x5531, 0x5539, 0x5541, 0x5549, 0x5551, ++ 0x5559, 0x5561, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0fb1_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x556a, 0x0000, 0x557a, ++ /* Node for range 0x0fb2_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x558a, 0x559a, 0x55ab, 0x55c3, 0x55da, 0x55ea, ++ /* Node for range 0x0fb3_ */ ++ 0x55fa, 0x560a, 0x561a, 0x562a, 0x563a, 0x564a, 0x565a, 0x0000, ++ 0x566a, 0x567a, 0x568a, 0x569a, 0x56aa, 0x0000, 0x56ba, 0x0000, ++ /* Node for range 0x0fb4_ */ ++ 0x56ca, 0x56da, 0x0000, 0x56ea, 0x56fa, 0x0000, 0x570a, 0x571a, ++ 0x572a, 0x573a, 0x574a, 0x575a, 0x576a, 0x577a, 0x578a, 0x0000, ++ /* Node for range 0x1109_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x579a, 0x0000, 0x57aa, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x110a_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x57ba, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1112_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x57ca, 0x57da, ++ /* Node for range 0x1134_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x57ea, 0x57fa, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x114b_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x580a, 0x581a, 0x0000, 0x582a, 0x0000, ++ /* Node for range 0x115b_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x583a, 0x584a, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1d15_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x585a, 0x586a, ++ /* Node for range 0x1d16_ */ ++ 0x587b, 0x5893, 0x58ab, 0x58c3, 0x58db, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1d1b_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x58f2, 0x5902, 0x5913, 0x592b, 0x5943, ++ /* Node for range 0x1d1c_ */ ++ 0x595b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x2f80_ */ ++ 0x5971, 0x5979, 0x5981, 0x5989, 0x5991, 0x5999, 0x59a1, 0x59a9, ++ 0x59b1, 0x59b9, 0x59c1, 0x59c9, 0x59d1, 0x59d9, 0x59e1, 0x59e9, ++ /* Node for range 0x2f81_ */ ++ 0x59f1, 0x59f9, 0x5a01, 0x5a09, 0x5a11, 0x5a19, 0x5a21, 0x5a29, ++ 0x5a31, 0x5a39, 0x5a41, 0x5a49, 0x5a51, 0x5a59, 0x5a61, 0x5a69, ++ /* Node for range 0x2f82_ */ ++ 0x5a71, 0x5a79, 0x5a81, 0x5a89, 0x5a91, 0x5a99, 0x5aa1, 0x5aa9, ++ 0x5ab1, 0x5ab9, 0x5ac1, 0x5ac9, 0x5ad1, 0x5ad9, 0x5ae1, 0x5ae9, ++ /* Node for range 0x2f83_ */ ++ 0x5af1, 0x5af9, 0x5b01, 0x5b09, 0x5b11, 0x5b19, 0x5b21, 0x5b29, ++ 0x5b31, 0x5b39, 0x5b41, 0x5b49, 0x5b51, 0x5b59, 0x5b61, 0x5b69, ++ /* Node for range 0x2f84_ */ ++ 0x5b71, 0x5b79, 0x5b81, 0x5b89, 0x5b91, 0x5b99, 0x5ba1, 0x5ba9, ++ 0x5bb1, 0x5bb9, 0x5bc1, 0x5bc9, 0x5bd1, 0x5bd9, 0x5be1, 0x5be9, ++ /* Node for range 0x2f85_ */ ++ 0x5bf1, 0x5bf9, 0x5c01, 0x5c09, 0x5c11, 0x5c19, 0x5c21, 0x5c29, ++ 0x5c31, 0x5c39, 0x5c41, 0x5c49, 0x5c51, 0x5c59, 0x5c61, 0x5c69, ++ /* Node for range 0x2f86_ */ ++ 0x5c71, 0x5c79, 0x5c81, 0x5c89, 0x5c91, 0x5c99, 0x5ca1, 0x5ca9, ++ 0x5cb1, 0x5cb9, 0x5cc1, 0x5cc9, 0x5cd1, 0x5cd9, 0x5ce1, 0x5ce9, ++ /* Node for range 0x2f87_ */ ++ 0x5cf1, 0x5cf9, 0x5d01, 0x5d09, 0x5d11, 0x5d19, 0x5d21, 0x5d29, ++ 0x5d31, 0x5d39, 0x5d41, 0x5d49, 0x5d51, 0x5d59, 0x5d61, 0x5d69, ++ /* Node for range 0x2f88_ */ ++ 0x5d71, 0x5d79, 0x5d81, 0x5d89, 0x5d91, 0x5d99, 0x5da1, 0x5da9, ++ 0x5db1, 0x5db9, 0x5dc1, 0x5dc9, 0x5dd1, 0x5dd9, 0x5de1, 0x5de9, ++ /* Node for range 0x2f89_ */ ++ 0x5df1, 0x5df9, 0x5e01, 0x5e09, 0x5e11, 0x5e19, 0x5e21, 0x5e29, ++ 0x5e31, 0x5e39, 0x5e41, 0x5e49, 0x5e51, 0x5e59, 0x5e61, 0x5e69, ++ /* Node for range 0x2f8a_ */ ++ 0x5e71, 0x5e79, 0x5e81, 0x5e89, 0x5e91, 0x5e99, 0x5ea1, 0x5ea9, ++ 0x5eb1, 0x5eb9, 0x5ec1, 0x5ec9, 0x5ed1, 0x5ed9, 0x5ee1, 0x5ee9, ++ /* Node for range 0x2f8b_ */ ++ 0x5ef1, 0x5ef9, 0x5f01, 0x5f09, 0x5f11, 0x5f19, 0x5f21, 0x5f29, ++ 0x5f31, 0x5f39, 0x5f41, 0x5f49, 0x5f51, 0x5f59, 0x5f61, 0x5f69, ++ /* Node for range 0x2f8c_ */ ++ 0x5f71, 0x5f79, 0x5f81, 0x5f89, 0x5f91, 0x5f99, 0x5fa1, 0x5fa9, ++ 0x5fb1, 0x5fb9, 0x5fc1, 0x5fc9, 0x5fd1, 0x5fd9, 0x5fe1, 0x5fe9, ++ /* Node for range 0x2f8d_ */ ++ 0x5ff1, 0x5ff9, 0x6001, 0x6009, 0x6011, 0x6019, 0x6021, 0x6029, ++ 0x6031, 0x6039, 0x6041, 0x6049, 0x6051, 0x6059, 0x6061, 0x6069, ++ /* Node for range 0x2f8e_ */ ++ 0x6071, 0x6079, 0x6081, 0x6089, 0x6091, 0x6099, 0x60a1, 0x60a9, ++ 0x60b1, 0x60b9, 0x60c1, 0x60c9, 0x60d1, 0x60d9, 0x60e1, 0x60e9, ++ /* Node for range 0x2f8f_ */ ++ 0x60f1, 0x60f9, 0x6101, 0x6109, 0x6111, 0x6119, 0x6121, 0x6129, ++ 0x6131, 0x6139, 0x6141, 0x6149, 0x6151, 0x6159, 0x6161, 0x6169, ++ /* Node for range 0x2f90_ */ ++ 0x6171, 0x6179, 0x6181, 0x6189, 0x6191, 0x6199, 0x61a1, 0x61a9, ++ 0x61b1, 0x61b9, 0x61c1, 0x61c9, 0x61d1, 0x61d9, 0x61e1, 0x61e9, ++ /* Node for range 0x2f91_ */ ++ 0x61f1, 0x61f9, 0x6201, 0x6209, 0x6211, 0x6219, 0x6221, 0x6229, ++ 0x6231, 0x6239, 0x6241, 0x6249, 0x6251, 0x6259, 0x6261, 0x6269, ++ /* Node for range 0x2f92_ */ ++ 0x6271, 0x6279, 0x6281, 0x6289, 0x6291, 0x6299, 0x62a1, 0x62a9, ++ 0x62b1, 0x62b9, 0x62c1, 0x62c9, 0x62d1, 0x62d9, 0x62e1, 0x62e9, ++ /* Node for range 0x2f93_ */ ++ 0x62f1, 0x62f9, 0x6301, 0x6309, 0x6311, 0x6319, 0x6321, 0x6329, ++ 0x6331, 0x6339, 0x6341, 0x6349, 0x6351, 0x6359, 0x6361, 0x6369, ++ /* Node for range 0x2f94_ */ ++ 0x6371, 0x6379, 0x6381, 0x6389, 0x6391, 0x6399, 0x63a1, 0x63a9, ++ 0x63b1, 0x63b9, 0x63c1, 0x63c9, 0x63d1, 0x63d9, 0x63e1, 0x63e9, ++ /* Node for range 0x2f95_ */ ++ 0x63f1, 0x63f9, 0x6401, 0x6409, 0x6411, 0x6419, 0x6421, 0x6429, ++ 0x6431, 0x6439, 0x6441, 0x6449, 0x6451, 0x6459, 0x6461, 0x6469, ++ /* Node for range 0x2f96_ */ ++ 0x6471, 0x6479, 0x6481, 0x6489, 0x6491, 0x6499, 0x64a1, 0x64a9, ++ 0x64b1, 0x64b9, 0x64c1, 0x64c9, 0x64d1, 0x64d9, 0x64e1, 0x64e9, ++ /* Node for range 0x2f97_ */ ++ 0x64f1, 0x64f9, 0x6501, 0x6509, 0x6511, 0x6519, 0x6521, 0x6529, ++ 0x6531, 0x6539, 0x6541, 0x6549, 0x6551, 0x6559, 0x6561, 0x6569, ++ /* Node for range 0x2f98_ */ ++ 0x6571, 0x6579, 0x6581, 0x6589, 0x6591, 0x6599, 0x65a1, 0x65a9, ++ 0x65b1, 0x65b9, 0x65c1, 0x65c9, 0x65d1, 0x65d9, 0x65e1, 0x65e9, ++ /* Node for range 0x2f99_ */ ++ 0x65f1, 0x65f9, 0x6601, 0x6609, 0x6611, 0x6619, 0x6621, 0x6629, ++ 0x6631, 0x6639, 0x6641, 0x6649, 0x6651, 0x6659, 0x6661, 0x6669, ++ /* Node for range 0x2f9a_ */ ++ 0x6671, 0x6679, 0x6681, 0x6689, 0x6691, 0x6699, 0x66a1, 0x66a9, ++ 0x66b1, 0x66b9, 0x66c1, 0x66c9, 0x66d1, 0x66d9, 0x66e1, 0x66e9, ++ /* Node for range 0x2f9b_ */ ++ 0x66f1, 0x66f9, 0x6701, 0x6709, 0x6711, 0x6719, 0x6721, 0x6729, ++ 0x6731, 0x6739, 0x6741, 0x6749, 0x6751, 0x6759, 0x6761, 0x6769, ++ /* Node for range 0x2f9c_ */ ++ 0x6771, 0x6779, 0x6781, 0x6789, 0x6791, 0x6799, 0x67a1, 0x67a9, ++ 0x67b1, 0x67b9, 0x67c1, 0x67c9, 0x67d1, 0x67d9, 0x67e1, 0x67e9, ++ /* Node for range 0x2f9d_ */ ++ 0x67f1, 0x67f9, 0x6801, 0x6809, 0x6811, 0x6819, 0x6821, 0x6829, ++ 0x6831, 0x6839, 0x6841, 0x6849, 0x6851, 0x6859, 0x6861, 0x6869, ++ /* Node for range 0x2f9e_ */ ++ 0x6871, 0x6879, 0x6881, 0x6889, 0x6891, 0x6899, 0x68a1, 0x68a9, ++ 0x68b1, 0x68b9, 0x68c1, 0x68c9, 0x68d1, 0x68d9, 0x68e1, 0x68e9, ++ /* Node for range 0x2f9f_ */ ++ 0x68f1, 0x68f9, 0x6901, 0x6909, 0x6911, 0x6919, 0x6921, 0x6929, ++ 0x6931, 0x6939, 0x6941, 0x6949, 0x6951, 0x6959, 0x6961, 0x6969, ++ /* Node for range 0x2fa0_ */ ++ 0x6971, 0x6979, 0x6981, 0x6989, 0x6991, 0x6999, 0x69a1, 0x69a9, ++ 0x69b1, 0x69b9, 0x69c1, 0x69c9, 0x69d1, 0x69d9, 0x69e1, 0x69e9, ++ /* Node for range 0x2fa1_ */ ++ 0x69f1, 0x69f9, 0x6a01, 0x6a09, 0x6a11, 0x6a19, 0x6a21, 0x6a29, ++ 0x6a31, 0x6a39, 0x6a41, 0x6a49, 0x6a51, 0x6a59, 0x0000, 0x0000, ++}; ++ ++static unicode_t apfs_nfd[] = { ++ 0x000041, 0x000300, 0x000041, 0x000301, 0x000041, 0x000302, ++ 0x000041, 0x000303, 0x000041, 0x000308, 0x000041, 0x00030a, ++ 0x000043, 0x000327, 0x000045, 0x000300, 0x000045, 0x000301, ++ 0x000045, 0x000302, 0x000045, 0x000308, 0x000049, 0x000300, ++ 0x000049, 0x000301, 0x000049, 0x000302, 0x000049, 0x000308, ++ 0x00004e, 0x000303, 0x00004f, 0x000300, 0x00004f, 0x000301, ++ 0x00004f, 0x000302, 0x00004f, 0x000303, 0x00004f, 0x000308, ++ 0x000055, 0x000300, 0x000055, 0x000301, 0x000055, 0x000302, ++ 0x000055, 0x000308, 0x000059, 0x000301, 0x000061, 0x000300, ++ 0x000061, 0x000301, 0x000061, 0x000302, 0x000061, 0x000303, ++ 0x000061, 0x000308, 0x000061, 0x00030a, 0x000063, 0x000327, ++ 0x000065, 0x000300, 0x000065, 0x000301, 0x000065, 0x000302, ++ 0x000065, 0x000308, 0x000069, 0x000300, 0x000069, 0x000301, ++ 0x000069, 0x000302, 0x000069, 0x000308, 0x00006e, 0x000303, ++ 0x00006f, 0x000300, 0x00006f, 0x000301, 0x00006f, 0x000302, ++ 0x00006f, 0x000303, 0x00006f, 0x000308, 0x000075, 0x000300, ++ 0x000075, 0x000301, 0x000075, 0x000302, 0x000075, 0x000308, ++ 0x000079, 0x000301, 0x000079, 0x000308, 0x000041, 0x000304, ++ 0x000061, 0x000304, 0x000041, 0x000306, 0x000061, 0x000306, ++ 0x000041, 0x000328, 0x000061, 0x000328, 0x000043, 0x000301, ++ 0x000063, 0x000301, 0x000043, 0x000302, 0x000063, 0x000302, ++ 0x000043, 0x000307, 0x000063, 0x000307, 0x000043, 0x00030c, ++ 0x000063, 0x00030c, 0x000044, 0x00030c, 0x000064, 0x00030c, ++ 0x000045, 0x000304, 0x000065, 0x000304, 0x000045, 0x000306, ++ 0x000065, 0x000306, 0x000045, 0x000307, 0x000065, 0x000307, ++ 0x000045, 0x000328, 0x000065, 0x000328, 0x000045, 0x00030c, ++ 0x000065, 0x00030c, 0x000047, 0x000302, 0x000067, 0x000302, ++ 0x000047, 0x000306, 0x000067, 0x000306, 0x000047, 0x000307, ++ 0x000067, 0x000307, 0x000047, 0x000327, 0x000067, 0x000327, ++ 0x000048, 0x000302, 0x000068, 0x000302, 0x000049, 0x000303, ++ 0x000069, 0x000303, 0x000049, 0x000304, 0x000069, 0x000304, ++ 0x000049, 0x000306, 0x000069, 0x000306, 0x000049, 0x000328, ++ 0x000069, 0x000328, 0x000049, 0x000307, 0x00004a, 0x000302, ++ 0x00006a, 0x000302, 0x00004b, 0x000327, 0x00006b, 0x000327, ++ 0x00004c, 0x000301, 0x00006c, 0x000301, 0x00004c, 0x000327, ++ 0x00006c, 0x000327, 0x00004c, 0x00030c, 0x00006c, 0x00030c, ++ 0x00004e, 0x000301, 0x00006e, 0x000301, 0x00004e, 0x000327, ++ 0x00006e, 0x000327, 0x00004e, 0x00030c, 0x00006e, 0x00030c, ++ 0x00004f, 0x000304, 0x00006f, 0x000304, 0x00004f, 0x000306, ++ 0x00006f, 0x000306, 0x00004f, 0x00030b, 0x00006f, 0x00030b, ++ 0x000052, 0x000301, 0x000072, 0x000301, 0x000052, 0x000327, ++ 0x000072, 0x000327, 0x000052, 0x00030c, 0x000072, 0x00030c, ++ 0x000053, 0x000301, 0x000073, 0x000301, 0x000053, 0x000302, ++ 0x000073, 0x000302, 0x000053, 0x000327, 0x000073, 0x000327, ++ 0x000053, 0x00030c, 0x000073, 0x00030c, 0x000054, 0x000327, ++ 0x000074, 0x000327, 0x000054, 0x00030c, 0x000074, 0x00030c, ++ 0x000055, 0x000303, 0x000075, 0x000303, 0x000055, 0x000304, ++ 0x000075, 0x000304, 0x000055, 0x000306, 0x000075, 0x000306, ++ 0x000055, 0x00030a, 0x000075, 0x00030a, 0x000055, 0x00030b, ++ 0x000075, 0x00030b, 0x000055, 0x000328, 0x000075, 0x000328, ++ 0x000057, 0x000302, 0x000077, 0x000302, 0x000059, 0x000302, ++ 0x000079, 0x000302, 0x000059, 0x000308, 0x00005a, 0x000301, ++ 0x00007a, 0x000301, 0x00005a, 0x000307, 0x00007a, 0x000307, ++ 0x00005a, 0x00030c, 0x00007a, 0x00030c, 0x00004f, 0x00031b, ++ 0x00006f, 0x00031b, 0x000055, 0x00031b, 0x000075, 0x00031b, ++ 0x000041, 0x00030c, 0x000061, 0x00030c, 0x000049, 0x00030c, ++ 0x000069, 0x00030c, 0x00004f, 0x00030c, 0x00006f, 0x00030c, ++ 0x000055, 0x00030c, 0x000075, 0x00030c, 0x000055, 0x000308, ++ 0x000304, 0x000075, 0x000308, 0x000304, 0x000055, 0x000308, ++ 0x000301, 0x000075, 0x000308, 0x000301, 0x000055, 0x000308, ++ 0x00030c, 0x000075, 0x000308, 0x00030c, 0x000055, 0x000308, ++ 0x000300, 0x000075, 0x000308, 0x000300, 0x000041, 0x000308, ++ 0x000304, 0x000061, 0x000308, 0x000304, 0x000041, 0x000307, ++ 0x000304, 0x000061, 0x000307, 0x000304, 0x0000c6, 0x000304, ++ 0x0000e6, 0x000304, 0x000047, 0x00030c, 0x000067, 0x00030c, ++ 0x00004b, 0x00030c, 0x00006b, 0x00030c, 0x00004f, 0x000328, ++ 0x00006f, 0x000328, 0x00004f, 0x000328, 0x000304, 0x00006f, ++ 0x000328, 0x000304, 0x0001b7, 0x00030c, 0x000292, 0x00030c, ++ 0x00006a, 0x00030c, 0x000047, 0x000301, 0x000067, 0x000301, ++ 0x00004e, 0x000300, 0x00006e, 0x000300, 0x000041, 0x00030a, ++ 0x000301, 0x000061, 0x00030a, 0x000301, 0x0000c6, 0x000301, ++ 0x0000e6, 0x000301, 0x0000d8, 0x000301, 0x0000f8, 0x000301, ++ 0x000041, 0x00030f, 0x000061, 0x00030f, 0x000041, 0x000311, ++ 0x000061, 0x000311, 0x000045, 0x00030f, 0x000065, 0x00030f, ++ 0x000045, 0x000311, 0x000065, 0x000311, 0x000049, 0x00030f, ++ 0x000069, 0x00030f, 0x000049, 0x000311, 0x000069, 0x000311, ++ 0x00004f, 0x00030f, 0x00006f, 0x00030f, 0x00004f, 0x000311, ++ 0x00006f, 0x000311, 0x000052, 0x00030f, 0x000072, 0x00030f, ++ 0x000052, 0x000311, 0x000072, 0x000311, 0x000055, 0x00030f, ++ 0x000075, 0x00030f, 0x000055, 0x000311, 0x000075, 0x000311, ++ 0x000053, 0x000326, 0x000073, 0x000326, 0x000054, 0x000326, ++ 0x000074, 0x000326, 0x000048, 0x00030c, 0x000068, 0x00030c, ++ 0x000041, 0x000307, 0x000061, 0x000307, 0x000045, 0x000327, ++ 0x000065, 0x000327, 0x00004f, 0x000308, 0x000304, 0x00006f, ++ 0x000308, 0x000304, 0x00004f, 0x000303, 0x000304, 0x00006f, ++ 0x000303, 0x000304, 0x00004f, 0x000307, 0x00006f, 0x000307, ++ 0x00004f, 0x000307, 0x000304, 0x00006f, 0x000307, 0x000304, ++ 0x000059, 0x000304, 0x000079, 0x000304, 0x000300, 0x000301, ++ 0x000313, 0x000308, 0x000301, 0x0002b9, 0x00003b, 0x0000a8, ++ 0x000301, 0x000391, 0x000301, 0x0000b7, 0x000395, 0x000301, ++ 0x000397, 0x000301, 0x000399, 0x000301, 0x00039f, 0x000301, ++ 0x0003a5, 0x000301, 0x0003a9, 0x000301, 0x0003b9, 0x000308, ++ 0x000301, 0x000399, 0x000308, 0x0003a5, 0x000308, 0x0003b1, ++ 0x000301, 0x0003b5, 0x000301, 0x0003b7, 0x000301, 0x0003b9, ++ 0x000301, 0x0003c5, 0x000308, 0x000301, 0x0003b9, 0x000308, ++ 0x0003c5, 0x000308, 0x0003bf, 0x000301, 0x0003c5, 0x000301, ++ 0x0003c9, 0x000301, 0x0003d2, 0x000301, 0x0003d2, 0x000308, ++ 0x000415, 0x000300, 0x000415, 0x000308, 0x000413, 0x000301, ++ 0x000406, 0x000308, 0x00041a, 0x000301, 0x000418, 0x000300, ++ 0x000423, 0x000306, 0x000418, 0x000306, 0x000438, 0x000306, ++ 0x000435, 0x000300, 0x000435, 0x000308, 0x000433, 0x000301, ++ 0x000456, 0x000308, 0x00043a, 0x000301, 0x000438, 0x000300, ++ 0x000443, 0x000306, 0x000474, 0x00030f, 0x000475, 0x00030f, ++ 0x000416, 0x000306, 0x000436, 0x000306, 0x000410, 0x000306, ++ 0x000430, 0x000306, 0x000410, 0x000308, 0x000430, 0x000308, ++ 0x000415, 0x000306, 0x000435, 0x000306, 0x0004d8, 0x000308, ++ 0x0004d9, 0x000308, 0x000416, 0x000308, 0x000436, 0x000308, ++ 0x000417, 0x000308, 0x000437, 0x000308, 0x000418, 0x000304, ++ 0x000438, 0x000304, 0x000418, 0x000308, 0x000438, 0x000308, ++ 0x00041e, 0x000308, 0x00043e, 0x000308, 0x0004e8, 0x000308, ++ 0x0004e9, 0x000308, 0x00042d, 0x000308, 0x00044d, 0x000308, ++ 0x000423, 0x000304, 0x000443, 0x000304, 0x000423, 0x000308, ++ 0x000443, 0x000308, 0x000423, 0x00030b, 0x000443, 0x00030b, ++ 0x000427, 0x000308, 0x000447, 0x000308, 0x00042b, 0x000308, ++ 0x00044b, 0x000308, 0x000627, 0x000653, 0x000627, 0x000654, ++ 0x000648, 0x000654, 0x000627, 0x000655, 0x00064a, 0x000654, ++ 0x0006d5, 0x000654, 0x0006c1, 0x000654, 0x0006d2, 0x000654, ++ 0x000928, 0x00093c, 0x000930, 0x00093c, 0x000933, 0x00093c, ++ 0x000915, 0x00093c, 0x000916, 0x00093c, 0x000917, 0x00093c, ++ 0x00091c, 0x00093c, 0x000921, 0x00093c, 0x000922, 0x00093c, ++ 0x00092b, 0x00093c, 0x00092f, 0x00093c, 0x0009c7, 0x0009be, ++ 0x0009c7, 0x0009d7, 0x0009a1, 0x0009bc, 0x0009a2, 0x0009bc, ++ 0x0009af, 0x0009bc, 0x000a32, 0x000a3c, 0x000a38, 0x000a3c, ++ 0x000a16, 0x000a3c, 0x000a17, 0x000a3c, 0x000a1c, 0x000a3c, ++ 0x000a2b, 0x000a3c, 0x000b47, 0x000b56, 0x000b47, 0x000b3e, ++ 0x000b47, 0x000b57, 0x000b21, 0x000b3c, 0x000b22, 0x000b3c, ++ 0x000b92, 0x000bd7, 0x000bc6, 0x000bbe, 0x000bc7, 0x000bbe, ++ 0x000bc6, 0x000bd7, 0x000c46, 0x000c56, 0x000cbf, 0x000cd5, ++ 0x000cc6, 0x000cd5, 0x000cc6, 0x000cd6, 0x000cc6, 0x000cc2, ++ 0x000cc6, 0x000cc2, 0x000cd5, 0x000d46, 0x000d3e, 0x000d47, ++ 0x000d3e, 0x000d46, 0x000d57, 0x000dd9, 0x000dca, 0x000dd9, ++ 0x000dcf, 0x000dd9, 0x000dcf, 0x000dca, 0x000dd9, 0x000ddf, ++ 0x000f42, 0x000fb7, 0x000f4c, 0x000fb7, 0x000f51, 0x000fb7, ++ 0x000f56, 0x000fb7, 0x000f5b, 0x000fb7, 0x000f40, 0x000fb5, ++ 0x000f71, 0x000f72, 0x000f71, 0x000f74, 0x000fb2, 0x000f80, ++ 0x000fb3, 0x000f80, 0x000f71, 0x000f80, 0x000f92, 0x000fb7, ++ 0x000f9c, 0x000fb7, 0x000fa1, 0x000fb7, 0x000fa6, 0x000fb7, ++ 0x000fab, 0x000fb7, 0x000f90, 0x000fb5, 0x001025, 0x00102e, ++ 0x001b05, 0x001b35, 0x001b07, 0x001b35, 0x001b09, 0x001b35, ++ 0x001b0b, 0x001b35, 0x001b0d, 0x001b35, 0x001b11, 0x001b35, ++ 0x001b3a, 0x001b35, 0x001b3c, 0x001b35, 0x001b3e, 0x001b35, ++ 0x001b3f, 0x001b35, 0x001b42, 0x001b35, 0x000041, 0x000325, ++ 0x000061, 0x000325, 0x000042, 0x000307, 0x000062, 0x000307, ++ 0x000042, 0x000323, 0x000062, 0x000323, 0x000042, 0x000331, ++ 0x000062, 0x000331, 0x000043, 0x000327, 0x000301, 0x000063, ++ 0x000327, 0x000301, 0x000044, 0x000307, 0x000064, 0x000307, ++ 0x000044, 0x000323, 0x000064, 0x000323, 0x000044, 0x000331, ++ 0x000064, 0x000331, 0x000044, 0x000327, 0x000064, 0x000327, ++ 0x000044, 0x00032d, 0x000064, 0x00032d, 0x000045, 0x000304, ++ 0x000300, 0x000065, 0x000304, 0x000300, 0x000045, 0x000304, ++ 0x000301, 0x000065, 0x000304, 0x000301, 0x000045, 0x00032d, ++ 0x000065, 0x00032d, 0x000045, 0x000330, 0x000065, 0x000330, ++ 0x000045, 0x000327, 0x000306, 0x000065, 0x000327, 0x000306, ++ 0x000046, 0x000307, 0x000066, 0x000307, 0x000047, 0x000304, ++ 0x000067, 0x000304, 0x000048, 0x000307, 0x000068, 0x000307, ++ 0x000048, 0x000323, 0x000068, 0x000323, 0x000048, 0x000308, ++ 0x000068, 0x000308, 0x000048, 0x000327, 0x000068, 0x000327, ++ 0x000048, 0x00032e, 0x000068, 0x00032e, 0x000049, 0x000330, ++ 0x000069, 0x000330, 0x000049, 0x000308, 0x000301, 0x000069, ++ 0x000308, 0x000301, 0x00004b, 0x000301, 0x00006b, 0x000301, ++ 0x00004b, 0x000323, 0x00006b, 0x000323, 0x00004b, 0x000331, ++ 0x00006b, 0x000331, 0x00004c, 0x000323, 0x00006c, 0x000323, ++ 0x00004c, 0x000323, 0x000304, 0x00006c, 0x000323, 0x000304, ++ 0x00004c, 0x000331, 0x00006c, 0x000331, 0x00004c, 0x00032d, ++ 0x00006c, 0x00032d, 0x00004d, 0x000301, 0x00006d, 0x000301, ++ 0x00004d, 0x000307, 0x00006d, 0x000307, 0x00004d, 0x000323, ++ 0x00006d, 0x000323, 0x00004e, 0x000307, 0x00006e, 0x000307, ++ 0x00004e, 0x000323, 0x00006e, 0x000323, 0x00004e, 0x000331, ++ 0x00006e, 0x000331, 0x00004e, 0x00032d, 0x00006e, 0x00032d, ++ 0x00004f, 0x000303, 0x000301, 0x00006f, 0x000303, 0x000301, ++ 0x00004f, 0x000303, 0x000308, 0x00006f, 0x000303, 0x000308, ++ 0x00004f, 0x000304, 0x000300, 0x00006f, 0x000304, 0x000300, ++ 0x00004f, 0x000304, 0x000301, 0x00006f, 0x000304, 0x000301, ++ 0x000050, 0x000301, 0x000070, 0x000301, 0x000050, 0x000307, ++ 0x000070, 0x000307, 0x000052, 0x000307, 0x000072, 0x000307, ++ 0x000052, 0x000323, 0x000072, 0x000323, 0x000052, 0x000323, ++ 0x000304, 0x000072, 0x000323, 0x000304, 0x000052, 0x000331, ++ 0x000072, 0x000331, 0x000053, 0x000307, 0x000073, 0x000307, ++ 0x000053, 0x000323, 0x000073, 0x000323, 0x000053, 0x000301, ++ 0x000307, 0x000073, 0x000301, 0x000307, 0x000053, 0x00030c, ++ 0x000307, 0x000073, 0x00030c, 0x000307, 0x000053, 0x000323, ++ 0x000307, 0x000073, 0x000323, 0x000307, 0x000054, 0x000307, ++ 0x000074, 0x000307, 0x000054, 0x000323, 0x000074, 0x000323, ++ 0x000054, 0x000331, 0x000074, 0x000331, 0x000054, 0x00032d, ++ 0x000074, 0x00032d, 0x000055, 0x000324, 0x000075, 0x000324, ++ 0x000055, 0x000330, 0x000075, 0x000330, 0x000055, 0x00032d, ++ 0x000075, 0x00032d, 0x000055, 0x000303, 0x000301, 0x000075, ++ 0x000303, 0x000301, 0x000055, 0x000304, 0x000308, 0x000075, ++ 0x000304, 0x000308, 0x000056, 0x000303, 0x000076, 0x000303, ++ 0x000056, 0x000323, 0x000076, 0x000323, 0x000057, 0x000300, ++ 0x000077, 0x000300, 0x000057, 0x000301, 0x000077, 0x000301, ++ 0x000057, 0x000308, 0x000077, 0x000308, 0x000057, 0x000307, ++ 0x000077, 0x000307, 0x000057, 0x000323, 0x000077, 0x000323, ++ 0x000058, 0x000307, 0x000078, 0x000307, 0x000058, 0x000308, ++ 0x000078, 0x000308, 0x000059, 0x000307, 0x000079, 0x000307, ++ 0x00005a, 0x000302, 0x00007a, 0x000302, 0x00005a, 0x000323, ++ 0x00007a, 0x000323, 0x00005a, 0x000331, 0x00007a, 0x000331, ++ 0x000068, 0x000331, 0x000074, 0x000308, 0x000077, 0x00030a, ++ 0x000079, 0x00030a, 0x00017f, 0x000307, 0x000041, 0x000323, ++ 0x000061, 0x000323, 0x000041, 0x000309, 0x000061, 0x000309, ++ 0x000041, 0x000302, 0x000301, 0x000061, 0x000302, 0x000301, ++ 0x000041, 0x000302, 0x000300, 0x000061, 0x000302, 0x000300, ++ 0x000041, 0x000302, 0x000309, 0x000061, 0x000302, 0x000309, ++ 0x000041, 0x000302, 0x000303, 0x000061, 0x000302, 0x000303, ++ 0x000041, 0x000323, 0x000302, 0x000061, 0x000323, 0x000302, ++ 0x000041, 0x000306, 0x000301, 0x000061, 0x000306, 0x000301, ++ 0x000041, 0x000306, 0x000300, 0x000061, 0x000306, 0x000300, ++ 0x000041, 0x000306, 0x000309, 0x000061, 0x000306, 0x000309, ++ 0x000041, 0x000306, 0x000303, 0x000061, 0x000306, 0x000303, ++ 0x000041, 0x000323, 0x000306, 0x000061, 0x000323, 0x000306, ++ 0x000045, 0x000323, 0x000065, 0x000323, 0x000045, 0x000309, ++ 0x000065, 0x000309, 0x000045, 0x000303, 0x000065, 0x000303, ++ 0x000045, 0x000302, 0x000301, 0x000065, 0x000302, 0x000301, ++ 0x000045, 0x000302, 0x000300, 0x000065, 0x000302, 0x000300, ++ 0x000045, 0x000302, 0x000309, 0x000065, 0x000302, 0x000309, ++ 0x000045, 0x000302, 0x000303, 0x000065, 0x000302, 0x000303, ++ 0x000045, 0x000323, 0x000302, 0x000065, 0x000323, 0x000302, ++ 0x000049, 0x000309, 0x000069, 0x000309, 0x000049, 0x000323, ++ 0x000069, 0x000323, 0x00004f, 0x000323, 0x00006f, 0x000323, ++ 0x00004f, 0x000309, 0x00006f, 0x000309, 0x00004f, 0x000302, ++ 0x000301, 0x00006f, 0x000302, 0x000301, 0x00004f, 0x000302, ++ 0x000300, 0x00006f, 0x000302, 0x000300, 0x00004f, 0x000302, ++ 0x000309, 0x00006f, 0x000302, 0x000309, 0x00004f, 0x000302, ++ 0x000303, 0x00006f, 0x000302, 0x000303, 0x00004f, 0x000323, ++ 0x000302, 0x00006f, 0x000323, 0x000302, 0x00004f, 0x00031b, ++ 0x000301, 0x00006f, 0x00031b, 0x000301, 0x00004f, 0x00031b, ++ 0x000300, 0x00006f, 0x00031b, 0x000300, 0x00004f, 0x00031b, ++ 0x000309, 0x00006f, 0x00031b, 0x000309, 0x00004f, 0x00031b, ++ 0x000303, 0x00006f, 0x00031b, 0x000303, 0x00004f, 0x00031b, ++ 0x000323, 0x00006f, 0x00031b, 0x000323, 0x000055, 0x000323, ++ 0x000075, 0x000323, 0x000055, 0x000309, 0x000075, 0x000309, ++ 0x000055, 0x00031b, 0x000301, 0x000075, 0x00031b, 0x000301, ++ 0x000055, 0x00031b, 0x000300, 0x000075, 0x00031b, 0x000300, ++ 0x000055, 0x00031b, 0x000309, 0x000075, 0x00031b, 0x000309, ++ 0x000055, 0x00031b, 0x000303, 0x000075, 0x00031b, 0x000303, ++ 0x000055, 0x00031b, 0x000323, 0x000075, 0x00031b, 0x000323, ++ 0x000059, 0x000300, 0x000079, 0x000300, 0x000059, 0x000323, ++ 0x000079, 0x000323, 0x000059, 0x000309, 0x000079, 0x000309, ++ 0x000059, 0x000303, 0x000079, 0x000303, 0x0003b1, 0x000313, ++ 0x0003b1, 0x000314, 0x0003b1, 0x000313, 0x000300, 0x0003b1, ++ 0x000314, 0x000300, 0x0003b1, 0x000313, 0x000301, 0x0003b1, ++ 0x000314, 0x000301, 0x0003b1, 0x000313, 0x000342, 0x0003b1, ++ 0x000314, 0x000342, 0x000391, 0x000313, 0x000391, 0x000314, ++ 0x000391, 0x000313, 0x000300, 0x000391, 0x000314, 0x000300, ++ 0x000391, 0x000313, 0x000301, 0x000391, 0x000314, 0x000301, ++ 0x000391, 0x000313, 0x000342, 0x000391, 0x000314, 0x000342, ++ 0x0003b5, 0x000313, 0x0003b5, 0x000314, 0x0003b5, 0x000313, ++ 0x000300, 0x0003b5, 0x000314, 0x000300, 0x0003b5, 0x000313, ++ 0x000301, 0x0003b5, 0x000314, 0x000301, 0x000395, 0x000313, ++ 0x000395, 0x000314, 0x000395, 0x000313, 0x000300, 0x000395, ++ 0x000314, 0x000300, 0x000395, 0x000313, 0x000301, 0x000395, ++ 0x000314, 0x000301, 0x0003b7, 0x000313, 0x0003b7, 0x000314, ++ 0x0003b7, 0x000313, 0x000300, 0x0003b7, 0x000314, 0x000300, ++ 0x0003b7, 0x000313, 0x000301, 0x0003b7, 0x000314, 0x000301, ++ 0x0003b7, 0x000313, 0x000342, 0x0003b7, 0x000314, 0x000342, ++ 0x000397, 0x000313, 0x000397, 0x000314, 0x000397, 0x000313, ++ 0x000300, 0x000397, 0x000314, 0x000300, 0x000397, 0x000313, ++ 0x000301, 0x000397, 0x000314, 0x000301, 0x000397, 0x000313, ++ 0x000342, 0x000397, 0x000314, 0x000342, 0x0003b9, 0x000313, ++ 0x0003b9, 0x000314, 0x0003b9, 0x000313, 0x000300, 0x0003b9, ++ 0x000314, 0x000300, 0x0003b9, 0x000313, 0x000301, 0x0003b9, ++ 0x000314, 0x000301, 0x0003b9, 0x000313, 0x000342, 0x0003b9, ++ 0x000314, 0x000342, 0x000399, 0x000313, 0x000399, 0x000314, ++ 0x000399, 0x000313, 0x000300, 0x000399, 0x000314, 0x000300, ++ 0x000399, 0x000313, 0x000301, 0x000399, 0x000314, 0x000301, ++ 0x000399, 0x000313, 0x000342, 0x000399, 0x000314, 0x000342, ++ 0x0003bf, 0x000313, 0x0003bf, 0x000314, 0x0003bf, 0x000313, ++ 0x000300, 0x0003bf, 0x000314, 0x000300, 0x0003bf, 0x000313, ++ 0x000301, 0x0003bf, 0x000314, 0x000301, 0x00039f, 0x000313, ++ 0x00039f, 0x000314, 0x00039f, 0x000313, 0x000300, 0x00039f, ++ 0x000314, 0x000300, 0x00039f, 0x000313, 0x000301, 0x00039f, ++ 0x000314, 0x000301, 0x0003c5, 0x000313, 0x0003c5, 0x000314, ++ 0x0003c5, 0x000313, 0x000300, 0x0003c5, 0x000314, 0x000300, ++ 0x0003c5, 0x000313, 0x000301, 0x0003c5, 0x000314, 0x000301, ++ 0x0003c5, 0x000313, 0x000342, 0x0003c5, 0x000314, 0x000342, ++ 0x0003a5, 0x000314, 0x0003a5, 0x000314, 0x000300, 0x0003a5, ++ 0x000314, 0x000301, 0x0003a5, 0x000314, 0x000342, 0x0003c9, ++ 0x000313, 0x0003c9, 0x000314, 0x0003c9, 0x000313, 0x000300, ++ 0x0003c9, 0x000314, 0x000300, 0x0003c9, 0x000313, 0x000301, ++ 0x0003c9, 0x000314, 0x000301, 0x0003c9, 0x000313, 0x000342, ++ 0x0003c9, 0x000314, 0x000342, 0x0003a9, 0x000313, 0x0003a9, ++ 0x000314, 0x0003a9, 0x000313, 0x000300, 0x0003a9, 0x000314, ++ 0x000300, 0x0003a9, 0x000313, 0x000301, 0x0003a9, 0x000314, ++ 0x000301, 0x0003a9, 0x000313, 0x000342, 0x0003a9, 0x000314, ++ 0x000342, 0x0003b1, 0x000300, 0x0003b1, 0x000301, 0x0003b5, ++ 0x000300, 0x0003b5, 0x000301, 0x0003b7, 0x000300, 0x0003b7, ++ 0x000301, 0x0003b9, 0x000300, 0x0003b9, 0x000301, 0x0003bf, ++ 0x000300, 0x0003bf, 0x000301, 0x0003c5, 0x000300, 0x0003c5, ++ 0x000301, 0x0003c9, 0x000300, 0x0003c9, 0x000301, 0x0003b1, ++ 0x000313, 0x000345, 0x0003b1, 0x000314, 0x000345, 0x0003b1, ++ 0x000313, 0x000300, 0x000345, 0x0003b1, 0x000314, 0x000300, ++ 0x000345, 0x0003b1, 0x000313, 0x000301, 0x000345, 0x0003b1, ++ 0x000314, 0x000301, 0x000345, 0x0003b1, 0x000313, 0x000342, ++ 0x000345, 0x0003b1, 0x000314, 0x000342, 0x000345, 0x000391, ++ 0x000313, 0x000345, 0x000391, 0x000314, 0x000345, 0x000391, ++ 0x000313, 0x000300, 0x000345, 0x000391, 0x000314, 0x000300, ++ 0x000345, 0x000391, 0x000313, 0x000301, 0x000345, 0x000391, ++ 0x000314, 0x000301, 0x000345, 0x000391, 0x000313, 0x000342, ++ 0x000345, 0x000391, 0x000314, 0x000342, 0x000345, 0x0003b7, ++ 0x000313, 0x000345, 0x0003b7, 0x000314, 0x000345, 0x0003b7, ++ 0x000313, 0x000300, 0x000345, 0x0003b7, 0x000314, 0x000300, ++ 0x000345, 0x0003b7, 0x000313, 0x000301, 0x000345, 0x0003b7, ++ 0x000314, 0x000301, 0x000345, 0x0003b7, 0x000313, 0x000342, ++ 0x000345, 0x0003b7, 0x000314, 0x000342, 0x000345, 0x000397, ++ 0x000313, 0x000345, 0x000397, 0x000314, 0x000345, 0x000397, ++ 0x000313, 0x000300, 0x000345, 0x000397, 0x000314, 0x000300, ++ 0x000345, 0x000397, 0x000313, 0x000301, 0x000345, 0x000397, ++ 0x000314, 0x000301, 0x000345, 0x000397, 0x000313, 0x000342, ++ 0x000345, 0x000397, 0x000314, 0x000342, 0x000345, 0x0003c9, ++ 0x000313, 0x000345, 0x0003c9, 0x000314, 0x000345, 0x0003c9, ++ 0x000313, 0x000300, 0x000345, 0x0003c9, 0x000314, 0x000300, ++ 0x000345, 0x0003c9, 0x000313, 0x000301, 0x000345, 0x0003c9, ++ 0x000314, 0x000301, 0x000345, 0x0003c9, 0x000313, 0x000342, ++ 0x000345, 0x0003c9, 0x000314, 0x000342, 0x000345, 0x0003a9, ++ 0x000313, 0x000345, 0x0003a9, 0x000314, 0x000345, 0x0003a9, ++ 0x000313, 0x000300, 0x000345, 0x0003a9, 0x000314, 0x000300, ++ 0x000345, 0x0003a9, 0x000313, 0x000301, 0x000345, 0x0003a9, ++ 0x000314, 0x000301, 0x000345, 0x0003a9, 0x000313, 0x000342, ++ 0x000345, 0x0003a9, 0x000314, 0x000342, 0x000345, 0x0003b1, ++ 0x000306, 0x0003b1, 0x000304, 0x0003b1, 0x000300, 0x000345, ++ 0x0003b1, 0x000345, 0x0003b1, 0x000301, 0x000345, 0x0003b1, ++ 0x000342, 0x0003b1, 0x000342, 0x000345, 0x000391, 0x000306, ++ 0x000391, 0x000304, 0x000391, 0x000300, 0x000391, 0x000301, ++ 0x000391, 0x000345, 0x0003b9, 0x0000a8, 0x000342, 0x0003b7, ++ 0x000300, 0x000345, 0x0003b7, 0x000345, 0x0003b7, 0x000301, ++ 0x000345, 0x0003b7, 0x000342, 0x0003b7, 0x000342, 0x000345, ++ 0x000395, 0x000300, 0x000395, 0x000301, 0x000397, 0x000300, ++ 0x000397, 0x000301, 0x000397, 0x000345, 0x001fbf, 0x000300, ++ 0x001fbf, 0x000301, 0x001fbf, 0x000342, 0x0003b9, 0x000306, ++ 0x0003b9, 0x000304, 0x0003b9, 0x000308, 0x000300, 0x0003b9, ++ 0x000308, 0x000301, 0x0003b9, 0x000342, 0x0003b9, 0x000308, ++ 0x000342, 0x000399, 0x000306, 0x000399, 0x000304, 0x000399, ++ 0x000300, 0x000399, 0x000301, 0x001ffe, 0x000300, 0x001ffe, ++ 0x000301, 0x001ffe, 0x000342, 0x0003c5, 0x000306, 0x0003c5, ++ 0x000304, 0x0003c5, 0x000308, 0x000300, 0x0003c5, 0x000308, ++ 0x000301, 0x0003c1, 0x000313, 0x0003c1, 0x000314, 0x0003c5, ++ 0x000342, 0x0003c5, 0x000308, 0x000342, 0x0003a5, 0x000306, ++ 0x0003a5, 0x000304, 0x0003a5, 0x000300, 0x0003a5, 0x000301, ++ 0x0003a1, 0x000314, 0x0000a8, 0x000300, 0x0000a8, 0x000301, ++ 0x000060, 0x0003c9, 0x000300, 0x000345, 0x0003c9, 0x000345, ++ 0x0003c9, 0x000301, 0x000345, 0x0003c9, 0x000342, 0x0003c9, ++ 0x000342, 0x000345, 0x00039f, 0x000300, 0x00039f, 0x000301, ++ 0x0003a9, 0x000300, 0x0003a9, 0x000301, 0x0003a9, 0x000345, ++ 0x0000b4, 0x002002, 0x002003, 0x0003a9, 0x00004b, 0x000041, ++ 0x00030a, 0x002190, 0x000338, 0x002192, 0x000338, 0x002194, ++ 0x000338, 0x0021d0, 0x000338, 0x0021d4, 0x000338, 0x0021d2, ++ 0x000338, 0x002203, 0x000338, 0x002208, 0x000338, 0x00220b, ++ 0x000338, 0x002223, 0x000338, 0x002225, 0x000338, 0x00223c, ++ 0x000338, 0x002243, 0x000338, 0x002245, 0x000338, 0x002248, ++ 0x000338, 0x00003d, 0x000338, 0x002261, 0x000338, 0x00224d, ++ 0x000338, 0x00003c, 0x000338, 0x00003e, 0x000338, 0x002264, ++ 0x000338, 0x002265, 0x000338, 0x002272, 0x000338, 0x002273, ++ 0x000338, 0x002276, 0x000338, 0x002277, 0x000338, 0x00227a, ++ 0x000338, 0x00227b, 0x000338, 0x002282, 0x000338, 0x002283, ++ 0x000338, 0x002286, 0x000338, 0x002287, 0x000338, 0x0022a2, ++ 0x000338, 0x0022a8, 0x000338, 0x0022a9, 0x000338, 0x0022ab, ++ 0x000338, 0x00227c, 0x000338, 0x00227d, 0x000338, 0x002291, ++ 0x000338, 0x002292, 0x000338, 0x0022b2, 0x000338, 0x0022b3, ++ 0x000338, 0x0022b4, 0x000338, 0x0022b5, 0x000338, 0x003008, ++ 0x003009, 0x002add, 0x000338, 0x00304b, 0x003099, 0x00304d, ++ 0x003099, 0x00304f, 0x003099, 0x003051, 0x003099, 0x003053, ++ 0x003099, 0x003055, 0x003099, 0x003057, 0x003099, 0x003059, ++ 0x003099, 0x00305b, 0x003099, 0x00305d, 0x003099, 0x00305f, ++ 0x003099, 0x003061, 0x003099, 0x003064, 0x003099, 0x003066, ++ 0x003099, 0x003068, 0x003099, 0x00306f, 0x003099, 0x00306f, ++ 0x00309a, 0x003072, 0x003099, 0x003072, 0x00309a, 0x003075, ++ 0x003099, 0x003075, 0x00309a, 0x003078, 0x003099, 0x003078, ++ 0x00309a, 0x00307b, 0x003099, 0x00307b, 0x00309a, 0x003046, ++ 0x003099, 0x00309d, 0x003099, 0x0030ab, 0x003099, 0x0030ad, ++ 0x003099, 0x0030af, 0x003099, 0x0030b1, 0x003099, 0x0030b3, ++ 0x003099, 0x0030b5, 0x003099, 0x0030b7, 0x003099, 0x0030b9, ++ 0x003099, 0x0030bb, 0x003099, 0x0030bd, 0x003099, 0x0030bf, ++ 0x003099, 0x0030c1, 0x003099, 0x0030c4, 0x003099, 0x0030c6, ++ 0x003099, 0x0030c8, 0x003099, 0x0030cf, 0x003099, 0x0030cf, ++ 0x00309a, 0x0030d2, 0x003099, 0x0030d2, 0x00309a, 0x0030d5, ++ 0x003099, 0x0030d5, 0x00309a, 0x0030d8, 0x003099, 0x0030d8, ++ 0x00309a, 0x0030db, 0x003099, 0x0030db, 0x00309a, 0x0030a6, ++ 0x003099, 0x0030ef, 0x003099, 0x0030f0, 0x003099, 0x0030f1, ++ 0x003099, 0x0030f2, 0x003099, 0x0030fd, 0x003099, 0x008c48, ++ 0x0066f4, 0x008eca, 0x008cc8, 0x006ed1, 0x004e32, 0x0053e5, ++ 0x009f9c, 0x009f9c, 0x005951, 0x0091d1, 0x005587, 0x005948, ++ 0x0061f6, 0x007669, 0x007f85, 0x00863f, 0x0087ba, 0x0088f8, ++ 0x00908f, 0x006a02, 0x006d1b, 0x0070d9, 0x0073de, 0x00843d, ++ 0x00916a, 0x0099f1, 0x004e82, 0x005375, 0x006b04, 0x00721b, ++ 0x00862d, 0x009e1e, 0x005d50, 0x006feb, 0x0085cd, 0x008964, ++ 0x0062c9, 0x0081d8, 0x00881f, 0x005eca, 0x006717, 0x006d6a, ++ 0x0072fc, 0x0090ce, 0x004f86, 0x0051b7, 0x0052de, 0x0064c4, ++ 0x006ad3, 0x007210, 0x0076e7, 0x008001, 0x008606, 0x00865c, ++ 0x008def, 0x009732, 0x009b6f, 0x009dfa, 0x00788c, 0x00797f, ++ 0x007da0, 0x0083c9, 0x009304, 0x009e7f, 0x008ad6, 0x0058df, ++ 0x005f04, 0x007c60, 0x00807e, 0x007262, 0x0078ca, 0x008cc2, ++ 0x0096f7, 0x0058d8, 0x005c62, 0x006a13, 0x006dda, 0x006f0f, ++ 0x007d2f, 0x007e37, 0x00964b, 0x0052d2, 0x00808b, 0x0051dc, ++ 0x0051cc, 0x007a1c, 0x007dbe, 0x0083f1, 0x009675, 0x008b80, ++ 0x0062cf, 0x006a02, 0x008afe, 0x004e39, 0x005be7, 0x006012, ++ 0x007387, 0x007570, 0x005317, 0x0078fb, 0x004fbf, 0x005fa9, ++ 0x004e0d, 0x006ccc, 0x006578, 0x007d22, 0x0053c3, 0x00585e, ++ 0x007701, 0x008449, 0x008aaa, 0x006bba, 0x008fb0, 0x006c88, ++ 0x0062fe, 0x0082e5, 0x0063a0, 0x007565, 0x004eae, 0x005169, ++ 0x0051c9, 0x006881, 0x007ce7, 0x00826f, 0x008ad2, 0x0091cf, ++ 0x0052f5, 0x005442, 0x005973, 0x005eec, 0x0065c5, 0x006ffe, ++ 0x00792a, 0x0095ad, 0x009a6a, 0x009e97, 0x009ece, 0x00529b, ++ 0x0066c6, 0x006b77, 0x008f62, 0x005e74, 0x006190, 0x006200, ++ 0x00649a, 0x006f23, 0x007149, 0x007489, 0x0079ca, 0x007df4, ++ 0x00806f, 0x008f26, 0x0084ee, 0x009023, 0x00934a, 0x005217, ++ 0x0052a3, 0x0054bd, 0x0070c8, 0x0088c2, 0x008aaa, 0x005ec9, ++ 0x005ff5, 0x00637b, 0x006bae, 0x007c3e, 0x007375, 0x004ee4, ++ 0x0056f9, 0x005be7, 0x005dba, 0x00601c, 0x0073b2, 0x007469, ++ 0x007f9a, 0x008046, 0x009234, 0x0096f6, 0x009748, 0x009818, ++ 0x004f8b, 0x0079ae, 0x0091b4, 0x0096b8, 0x0060e1, 0x004e86, ++ 0x0050da, 0x005bee, 0x005c3f, 0x006599, 0x006a02, 0x0071ce, ++ 0x007642, 0x0084fc, 0x00907c, 0x009f8d, 0x006688, 0x00962e, ++ 0x005289, 0x00677b, 0x0067f3, 0x006d41, 0x006e9c, 0x007409, ++ 0x007559, 0x00786b, 0x007d10, 0x00985e, 0x00516d, 0x00622e, ++ 0x009678, 0x00502b, 0x005d19, 0x006dea, 0x008f2a, 0x005f8b, ++ 0x006144, 0x006817, 0x007387, 0x009686, 0x005229, 0x00540f, ++ 0x005c65, 0x006613, 0x00674e, 0x0068a8, 0x006ce5, 0x007406, ++ 0x0075e2, 0x007f79, 0x0088cf, 0x0088e1, 0x0091cc, 0x0096e2, ++ 0x00533f, 0x006eba, 0x00541d, 0x0071d0, 0x007498, 0x0085fa, ++ 0x0096a3, 0x009c57, 0x009e9f, 0x006797, 0x006dcb, 0x0081e8, ++ 0x007acb, 0x007b20, 0x007c92, 0x0072c0, 0x007099, 0x008b58, ++ 0x004ec0, 0x008336, 0x00523a, 0x005207, 0x005ea6, 0x0062d3, ++ 0x007cd6, 0x005b85, 0x006d1e, 0x0066b4, 0x008f3b, 0x00884c, ++ 0x00964d, 0x00898b, 0x005ed3, 0x005140, 0x0055c0, 0x00585a, ++ 0x006674, 0x0051de, 0x00732a, 0x0076ca, 0x00793c, 0x00795e, ++ 0x007965, 0x00798f, 0x009756, 0x007cbe, 0x007fbd, 0x008612, ++ 0x008af8, 0x009038, 0x0090fd, 0x0098ef, 0x0098fc, 0x009928, ++ 0x009db4, 0x0090de, 0x0096b7, 0x004fae, 0x0050e7, 0x00514d, ++ 0x0052c9, 0x0052e4, 0x005351, 0x00559d, 0x005606, 0x005668, ++ 0x005840, 0x0058a8, 0x005c64, 0x005c6e, 0x006094, 0x006168, ++ 0x00618e, 0x0061f2, 0x00654f, 0x0065e2, 0x006691, 0x006885, ++ 0x006d77, 0x006e1a, 0x006f22, 0x00716e, 0x00722b, 0x007422, ++ 0x007891, 0x00793e, 0x007949, 0x007948, 0x007950, 0x007956, ++ 0x00795d, 0x00798d, 0x00798e, 0x007a40, 0x007a81, 0x007bc0, ++ 0x007df4, 0x007e09, 0x007e41, 0x007f72, 0x008005, 0x0081ed, ++ 0x008279, 0x008279, 0x008457, 0x008910, 0x008996, 0x008b01, ++ 0x008b39, 0x008cd3, 0x008d08, 0x008fb6, 0x009038, 0x0096e3, ++ 0x0097ff, 0x00983b, 0x006075, 0x0242ee, 0x008218, 0x004e26, ++ 0x0051b5, 0x005168, 0x004f80, 0x005145, 0x005180, 0x0052c7, ++ 0x0052fa, 0x00559d, 0x005555, 0x005599, 0x0055e2, 0x00585a, ++ 0x0058b3, 0x005944, 0x005954, 0x005a62, 0x005b28, 0x005ed2, ++ 0x005ed9, 0x005f69, 0x005fad, 0x0060d8, 0x00614e, 0x006108, ++ 0x00618e, 0x006160, 0x0061f2, 0x006234, 0x0063c4, 0x00641c, ++ 0x006452, 0x006556, 0x006674, 0x006717, 0x00671b, 0x006756, ++ 0x006b79, 0x006bba, 0x006d41, 0x006edb, 0x006ecb, 0x006f22, ++ 0x00701e, 0x00716e, 0x0077a7, 0x007235, 0x0072af, 0x00732a, ++ 0x007471, 0x007506, 0x00753b, 0x00761d, 0x00761f, 0x0076ca, ++ 0x0076db, 0x0076f4, 0x00774a, 0x007740, 0x0078cc, 0x007ab1, ++ 0x007bc0, 0x007c7b, 0x007d5b, 0x007df4, 0x007f3e, 0x008005, ++ 0x008352, 0x0083ef, 0x008779, 0x008941, 0x008986, 0x008996, ++ 0x008abf, 0x008af8, 0x008acb, 0x008b01, 0x008afe, 0x008aed, ++ 0x008b39, 0x008b8a, 0x008d08, 0x008f38, 0x009072, 0x009199, ++ 0x009276, 0x00967c, 0x0096e3, 0x009756, 0x0097db, 0x0097ff, ++ 0x00980b, 0x00983b, 0x009b12, 0x009f9c, 0x02284a, 0x022844, ++ 0x0233d5, 0x003b9d, 0x004018, 0x004039, 0x025249, 0x025cd0, ++ 0x027ed3, 0x009f43, 0x009f8e, 0x0005d9, 0x0005b4, 0x0005f2, ++ 0x0005b7, 0x0005e9, 0x0005c1, 0x0005e9, 0x0005c2, 0x0005e9, ++ 0x0005bc, 0x0005c1, 0x0005e9, 0x0005bc, 0x0005c2, 0x0005d0, ++ 0x0005b7, 0x0005d0, 0x0005b8, 0x0005d0, 0x0005bc, 0x0005d1, ++ 0x0005bc, 0x0005d2, 0x0005bc, 0x0005d3, 0x0005bc, 0x0005d4, ++ 0x0005bc, 0x0005d5, 0x0005bc, 0x0005d6, 0x0005bc, 0x0005d8, ++ 0x0005bc, 0x0005d9, 0x0005bc, 0x0005da, 0x0005bc, 0x0005db, ++ 0x0005bc, 0x0005dc, 0x0005bc, 0x0005de, 0x0005bc, 0x0005e0, ++ 0x0005bc, 0x0005e1, 0x0005bc, 0x0005e3, 0x0005bc, 0x0005e4, ++ 0x0005bc, 0x0005e6, 0x0005bc, 0x0005e7, 0x0005bc, 0x0005e8, ++ 0x0005bc, 0x0005e9, 0x0005bc, 0x0005ea, 0x0005bc, 0x0005d5, ++ 0x0005b9, 0x0005d1, 0x0005bf, 0x0005db, 0x0005bf, 0x0005e4, ++ 0x0005bf, 0x011099, 0x0110ba, 0x01109b, 0x0110ba, 0x0110a5, ++ 0x0110ba, 0x011131, 0x011127, 0x011132, 0x011127, 0x011347, ++ 0x01133e, 0x011347, 0x011357, 0x0114b9, 0x0114ba, 0x0114b9, ++ 0x0114b0, 0x0114b9, 0x0114bd, 0x0115b8, 0x0115af, 0x0115b9, ++ 0x0115af, 0x01d157, 0x01d165, 0x01d158, 0x01d165, 0x01d158, ++ 0x01d165, 0x01d16e, 0x01d158, 0x01d165, 0x01d16f, 0x01d158, ++ 0x01d165, 0x01d170, 0x01d158, 0x01d165, 0x01d171, 0x01d158, ++ 0x01d165, 0x01d172, 0x01d1b9, 0x01d165, 0x01d1ba, 0x01d165, ++ 0x01d1b9, 0x01d165, 0x01d16e, 0x01d1ba, 0x01d165, 0x01d16e, ++ 0x01d1b9, 0x01d165, 0x01d16f, 0x01d1ba, 0x01d165, 0x01d16f, ++ 0x004e3d, 0x004e38, 0x004e41, 0x020122, 0x004f60, 0x004fae, ++ 0x004fbb, 0x005002, 0x00507a, 0x005099, 0x0050e7, 0x0050cf, ++ 0x00349e, 0x02063a, 0x00514d, 0x005154, 0x005164, 0x005177, ++ 0x02051c, 0x0034b9, 0x005167, 0x00518d, 0x02054b, 0x005197, ++ 0x0051a4, 0x004ecc, 0x0051ac, 0x0051b5, 0x0291df, 0x0051f5, ++ 0x005203, 0x0034df, 0x00523b, 0x005246, 0x005272, 0x005277, ++ 0x003515, 0x0052c7, 0x0052c9, 0x0052e4, 0x0052fa, 0x005305, ++ 0x005306, 0x005317, 0x005349, 0x005351, 0x00535a, 0x005373, ++ 0x00537d, 0x00537f, 0x00537f, 0x00537f, 0x020a2c, 0x007070, ++ 0x0053ca, 0x0053df, 0x020b63, 0x0053eb, 0x0053f1, 0x005406, ++ 0x00549e, 0x005438, 0x005448, 0x005468, 0x0054a2, 0x0054f6, ++ 0x005510, 0x005553, 0x005563, 0x005584, 0x005584, 0x005599, ++ 0x0055ab, 0x0055b3, 0x0055c2, 0x005716, 0x005606, 0x005717, ++ 0x005651, 0x005674, 0x005207, 0x0058ee, 0x0057ce, 0x0057f4, ++ 0x00580d, 0x00578b, 0x005832, 0x005831, 0x0058ac, 0x0214e4, ++ 0x0058f2, 0x0058f7, 0x005906, 0x00591a, 0x005922, 0x005962, ++ 0x0216a8, 0x0216ea, 0x0059ec, 0x005a1b, 0x005a27, 0x0059d8, ++ 0x005a66, 0x0036ee, 0x0036fc, 0x005b08, 0x005b3e, 0x005b3e, ++ 0x0219c8, 0x005bc3, 0x005bd8, 0x005be7, 0x005bf3, 0x021b18, ++ 0x005bff, 0x005c06, 0x005f53, 0x005c22, 0x003781, 0x005c60, ++ 0x005c6e, 0x005cc0, 0x005c8d, 0x021de4, 0x005d43, 0x021de6, ++ 0x005d6e, 0x005d6b, 0x005d7c, 0x005de1, 0x005de2, 0x00382f, ++ 0x005dfd, 0x005e28, 0x005e3d, 0x005e69, 0x003862, 0x022183, ++ 0x00387c, 0x005eb0, 0x005eb3, 0x005eb6, 0x005eca, 0x02a392, ++ 0x005efe, 0x022331, 0x022331, 0x008201, 0x005f22, 0x005f22, ++ 0x0038c7, 0x0232b8, 0x0261da, 0x005f62, 0x005f6b, 0x0038e3, ++ 0x005f9a, 0x005fcd, 0x005fd7, 0x005ff9, 0x006081, 0x00393a, ++ 0x00391c, 0x006094, 0x0226d4, 0x0060c7, 0x006148, 0x00614c, ++ 0x00614e, 0x00614c, 0x00617a, 0x00618e, 0x0061b2, 0x0061a4, ++ 0x0061af, 0x0061de, 0x0061f2, 0x0061f6, 0x006210, 0x00621b, ++ 0x00625d, 0x0062b1, 0x0062d4, 0x006350, 0x022b0c, 0x00633d, ++ 0x0062fc, 0x006368, 0x006383, 0x0063e4, 0x022bf1, 0x006422, ++ 0x0063c5, 0x0063a9, 0x003a2e, 0x006469, 0x00647e, 0x00649d, ++ 0x006477, 0x003a6c, 0x00654f, 0x00656c, 0x02300a, 0x0065e3, ++ 0x0066f8, 0x006649, 0x003b19, 0x006691, 0x003b08, 0x003ae4, ++ 0x005192, 0x005195, 0x006700, 0x00669c, 0x0080ad, 0x0043d9, ++ 0x006717, 0x00671b, 0x006721, 0x00675e, 0x006753, 0x0233c3, ++ 0x003b49, 0x0067fa, 0x006785, 0x006852, 0x006885, 0x02346d, ++ 0x00688e, 0x00681f, 0x006914, 0x003b9d, 0x006942, 0x0069a3, ++ 0x0069ea, 0x006aa8, 0x0236a3, 0x006adb, 0x003c18, 0x006b21, ++ 0x0238a7, 0x006b54, 0x003c4e, 0x006b72, 0x006b9f, 0x006bba, ++ 0x006bbb, 0x023a8d, 0x021d0b, 0x023afa, 0x006c4e, 0x023cbc, ++ 0x006cbf, 0x006ccd, 0x006c67, 0x006d16, 0x006d3e, 0x006d77, ++ 0x006d41, 0x006d69, 0x006d78, 0x006d85, 0x023d1e, 0x006d34, ++ 0x006e2f, 0x006e6e, 0x003d33, 0x006ecb, 0x006ec7, 0x023ed1, ++ 0x006df9, 0x006f6e, 0x023f5e, 0x023f8e, 0x006fc6, 0x007039, ++ 0x00701e, 0x00701b, 0x003d96, 0x00704a, 0x00707d, 0x007077, ++ 0x0070ad, 0x020525, 0x007145, 0x024263, 0x00719c, 0x0243ab, ++ 0x007228, 0x007235, 0x007250, 0x024608, 0x007280, 0x007295, ++ 0x024735, 0x024814, 0x00737a, 0x00738b, 0x003eac, 0x0073a5, ++ 0x003eb8, 0x003eb8, 0x007447, 0x00745c, 0x007471, 0x007485, ++ 0x0074ca, 0x003f1b, 0x007524, 0x024c36, 0x00753e, 0x024c92, ++ 0x007570, 0x02219f, 0x007610, 0x024fa1, 0x024fb8, 0x025044, ++ 0x003ffc, 0x004008, 0x0076f4, 0x0250f3, 0x0250f2, 0x025119, ++ 0x025133, 0x00771e, 0x00771f, 0x00771f, 0x00774a, 0x004039, ++ 0x00778b, 0x004046, 0x004096, 0x02541d, 0x00784e, 0x00788c, ++ 0x0078cc, 0x0040e3, 0x025626, 0x007956, 0x02569a, 0x0256c5, ++ 0x00798f, 0x0079eb, 0x00412f, 0x007a40, 0x007a4a, 0x007a4f, ++ 0x02597c, 0x025aa7, 0x025aa7, 0x007aee, 0x004202, 0x025bab, ++ 0x007bc6, 0x007bc9, 0x004227, 0x025c80, 0x007cd2, 0x0042a0, ++ 0x007ce8, 0x007ce3, 0x007d00, 0x025f86, 0x007d63, 0x004301, ++ 0x007dc7, 0x007e02, 0x007e45, 0x004334, 0x026228, 0x026247, ++ 0x004359, 0x0262d9, 0x007f7a, 0x02633e, 0x007f95, 0x007ffa, ++ 0x008005, 0x0264da, 0x026523, 0x008060, 0x0265a8, 0x008070, ++ 0x02335f, 0x0043d5, 0x0080b2, 0x008103, 0x00440b, 0x00813e, ++ 0x005ab5, 0x0267a7, 0x0267b5, 0x023393, 0x02339c, 0x008201, ++ 0x008204, 0x008f9e, 0x00446b, 0x008291, 0x00828b, 0x00829d, ++ 0x0052b3, 0x0082b1, 0x0082b3, 0x0082bd, 0x0082e6, 0x026b3c, ++ 0x0082e5, 0x00831d, 0x008363, 0x0083ad, 0x008323, 0x0083bd, ++ 0x0083e7, 0x008457, 0x008353, 0x0083ca, 0x0083cc, 0x0083dc, ++ 0x026c36, 0x026d6b, 0x026cd5, 0x00452b, 0x0084f1, 0x0084f3, ++ 0x008516, 0x0273ca, 0x008564, 0x026f2c, 0x00455d, 0x004561, ++ 0x026fb1, 0x0270d2, 0x00456b, 0x008650, 0x00865c, 0x008667, ++ 0x008669, 0x0086a9, 0x008688, 0x00870e, 0x0086e2, 0x008779, ++ 0x008728, 0x00876b, 0x008786, 0x0045d7, 0x0087e1, 0x008801, ++ 0x0045f9, 0x008860, 0x008863, 0x027667, 0x0088d7, 0x0088de, ++ 0x004635, 0x0088fa, 0x0034bb, 0x0278ae, 0x027966, 0x0046be, ++ 0x0046c7, 0x008aa0, 0x008aed, 0x008b8a, 0x008c55, 0x027ca8, ++ 0x008cab, 0x008cc1, 0x008d1b, 0x008d77, 0x027f2f, 0x020804, ++ 0x008dcb, 0x008dbc, 0x008df0, 0x0208de, 0x008ed4, 0x008f38, ++ 0x0285d2, 0x0285ed, 0x009094, 0x0090f1, 0x009111, 0x02872e, ++ 0x00911b, 0x009238, 0x0092d7, 0x0092d8, 0x00927c, 0x0093f9, ++ 0x009415, 0x028bfa, 0x00958b, 0x004995, 0x0095b7, 0x028d77, ++ 0x0049e6, 0x0096c3, 0x005db2, 0x009723, 0x029145, 0x02921a, ++ 0x004a6e, 0x004a76, 0x0097e0, 0x02940a, 0x004ab2, 0x029496, ++ 0x00980b, 0x00980b, 0x009829, 0x0295b6, 0x0098e2, 0x004b33, ++ 0x009929, 0x0099a7, 0x0099c2, 0x0099fe, 0x004bce, 0x029b30, ++ 0x009b12, 0x009c40, 0x009cfd, 0x004cce, 0x004ced, 0x009d67, ++ 0x02a0ce, 0x004cf8, 0x02a105, 0x02a20e, 0x02a291, 0x009ebb, ++ 0x004d56, 0x009ef9, 0x009efe, 0x009f05, 0x009f0f, 0x009f16, ++ 0x009f3b, 0x02a600, ++}; ++ ++static u16 apfs_cf_trie[] = { ++ /* Node for range 0x_____ */ ++ 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0____ */ ++ 0x0003, 0x0004, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, ++ /* Node for range 0x1____ */ ++ 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x0000, ++ /* Node for range 0x00___ */ ++ 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01___ */ ++ 0x0011, 0x0000, 0x0000, 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0013, 0x0000, 0x0014, 0x0015, ++ /* Node for range 0x02___ */ ++ 0x0000, 0x0016, 0x0000, 0x0000, 0x0017, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0018, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0a___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0019, 0x001a, ++ 0x0000, 0x0000, 0x0000, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0f___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x001c, 0x0000, 0x0000, 0x0000, 0x001d, ++ /* Node for range 0x10___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x001e, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x11___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1e___ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0021, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x000__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0022, 0x0023, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0024, 0x0025, 0x0026, 0x0000, 0x0000, ++ /* Node for range 0x001__ */ ++ 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, ++ 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, ++ /* Node for range 0x002__ */ ++ 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003d, ++ 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, ++ /* Node for range 0x004__ */ ++ 0x0046, 0x0047, 0x0048, 0x0000, 0x0000, 0x0000, 0x0049, 0x004a, ++ 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, ++ /* Node for range 0x005__ */ ++ 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0000, 0x0000, ++ 0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x010__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x005a, 0x005b, 0x005c, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x013__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x005d, ++ /* Node for range 0x01c__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x005e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01e__ */ ++ 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, ++ 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, ++ /* Node for range 0x01f__ */ ++ 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0000, ++ 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, ++ /* Node for range 0x021__ */ ++ 0x0000, 0x0000, 0x007e, 0x007f, 0x0000, 0x0000, 0x0080, 0x0000, ++ 0x0081, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x024__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0082, 0x0083, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x02c__ */ ++ 0x0084, 0x0085, 0x0086, 0x0000, 0x0000, 0x0000, 0x0087, 0x0088, ++ 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, ++ /* Node for range 0x0a6__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0091, 0x0092, 0x0093, 0x0000, ++ 0x0094, 0x0095, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0a7__ */ ++ 0x0000, 0x0000, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, ++ 0x009c, 0x009d, 0x009e, 0x009f, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0ab__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00a0, ++ 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0fb__ */ ++ 0x00a5, 0x00a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0ff__ */ ++ 0x0000, 0x0000, 0x00a7, 0x00a8, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x104__ */ ++ 0x00a9, 0x00aa, 0x00ab, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x00ac, 0x00ad, 0x00ae, 0x0000, 0x0000, ++ /* Node for range 0x10c__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x118__ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x00b3, 0x00b4, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1e9__ */ ++ 0x00b5, 0x00b6, 0x00b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0004_ */ ++ 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, ++ 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, ++ /* Node for range 0x0005_ */ ++ 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, ++ 0x00b9, 0x00c1, 0x00c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x000b_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d1, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x000c_ */ ++ 0x00d9, 0x00e1, 0x00e9, 0x00f1, 0x00f9, 0x0101, 0x0109, 0x0111, ++ 0x0119, 0x0121, 0x0129, 0x0131, 0x0139, 0x0141, 0x0149, 0x0151, ++ /* Node for range 0x000d_ */ ++ 0x0159, 0x0161, 0x0169, 0x0171, 0x0179, 0x0181, 0x0189, 0x0000, ++ 0x0191, 0x0199, 0x01a1, 0x01a9, 0x01b1, 0x01b9, 0x01c1, 0x01ca, ++ /* Node for range 0x0010_ */ ++ 0x01d9, 0x0000, 0x01e1, 0x0000, 0x01e9, 0x0000, 0x01f1, 0x0000, ++ 0x01f9, 0x0000, 0x0201, 0x0000, 0x0209, 0x0000, 0x0211, 0x0000, ++ /* Node for range 0x0011_ */ ++ 0x0219, 0x0000, 0x0221, 0x0000, 0x0229, 0x0000, 0x0231, 0x0000, ++ 0x0239, 0x0000, 0x0241, 0x0000, 0x0249, 0x0000, 0x0251, 0x0000, ++ /* Node for range 0x0012_ */ ++ 0x0259, 0x0000, 0x0261, 0x0000, 0x0269, 0x0000, 0x0271, 0x0000, ++ 0x0279, 0x0000, 0x0281, 0x0000, 0x0289, 0x0000, 0x0291, 0x0000, ++ /* Node for range 0x0013_ */ ++ 0x029a, 0x0000, 0x02a9, 0x0000, 0x02b1, 0x0000, 0x02b9, 0x0000, ++ 0x0000, 0x02c1, 0x0000, 0x02c9, 0x0000, 0x02d1, 0x0000, 0x02d9, ++ /* Node for range 0x0014_ */ ++ 0x0000, 0x02e1, 0x0000, 0x02e9, 0x0000, 0x02f1, 0x0000, 0x02f9, ++ 0x0000, 0x0302, 0x0311, 0x0000, 0x0319, 0x0000, 0x0321, 0x0000, ++ /* Node for range 0x0015_ */ ++ 0x0329, 0x0000, 0x0331, 0x0000, 0x0339, 0x0000, 0x0341, 0x0000, ++ 0x0349, 0x0000, 0x0351, 0x0000, 0x0359, 0x0000, 0x0361, 0x0000, ++ /* Node for range 0x0016_ */ ++ 0x0369, 0x0000, 0x0371, 0x0000, 0x0379, 0x0000, 0x0381, 0x0000, ++ 0x0389, 0x0000, 0x0391, 0x0000, 0x0399, 0x0000, 0x03a1, 0x0000, ++ /* Node for range 0x0017_ */ ++ 0x03a9, 0x0000, 0x03b1, 0x0000, 0x03b9, 0x0000, 0x03c1, 0x0000, ++ 0x03c9, 0x03d1, 0x0000, 0x03d9, 0x0000, 0x03e1, 0x0000, 0x03e9, ++ /* Node for range 0x0018_ */ ++ 0x0000, 0x03f1, 0x03f9, 0x0000, 0x0401, 0x0000, 0x0409, 0x0411, ++ 0x0000, 0x0419, 0x0421, 0x0429, 0x0000, 0x0000, 0x0431, 0x0439, ++ /* Node for range 0x0019_ */ ++ 0x0441, 0x0449, 0x0000, 0x0451, 0x0459, 0x0000, 0x0461, 0x0469, ++ 0x0471, 0x0000, 0x0000, 0x0000, 0x0479, 0x0481, 0x0000, 0x0489, ++ /* Node for range 0x001a_ */ ++ 0x0491, 0x0000, 0x0499, 0x0000, 0x04a1, 0x0000, 0x04a9, 0x04b1, ++ 0x0000, 0x04b9, 0x0000, 0x0000, 0x04c1, 0x0000, 0x04c9, 0x04d1, ++ /* Node for range 0x001b_ */ ++ 0x0000, 0x04d9, 0x04e1, 0x04e9, 0x0000, 0x04f1, 0x0000, 0x04f9, ++ 0x0501, 0x0000, 0x0000, 0x0000, 0x0509, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x001c_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0511, 0x0519, 0x0000, 0x0521, ++ 0x0529, 0x0000, 0x0531, 0x0539, 0x0000, 0x0541, 0x0000, 0x0549, ++ /* Node for range 0x001d_ */ ++ 0x0000, 0x0551, 0x0000, 0x0559, 0x0000, 0x0561, 0x0000, 0x0569, ++ 0x0000, 0x0571, 0x0000, 0x0579, 0x0000, 0x0000, 0x0581, 0x0000, ++ /* Node for range 0x001e_ */ ++ 0x0589, 0x0000, 0x0591, 0x0000, 0x0599, 0x0000, 0x05a1, 0x0000, ++ 0x05a9, 0x0000, 0x05b1, 0x0000, 0x05b9, 0x0000, 0x05c1, 0x0000, ++ /* Node for range 0x001f_ */ ++ 0x05ca, 0x05d9, 0x05e1, 0x0000, 0x05e9, 0x0000, 0x05f1, 0x05f9, ++ 0x0601, 0x0000, 0x0609, 0x0000, 0x0611, 0x0000, 0x0619, 0x0000, ++ /* Node for range 0x0020_ */ ++ 0x0621, 0x0000, 0x0629, 0x0000, 0x0631, 0x0000, 0x0639, 0x0000, ++ 0x0641, 0x0000, 0x0649, 0x0000, 0x0651, 0x0000, 0x0659, 0x0000, ++ /* Node for range 0x0021_ */ ++ 0x0661, 0x0000, 0x0669, 0x0000, 0x0671, 0x0000, 0x0679, 0x0000, ++ 0x0681, 0x0000, 0x0689, 0x0000, 0x0691, 0x0000, 0x0699, 0x0000, ++ /* Node for range 0x0022_ */ ++ 0x06a1, 0x0000, 0x06a9, 0x0000, 0x06b1, 0x0000, 0x06b9, 0x0000, ++ 0x06c1, 0x0000, 0x06c9, 0x0000, 0x06d1, 0x0000, 0x06d9, 0x0000, ++ /* Node for range 0x0023_ */ ++ 0x06e1, 0x0000, 0x06e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x06f1, 0x06f9, 0x0000, 0x0701, 0x0709, 0x0000, ++ /* Node for range 0x0024_ */ ++ 0x0000, 0x0711, 0x0000, 0x0719, 0x0721, 0x0729, 0x0731, 0x0000, ++ 0x0739, 0x0000, 0x0741, 0x0000, 0x0749, 0x0000, 0x0751, 0x0000, ++ /* Node for range 0x0034_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0759, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0037_ */ ++ 0x0761, 0x0000, 0x0769, 0x0000, 0x0000, 0x0000, 0x0771, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0779, ++ /* Node for range 0x0038_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0781, 0x0000, ++ 0x0789, 0x0791, 0x0799, 0x0000, 0x07a1, 0x0000, 0x07a9, 0x07b1, ++ /* Node for range 0x0039_ */ ++ 0x07bb, 0x07d1, 0x07d9, 0x07e1, 0x07e9, 0x07f1, 0x07f9, 0x0801, ++ 0x0809, 0x0811, 0x0819, 0x0821, 0x0829, 0x0831, 0x0839, 0x0841, ++ /* Node for range 0x003a_ */ ++ 0x0849, 0x0851, 0x0000, 0x0859, 0x0861, 0x0869, 0x0871, 0x0879, ++ 0x0881, 0x0889, 0x0891, 0x0899, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003b_ */ ++ 0x08a3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x003c_ */ ++ 0x0000, 0x0000, 0x08b9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08c1, ++ /* Node for range 0x003d_ */ ++ 0x08c9, 0x08d1, 0x0000, 0x0000, 0x0000, 0x08d9, 0x08e1, 0x0000, ++ 0x08e9, 0x0000, 0x08f1, 0x0000, 0x08f9, 0x0000, 0x0901, 0x0000, ++ /* Node for range 0x003e_ */ ++ 0x0909, 0x0000, 0x0911, 0x0000, 0x0919, 0x0000, 0x0921, 0x0000, ++ 0x0929, 0x0000, 0x0931, 0x0000, 0x0939, 0x0000, 0x0941, 0x0000, ++ /* Node for range 0x003f_ */ ++ 0x0949, 0x0951, 0x0000, 0x0000, 0x0959, 0x0961, 0x0000, 0x0969, ++ 0x0000, 0x0971, 0x0979, 0x0000, 0x0000, 0x0981, 0x0989, 0x0991, ++ /* Node for range 0x0040_ */ ++ 0x0999, 0x09a1, 0x09a9, 0x09b1, 0x09b9, 0x09c1, 0x09c9, 0x09d1, ++ 0x09d9, 0x09e1, 0x09e9, 0x09f1, 0x09f9, 0x0a01, 0x0a09, 0x0a11, ++ /* Node for range 0x0041_ */ ++ 0x0a19, 0x0a21, 0x0a29, 0x0a31, 0x0a39, 0x0a41, 0x0a49, 0x0a51, ++ 0x0a59, 0x0a61, 0x0a69, 0x0a71, 0x0a79, 0x0a81, 0x0a89, 0x0a91, ++ /* Node for range 0x0042_ */ ++ 0x0a99, 0x0aa1, 0x0aa9, 0x0ab1, 0x0ab9, 0x0ac1, 0x0ac9, 0x0ad1, ++ 0x0ad9, 0x0ae1, 0x0ae9, 0x0af1, 0x0af9, 0x0b01, 0x0b09, 0x0b11, ++ /* Node for range 0x0046_ */ ++ 0x0b19, 0x0000, 0x0b21, 0x0000, 0x0b29, 0x0000, 0x0b31, 0x0000, ++ 0x0b39, 0x0000, 0x0b41, 0x0000, 0x0b49, 0x0000, 0x0b51, 0x0000, ++ /* Node for range 0x0047_ */ ++ 0x0b59, 0x0000, 0x0b61, 0x0000, 0x0b69, 0x0000, 0x0b71, 0x0000, ++ 0x0b79, 0x0000, 0x0b81, 0x0000, 0x0b89, 0x0000, 0x0b91, 0x0000, ++ /* Node for range 0x0048_ */ ++ 0x0b99, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0ba1, 0x0000, 0x0ba9, 0x0000, 0x0bb1, 0x0000, ++ /* Node for range 0x0049_ */ ++ 0x0bb9, 0x0000, 0x0bc1, 0x0000, 0x0bc9, 0x0000, 0x0bd1, 0x0000, ++ 0x0bd9, 0x0000, 0x0be1, 0x0000, 0x0be9, 0x0000, 0x0bf1, 0x0000, ++ /* Node for range 0x004a_ */ ++ 0x0bf9, 0x0000, 0x0c01, 0x0000, 0x0c09, 0x0000, 0x0c11, 0x0000, ++ 0x0c19, 0x0000, 0x0c21, 0x0000, 0x0c29, 0x0000, 0x0c31, 0x0000, ++ /* Node for range 0x004b_ */ ++ 0x0c39, 0x0000, 0x0c41, 0x0000, 0x0c49, 0x0000, 0x0c51, 0x0000, ++ 0x0c59, 0x0000, 0x0c61, 0x0000, 0x0c69, 0x0000, 0x0c71, 0x0000, ++ /* Node for range 0x004c_ */ ++ 0x0c79, 0x0c81, 0x0000, 0x0c89, 0x0000, 0x0c91, 0x0000, 0x0c99, ++ 0x0000, 0x0ca1, 0x0000, 0x0ca9, 0x0000, 0x0cb1, 0x0000, 0x0000, ++ /* Node for range 0x004d_ */ ++ 0x0cb9, 0x0000, 0x0cc1, 0x0000, 0x0cc9, 0x0000, 0x0cd1, 0x0000, ++ 0x0cd9, 0x0000, 0x0ce1, 0x0000, 0x0ce9, 0x0000, 0x0cf1, 0x0000, ++ /* Node for range 0x004e_ */ ++ 0x0cf9, 0x0000, 0x0d01, 0x0000, 0x0d09, 0x0000, 0x0d11, 0x0000, ++ 0x0d19, 0x0000, 0x0d21, 0x0000, 0x0d29, 0x0000, 0x0d31, 0x0000, ++ /* Node for range 0x004f_ */ ++ 0x0d39, 0x0000, 0x0d41, 0x0000, 0x0d49, 0x0000, 0x0d51, 0x0000, ++ 0x0d59, 0x0000, 0x0d61, 0x0000, 0x0d69, 0x0000, 0x0d71, 0x0000, ++ /* Node for range 0x0050_ */ ++ 0x0d79, 0x0000, 0x0d81, 0x0000, 0x0d89, 0x0000, 0x0d91, 0x0000, ++ 0x0d99, 0x0000, 0x0da1, 0x0000, 0x0da9, 0x0000, 0x0db1, 0x0000, ++ /* Node for range 0x0051_ */ ++ 0x0db9, 0x0000, 0x0dc1, 0x0000, 0x0dc9, 0x0000, 0x0dd1, 0x0000, ++ 0x0dd9, 0x0000, 0x0de1, 0x0000, 0x0de9, 0x0000, 0x0df1, 0x0000, ++ /* Node for range 0x0052_ */ ++ 0x0df9, 0x0000, 0x0e01, 0x0000, 0x0e09, 0x0000, 0x0e11, 0x0000, ++ 0x0e19, 0x0000, 0x0e21, 0x0000, 0x0e29, 0x0000, 0x0e31, 0x0000, ++ /* Node for range 0x0053_ */ ++ 0x0000, 0x0e39, 0x0e41, 0x0e49, 0x0e51, 0x0e59, 0x0e61, 0x0e69, ++ 0x0e71, 0x0e79, 0x0e81, 0x0e89, 0x0e91, 0x0e99, 0x0ea1, 0x0ea9, ++ /* Node for range 0x0054_ */ ++ 0x0eb1, 0x0eb9, 0x0ec1, 0x0ec9, 0x0ed1, 0x0ed9, 0x0ee1, 0x0ee9, ++ 0x0ef1, 0x0ef9, 0x0f01, 0x0f09, 0x0f11, 0x0f19, 0x0f21, 0x0f29, ++ /* Node for range 0x0055_ */ ++ 0x0f31, 0x0f39, 0x0f41, 0x0f49, 0x0f51, 0x0f59, 0x0f61, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0058_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f6a, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x010a_ */ ++ 0x0f79, 0x0f81, 0x0f89, 0x0f91, 0x0f99, 0x0fa1, 0x0fa9, 0x0fb1, ++ 0x0fb9, 0x0fc1, 0x0fc9, 0x0fd1, 0x0fd9, 0x0fe1, 0x0fe9, 0x0ff1, ++ /* Node for range 0x010b_ */ ++ 0x0ff9, 0x1001, 0x1009, 0x1011, 0x1019, 0x1021, 0x1029, 0x1031, ++ 0x1039, 0x1041, 0x1049, 0x1051, 0x1059, 0x1061, 0x1069, 0x1071, ++ /* Node for range 0x010c_ */ ++ 0x1079, 0x1081, 0x1089, 0x1091, 0x1099, 0x10a1, 0x0000, 0x10a9, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10b1, 0x0000, 0x0000, ++ /* Node for range 0x013f_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x10b9, 0x10c1, 0x10c9, 0x10d1, 0x10d9, 0x10e1, 0x0000, 0x0000, ++ /* Node for range 0x01c8_ */ ++ 0x10e9, 0x10f1, 0x10f9, 0x1101, 0x1109, 0x1111, 0x1119, 0x1121, ++ 0x1129, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01e0_ */ ++ 0x1131, 0x0000, 0x1139, 0x0000, 0x1141, 0x0000, 0x1149, 0x0000, ++ 0x1151, 0x0000, 0x1159, 0x0000, 0x1161, 0x0000, 0x1169, 0x0000, ++ /* Node for range 0x01e1_ */ ++ 0x1171, 0x0000, 0x1179, 0x0000, 0x1181, 0x0000, 0x1189, 0x0000, ++ 0x1191, 0x0000, 0x1199, 0x0000, 0x11a1, 0x0000, 0x11a9, 0x0000, ++ /* Node for range 0x01e2_ */ ++ 0x11b1, 0x0000, 0x11b9, 0x0000, 0x11c1, 0x0000, 0x11c9, 0x0000, ++ 0x11d1, 0x0000, 0x11d9, 0x0000, 0x11e1, 0x0000, 0x11e9, 0x0000, ++ /* Node for range 0x01e3_ */ ++ 0x11f1, 0x0000, 0x11f9, 0x0000, 0x1201, 0x0000, 0x1209, 0x0000, ++ 0x1211, 0x0000, 0x1219, 0x0000, 0x1221, 0x0000, 0x1229, 0x0000, ++ /* Node for range 0x01e4_ */ ++ 0x1231, 0x0000, 0x1239, 0x0000, 0x1241, 0x0000, 0x1249, 0x0000, ++ 0x1251, 0x0000, 0x1259, 0x0000, 0x1261, 0x0000, 0x1269, 0x0000, ++ /* Node for range 0x01e5_ */ ++ 0x1271, 0x0000, 0x1279, 0x0000, 0x1281, 0x0000, 0x1289, 0x0000, ++ 0x1291, 0x0000, 0x1299, 0x0000, 0x12a1, 0x0000, 0x12a9, 0x0000, ++ /* Node for range 0x01e6_ */ ++ 0x12b1, 0x0000, 0x12b9, 0x0000, 0x12c1, 0x0000, 0x12c9, 0x0000, ++ 0x12d1, 0x0000, 0x12d9, 0x0000, 0x12e1, 0x0000, 0x12e9, 0x0000, ++ /* Node for range 0x01e7_ */ ++ 0x12f1, 0x0000, 0x12f9, 0x0000, 0x1301, 0x0000, 0x1309, 0x0000, ++ 0x1311, 0x0000, 0x1319, 0x0000, 0x1321, 0x0000, 0x1329, 0x0000, ++ /* Node for range 0x01e8_ */ ++ 0x1331, 0x0000, 0x1339, 0x0000, 0x1341, 0x0000, 0x1349, 0x0000, ++ 0x1351, 0x0000, 0x1359, 0x0000, 0x1361, 0x0000, 0x1369, 0x0000, ++ /* Node for range 0x01e9_ */ ++ 0x1371, 0x0000, 0x1379, 0x0000, 0x1381, 0x0000, 0x138a, 0x139a, ++ 0x13aa, 0x13ba, 0x13ca, 0x13d9, 0x0000, 0x0000, 0x13e2, 0x0000, ++ /* Node for range 0x01ea_ */ ++ 0x13f1, 0x0000, 0x13f9, 0x0000, 0x1401, 0x0000, 0x1409, 0x0000, ++ 0x1411, 0x0000, 0x1419, 0x0000, 0x1421, 0x0000, 0x1429, 0x0000, ++ /* Node for range 0x01eb_ */ ++ 0x1431, 0x0000, 0x1439, 0x0000, 0x1441, 0x0000, 0x1449, 0x0000, ++ 0x1451, 0x0000, 0x1459, 0x0000, 0x1461, 0x0000, 0x1469, 0x0000, ++ /* Node for range 0x01ec_ */ ++ 0x1471, 0x0000, 0x1479, 0x0000, 0x1481, 0x0000, 0x1489, 0x0000, ++ 0x1491, 0x0000, 0x1499, 0x0000, 0x14a1, 0x0000, 0x14a9, 0x0000, ++ /* Node for range 0x01ed_ */ ++ 0x14b1, 0x0000, 0x14b9, 0x0000, 0x14c1, 0x0000, 0x14c9, 0x0000, ++ 0x14d1, 0x0000, 0x14d9, 0x0000, 0x14e1, 0x0000, 0x14e9, 0x0000, ++ /* Node for range 0x01ee_ */ ++ 0x14f1, 0x0000, 0x14f9, 0x0000, 0x1501, 0x0000, 0x1509, 0x0000, ++ 0x1511, 0x0000, 0x1519, 0x0000, 0x1521, 0x0000, 0x1529, 0x0000, ++ /* Node for range 0x01ef_ */ ++ 0x1531, 0x0000, 0x1539, 0x0000, 0x1541, 0x0000, 0x1549, 0x0000, ++ 0x1551, 0x0000, 0x1559, 0x0000, 0x1561, 0x0000, 0x1569, 0x0000, ++ /* Node for range 0x01f0_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1571, 0x1579, 0x1581, 0x1589, 0x1591, 0x1599, 0x15a1, 0x15a9, ++ /* Node for range 0x01f1_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x15b1, 0x15b9, 0x15c1, 0x15c9, 0x15d1, 0x15d9, 0x0000, 0x0000, ++ /* Node for range 0x01f2_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x15e1, 0x15e9, 0x15f1, 0x15f9, 0x1601, 0x1609, 0x1611, 0x1619, ++ /* Node for range 0x01f3_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1621, 0x1629, 0x1631, 0x1639, 0x1641, 0x1649, 0x1651, 0x1659, ++ /* Node for range 0x01f4_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1661, 0x1669, 0x1671, 0x1679, 0x1681, 0x1689, 0x0000, 0x0000, ++ /* Node for range 0x01f5_ */ ++ 0x1692, 0x0000, 0x16a3, 0x0000, 0x16bb, 0x0000, 0x16d3, 0x0000, ++ 0x0000, 0x16e9, 0x0000, 0x16f1, 0x0000, 0x16f9, 0x0000, 0x1701, ++ /* Node for range 0x01f6_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x1709, 0x1711, 0x1719, 0x1721, 0x1729, 0x1731, 0x1739, 0x1741, ++ /* Node for range 0x01f8_ */ ++ 0x174a, 0x175a, 0x176a, 0x177a, 0x178a, 0x179a, 0x17aa, 0x17ba, ++ 0x17ca, 0x17da, 0x17ea, 0x17fa, 0x180a, 0x181a, 0x182a, 0x183a, ++ /* Node for range 0x01f9_ */ ++ 0x184a, 0x185a, 0x186a, 0x187a, 0x188a, 0x189a, 0x18aa, 0x18ba, ++ 0x18ca, 0x18da, 0x18ea, 0x18fa, 0x190a, 0x191a, 0x192a, 0x193a, ++ /* Node for range 0x01fa_ */ ++ 0x194a, 0x195a, 0x196a, 0x197a, 0x198a, 0x199a, 0x19aa, 0x19ba, ++ 0x19ca, 0x19da, 0x19ea, 0x19fa, 0x1a0a, 0x1a1a, 0x1a2a, 0x1a3a, ++ /* Node for range 0x01fb_ */ ++ 0x0000, 0x0000, 0x1a4a, 0x1a5a, 0x1a6a, 0x0000, 0x1a7a, 0x1a8b, ++ 0x1aa1, 0x1aa9, 0x1ab1, 0x1ab9, 0x1ac2, 0x0000, 0x1ad1, 0x0000, ++ /* Node for range 0x01fc_ */ ++ 0x0000, 0x0000, 0x1ada, 0x1aea, 0x1afa, 0x0000, 0x1b0a, 0x1b1b, ++ 0x1b31, 0x1b39, 0x1b41, 0x1b49, 0x1b52, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01fd_ */ ++ 0x0000, 0x0000, 0x1b63, 0x1b7b, 0x0000, 0x0000, 0x1b92, 0x1ba3, ++ 0x1bb9, 0x1bc1, 0x1bc9, 0x1bd1, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01fe_ */ ++ 0x0000, 0x0000, 0x1bdb, 0x1bf3, 0x1c0a, 0x0000, 0x1c1a, 0x1c2b, ++ 0x1c41, 0x1c49, 0x1c51, 0x1c59, 0x1c61, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x01ff_ */ ++ 0x0000, 0x0000, 0x1c6a, 0x1c7a, 0x1c8a, 0x0000, 0x1c9a, 0x1cab, ++ 0x1cc1, 0x1cc9, 0x1cd1, 0x1cd9, 0x1ce2, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0212_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1cf1, 0x0000, ++ 0x0000, 0x0000, 0x1cf9, 0x1d01, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0213_ */ ++ 0x0000, 0x0000, 0x1d09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0216_ */ ++ 0x1d11, 0x1d19, 0x1d21, 0x1d29, 0x1d31, 0x1d39, 0x1d41, 0x1d49, ++ 0x1d51, 0x1d59, 0x1d61, 0x1d69, 0x1d71, 0x1d79, 0x1d81, 0x1d89, ++ /* Node for range 0x0218_ */ ++ 0x0000, 0x0000, 0x0000, 0x1d91, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x024b_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1d99, 0x1da1, ++ 0x1da9, 0x1db1, 0x1db9, 0x1dc1, 0x1dc9, 0x1dd1, 0x1dd9, 0x1de1, ++ /* Node for range 0x024c_ */ ++ 0x1de9, 0x1df1, 0x1df9, 0x1e01, 0x1e09, 0x1e11, 0x1e19, 0x1e21, ++ 0x1e29, 0x1e31, 0x1e39, 0x1e41, 0x1e49, 0x1e51, 0x1e59, 0x1e61, ++ /* Node for range 0x02c0_ */ ++ 0x1e69, 0x1e71, 0x1e79, 0x1e81, 0x1e89, 0x1e91, 0x1e99, 0x1ea1, ++ 0x1ea9, 0x1eb1, 0x1eb9, 0x1ec1, 0x1ec9, 0x1ed1, 0x1ed9, 0x1ee1, ++ /* Node for range 0x02c1_ */ ++ 0x1ee9, 0x1ef1, 0x1ef9, 0x1f01, 0x1f09, 0x1f11, 0x1f19, 0x1f21, ++ 0x1f29, 0x1f31, 0x1f39, 0x1f41, 0x1f49, 0x1f51, 0x1f59, 0x1f61, ++ /* Node for range 0x02c2_ */ ++ 0x1f69, 0x1f71, 0x1f79, 0x1f81, 0x1f89, 0x1f91, 0x1f99, 0x1fa1, ++ 0x1fa9, 0x1fb1, 0x1fb9, 0x1fc1, 0x1fc9, 0x1fd1, 0x1fd9, 0x0000, ++ /* Node for range 0x02c6_ */ ++ 0x1fe1, 0x0000, 0x1fe9, 0x1ff1, 0x1ff9, 0x0000, 0x0000, 0x2001, ++ 0x0000, 0x2009, 0x0000, 0x2011, 0x0000, 0x2019, 0x2021, 0x2029, ++ /* Node for range 0x02c7_ */ ++ 0x2031, 0x0000, 0x2039, 0x0000, 0x0000, 0x2041, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2049, 0x2051, ++ /* Node for range 0x02c8_ */ ++ 0x2059, 0x0000, 0x2061, 0x0000, 0x2069, 0x0000, 0x2071, 0x0000, ++ 0x2079, 0x0000, 0x2081, 0x0000, 0x2089, 0x0000, 0x2091, 0x0000, ++ /* Node for range 0x02c9_ */ ++ 0x2099, 0x0000, 0x20a1, 0x0000, 0x20a9, 0x0000, 0x20b1, 0x0000, ++ 0x20b9, 0x0000, 0x20c1, 0x0000, 0x20c9, 0x0000, 0x20d1, 0x0000, ++ /* Node for range 0x02ca_ */ ++ 0x20d9, 0x0000, 0x20e1, 0x0000, 0x20e9, 0x0000, 0x20f1, 0x0000, ++ 0x20f9, 0x0000, 0x2101, 0x0000, 0x2109, 0x0000, 0x2111, 0x0000, ++ /* Node for range 0x02cb_ */ ++ 0x2119, 0x0000, 0x2121, 0x0000, 0x2129, 0x0000, 0x2131, 0x0000, ++ 0x2139, 0x0000, 0x2141, 0x0000, 0x2149, 0x0000, 0x2151, 0x0000, ++ /* Node for range 0x02cc_ */ ++ 0x2159, 0x0000, 0x2161, 0x0000, 0x2169, 0x0000, 0x2171, 0x0000, ++ 0x2179, 0x0000, 0x2181, 0x0000, 0x2189, 0x0000, 0x2191, 0x0000, ++ /* Node for range 0x02cd_ */ ++ 0x2199, 0x0000, 0x21a1, 0x0000, 0x21a9, 0x0000, 0x21b1, 0x0000, ++ 0x21b9, 0x0000, 0x21c1, 0x0000, 0x21c9, 0x0000, 0x21d1, 0x0000, ++ /* Node for range 0x02ce_ */ ++ 0x21d9, 0x0000, 0x21e1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x21e9, 0x0000, 0x21f1, 0x0000, 0x0000, ++ /* Node for range 0x02cf_ */ ++ 0x0000, 0x0000, 0x21f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0a64_ */ ++ 0x2201, 0x0000, 0x2209, 0x0000, 0x2211, 0x0000, 0x2219, 0x0000, ++ 0x2221, 0x0000, 0x2229, 0x0000, 0x2231, 0x0000, 0x2239, 0x0000, ++ /* Node for range 0x0a65_ */ ++ 0x2241, 0x0000, 0x2249, 0x0000, 0x2251, 0x0000, 0x2259, 0x0000, ++ 0x2261, 0x0000, 0x2269, 0x0000, 0x2271, 0x0000, 0x2279, 0x0000, ++ /* Node for range 0x0a66_ */ ++ 0x2281, 0x0000, 0x2289, 0x0000, 0x2291, 0x0000, 0x2299, 0x0000, ++ 0x22a1, 0x0000, 0x22a9, 0x0000, 0x22b1, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0a68_ */ ++ 0x22b9, 0x0000, 0x22c1, 0x0000, 0x22c9, 0x0000, 0x22d1, 0x0000, ++ 0x22d9, 0x0000, 0x22e1, 0x0000, 0x22e9, 0x0000, 0x22f1, 0x0000, ++ /* Node for range 0x0a69_ */ ++ 0x22f9, 0x0000, 0x2301, 0x0000, 0x2309, 0x0000, 0x2311, 0x0000, ++ 0x2319, 0x0000, 0x2321, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0a72_ */ ++ 0x0000, 0x0000, 0x2329, 0x0000, 0x2331, 0x0000, 0x2339, 0x0000, ++ 0x2341, 0x0000, 0x2349, 0x0000, 0x2351, 0x0000, 0x2359, 0x0000, ++ /* Node for range 0x0a73_ */ ++ 0x0000, 0x0000, 0x2361, 0x0000, 0x2369, 0x0000, 0x2371, 0x0000, ++ 0x2379, 0x0000, 0x2381, 0x0000, 0x2389, 0x0000, 0x2391, 0x0000, ++ /* Node for range 0x0a74_ */ ++ 0x2399, 0x0000, 0x23a1, 0x0000, 0x23a9, 0x0000, 0x23b1, 0x0000, ++ 0x23b9, 0x0000, 0x23c1, 0x0000, 0x23c9, 0x0000, 0x23d1, 0x0000, ++ /* Node for range 0x0a75_ */ ++ 0x23d9, 0x0000, 0x23e1, 0x0000, 0x23e9, 0x0000, 0x23f1, 0x0000, ++ 0x23f9, 0x0000, 0x2401, 0x0000, 0x2409, 0x0000, 0x2411, 0x0000, ++ /* Node for range 0x0a76_ */ ++ 0x2419, 0x0000, 0x2421, 0x0000, 0x2429, 0x0000, 0x2431, 0x0000, ++ 0x2439, 0x0000, 0x2441, 0x0000, 0x2449, 0x0000, 0x2451, 0x0000, ++ /* Node for range 0x0a77_ */ ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x2459, 0x0000, 0x2461, 0x0000, 0x2469, 0x2471, 0x0000, ++ /* Node for range 0x0a78_ */ ++ 0x2479, 0x0000, 0x2481, 0x0000, 0x2489, 0x0000, 0x2491, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x2499, 0x0000, 0x24a1, 0x0000, 0x0000, ++ /* Node for range 0x0a79_ */ ++ 0x24a9, 0x0000, 0x24b1, 0x0000, 0x0000, 0x0000, 0x24b9, 0x0000, ++ 0x24c1, 0x0000, 0x24c9, 0x0000, 0x24d1, 0x0000, 0x24d9, 0x0000, ++ /* Node for range 0x0a7a_ */ ++ 0x24e1, 0x0000, 0x24e9, 0x0000, 0x24f1, 0x0000, 0x24f9, 0x0000, ++ 0x2501, 0x0000, 0x2509, 0x2511, 0x2519, 0x2521, 0x2529, 0x0000, ++ /* Node for range 0x0a7b_ */ ++ 0x2531, 0x2539, 0x2541, 0x2549, 0x2551, 0x0000, 0x2559, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0ab7_ */ ++ 0x2561, 0x2569, 0x2571, 0x2579, 0x2581, 0x2589, 0x2591, 0x2599, ++ 0x25a1, 0x25a9, 0x25b1, 0x25b9, 0x25c1, 0x25c9, 0x25d1, 0x25d9, ++ /* Node for range 0x0ab8_ */ ++ 0x25e1, 0x25e9, 0x25f1, 0x25f9, 0x2601, 0x2609, 0x2611, 0x2619, ++ 0x2621, 0x2629, 0x2631, 0x2639, 0x2641, 0x2649, 0x2651, 0x2659, ++ /* Node for range 0x0ab9_ */ ++ 0x2661, 0x2669, 0x2671, 0x2679, 0x2681, 0x2689, 0x2691, 0x2699, ++ 0x26a1, 0x26a9, 0x26b1, 0x26b9, 0x26c1, 0x26c9, 0x26d1, 0x26d9, ++ /* Node for range 0x0aba_ */ ++ 0x26e1, 0x26e9, 0x26f1, 0x26f9, 0x2701, 0x2709, 0x2711, 0x2719, ++ 0x2721, 0x2729, 0x2731, 0x2739, 0x2741, 0x2749, 0x2751, 0x2759, ++ /* Node for range 0x0abb_ */ ++ 0x2761, 0x2769, 0x2771, 0x2779, 0x2781, 0x2789, 0x2791, 0x2799, ++ 0x27a1, 0x27a9, 0x27b1, 0x27b9, 0x27c1, 0x27c9, 0x27d1, 0x27d9, ++ /* Node for range 0x0fb0_ */ ++ 0x27e2, 0x27f2, 0x2802, 0x2813, 0x282b, 0x2842, 0x2852, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0fb1_ */ ++ 0x0000, 0x0000, 0x0000, 0x2862, 0x2872, 0x2882, 0x2892, 0x28a2, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x0ff2_ */ ++ 0x0000, 0x28b1, 0x28b9, 0x28c1, 0x28c9, 0x28d1, 0x28d9, 0x28e1, ++ 0x28e9, 0x28f1, 0x28f9, 0x2901, 0x2909, 0x2911, 0x2919, 0x2921, ++ /* Node for range 0x0ff3_ */ ++ 0x2929, 0x2931, 0x2939, 0x2941, 0x2949, 0x2951, 0x2959, 0x2961, ++ 0x2969, 0x2971, 0x2979, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x1040_ */ ++ 0x2981, 0x2989, 0x2991, 0x2999, 0x29a1, 0x29a9, 0x29b1, 0x29b9, ++ 0x29c1, 0x29c9, 0x29d1, 0x29d9, 0x29e1, 0x29e9, 0x29f1, 0x29f9, ++ /* Node for range 0x1041_ */ ++ 0x2a01, 0x2a09, 0x2a11, 0x2a19, 0x2a21, 0x2a29, 0x2a31, 0x2a39, ++ 0x2a41, 0x2a49, 0x2a51, 0x2a59, 0x2a61, 0x2a69, 0x2a71, 0x2a79, ++ /* Node for range 0x1042_ */ ++ 0x2a81, 0x2a89, 0x2a91, 0x2a99, 0x2aa1, 0x2aa9, 0x2ab1, 0x2ab9, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x104b_ */ ++ 0x2ac1, 0x2ac9, 0x2ad1, 0x2ad9, 0x2ae1, 0x2ae9, 0x2af1, 0x2af9, ++ 0x2b01, 0x2b09, 0x2b11, 0x2b19, 0x2b21, 0x2b29, 0x2b31, 0x2b39, ++ /* Node for range 0x104c_ */ ++ 0x2b41, 0x2b49, 0x2b51, 0x2b59, 0x2b61, 0x2b69, 0x2b71, 0x2b79, ++ 0x2b81, 0x2b89, 0x2b91, 0x2b99, 0x2ba1, 0x2ba9, 0x2bb1, 0x2bb9, ++ /* Node for range 0x104d_ */ ++ 0x2bc1, 0x2bc9, 0x2bd1, 0x2bd9, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x10c8_ */ ++ 0x2be1, 0x2be9, 0x2bf1, 0x2bf9, 0x2c01, 0x2c09, 0x2c11, 0x2c19, ++ 0x2c21, 0x2c29, 0x2c31, 0x2c39, 0x2c41, 0x2c49, 0x2c51, 0x2c59, ++ /* Node for range 0x10c9_ */ ++ 0x2c61, 0x2c69, 0x2c71, 0x2c79, 0x2c81, 0x2c89, 0x2c91, 0x2c99, ++ 0x2ca1, 0x2ca9, 0x2cb1, 0x2cb9, 0x2cc1, 0x2cc9, 0x2cd1, 0x2cd9, ++ /* Node for range 0x10ca_ */ ++ 0x2ce1, 0x2ce9, 0x2cf1, 0x2cf9, 0x2d01, 0x2d09, 0x2d11, 0x2d19, ++ 0x2d21, 0x2d29, 0x2d31, 0x2d39, 0x2d41, 0x2d49, 0x2d51, 0x2d59, ++ /* Node for range 0x10cb_ */ ++ 0x2d61, 0x2d69, 0x2d71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ /* Node for range 0x118a_ */ ++ 0x2d79, 0x2d81, 0x2d89, 0x2d91, 0x2d99, 0x2da1, 0x2da9, 0x2db1, ++ 0x2db9, 0x2dc1, 0x2dc9, 0x2dd1, 0x2dd9, 0x2de1, 0x2de9, 0x2df1, ++ /* Node for range 0x118b_ */ ++ 0x2df9, 0x2e01, 0x2e09, 0x2e11, 0x2e19, 0x2e21, 0x2e29, 0x2e31, ++ 0x2e39, 0x2e41, 0x2e49, 0x2e51, 0x2e59, 0x2e61, 0x2e69, 0x2e71, ++ /* Node for range 0x1e90_ */ ++ 0x2e79, 0x2e81, 0x2e89, 0x2e91, 0x2e99, 0x2ea1, 0x2ea9, 0x2eb1, ++ 0x2eb9, 0x2ec1, 0x2ec9, 0x2ed1, 0x2ed9, 0x2ee1, 0x2ee9, 0x2ef1, ++ /* Node for range 0x1e91_ */ ++ 0x2ef9, 0x2f01, 0x2f09, 0x2f11, 0x2f19, 0x2f21, 0x2f29, 0x2f31, ++ 0x2f39, 0x2f41, 0x2f49, 0x2f51, 0x2f59, 0x2f61, 0x2f69, 0x2f71, ++ /* Node for range 0x1e92_ */ ++ 0x2f79, 0x2f81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ++}; ++ ++static unicode_t apfs_cf[] = { ++ 0x000061, 0x000062, 0x000063, 0x000064, 0x000065, 0x000066, ++ 0x000067, 0x000068, 0x000069, 0x00006a, 0x00006b, 0x00006c, ++ 0x00006d, 0x00006e, 0x00006f, 0x000070, 0x000071, 0x000072, ++ 0x000073, 0x000074, 0x000075, 0x000076, 0x000077, 0x000078, ++ 0x000079, 0x00007a, 0x0003bc, 0x0000e0, 0x0000e1, 0x0000e2, ++ 0x0000e3, 0x0000e4, 0x0000e5, 0x0000e6, 0x0000e7, 0x0000e8, ++ 0x0000e9, 0x0000ea, 0x0000eb, 0x0000ec, 0x0000ed, 0x0000ee, ++ 0x0000ef, 0x0000f0, 0x0000f1, 0x0000f2, 0x0000f3, 0x0000f4, ++ 0x0000f5, 0x0000f6, 0x0000f8, 0x0000f9, 0x0000fa, 0x0000fb, ++ 0x0000fc, 0x0000fd, 0x0000fe, 0x000073, 0x000073, 0x000101, ++ 0x000103, 0x000105, 0x000107, 0x000109, 0x00010b, 0x00010d, ++ 0x00010f, 0x000111, 0x000113, 0x000115, 0x000117, 0x000119, ++ 0x00011b, 0x00011d, 0x00011f, 0x000121, 0x000123, 0x000125, ++ 0x000127, 0x000129, 0x00012b, 0x00012d, 0x00012f, 0x000069, ++ 0x000307, 0x000133, 0x000135, 0x000137, 0x00013a, 0x00013c, ++ 0x00013e, 0x000140, 0x000142, 0x000144, 0x000146, 0x000148, ++ 0x0002bc, 0x00006e, 0x00014b, 0x00014d, 0x00014f, 0x000151, ++ 0x000153, 0x000155, 0x000157, 0x000159, 0x00015b, 0x00015d, ++ 0x00015f, 0x000161, 0x000163, 0x000165, 0x000167, 0x000169, ++ 0x00016b, 0x00016d, 0x00016f, 0x000171, 0x000173, 0x000175, ++ 0x000177, 0x0000ff, 0x00017a, 0x00017c, 0x00017e, 0x000073, ++ 0x000253, 0x000183, 0x000185, 0x000254, 0x000188, 0x000256, ++ 0x000257, 0x00018c, 0x0001dd, 0x000259, 0x00025b, 0x000192, ++ 0x000260, 0x000263, 0x000269, 0x000268, 0x000199, 0x00026f, ++ 0x000272, 0x000275, 0x0001a1, 0x0001a3, 0x0001a5, 0x000280, ++ 0x0001a8, 0x000283, 0x0001ad, 0x000288, 0x0001b0, 0x00028a, ++ 0x00028b, 0x0001b4, 0x0001b6, 0x000292, 0x0001b9, 0x0001bd, ++ 0x0001c6, 0x0001c6, 0x0001c9, 0x0001c9, 0x0001cc, 0x0001cc, ++ 0x0001ce, 0x0001d0, 0x0001d2, 0x0001d4, 0x0001d6, 0x0001d8, ++ 0x0001da, 0x0001dc, 0x0001df, 0x0001e1, 0x0001e3, 0x0001e5, ++ 0x0001e7, 0x0001e9, 0x0001eb, 0x0001ed, 0x0001ef, 0x00006a, ++ 0x00030c, 0x0001f3, 0x0001f3, 0x0001f5, 0x000195, 0x0001bf, ++ 0x0001f9, 0x0001fb, 0x0001fd, 0x0001ff, 0x000201, 0x000203, ++ 0x000205, 0x000207, 0x000209, 0x00020b, 0x00020d, 0x00020f, ++ 0x000211, 0x000213, 0x000215, 0x000217, 0x000219, 0x00021b, ++ 0x00021d, 0x00021f, 0x00019e, 0x000223, 0x000225, 0x000227, ++ 0x000229, 0x00022b, 0x00022d, 0x00022f, 0x000231, 0x000233, ++ 0x002c65, 0x00023c, 0x00019a, 0x002c66, 0x000242, 0x000180, ++ 0x000289, 0x00028c, 0x000247, 0x000249, 0x00024b, 0x00024d, ++ 0x00024f, 0x0003b9, 0x000371, 0x000373, 0x000377, 0x0003f3, ++ 0x0003ac, 0x0003ad, 0x0003ae, 0x0003af, 0x0003cc, 0x0003cd, ++ 0x0003ce, 0x0003b9, 0x000308, 0x000301, 0x0003b1, 0x0003b2, ++ 0x0003b3, 0x0003b4, 0x0003b5, 0x0003b6, 0x0003b7, 0x0003b8, ++ 0x0003b9, 0x0003ba, 0x0003bb, 0x0003bc, 0x0003bd, 0x0003be, ++ 0x0003bf, 0x0003c0, 0x0003c1, 0x0003c3, 0x0003c4, 0x0003c5, ++ 0x0003c6, 0x0003c7, 0x0003c8, 0x0003c9, 0x0003ca, 0x0003cb, ++ 0x0003c5, 0x000308, 0x000301, 0x0003c3, 0x0003d7, 0x0003b2, ++ 0x0003b8, 0x0003c6, 0x0003c0, 0x0003d9, 0x0003db, 0x0003dd, ++ 0x0003df, 0x0003e1, 0x0003e3, 0x0003e5, 0x0003e7, 0x0003e9, ++ 0x0003eb, 0x0003ed, 0x0003ef, 0x0003ba, 0x0003c1, 0x0003b8, ++ 0x0003b5, 0x0003f8, 0x0003f2, 0x0003fb, 0x00037b, 0x00037c, ++ 0x00037d, 0x000450, 0x000451, 0x000452, 0x000453, 0x000454, ++ 0x000455, 0x000456, 0x000457, 0x000458, 0x000459, 0x00045a, ++ 0x00045b, 0x00045c, 0x00045d, 0x00045e, 0x00045f, 0x000430, ++ 0x000431, 0x000432, 0x000433, 0x000434, 0x000435, 0x000436, ++ 0x000437, 0x000438, 0x000439, 0x00043a, 0x00043b, 0x00043c, ++ 0x00043d, 0x00043e, 0x00043f, 0x000440, 0x000441, 0x000442, ++ 0x000443, 0x000444, 0x000445, 0x000446, 0x000447, 0x000448, ++ 0x000449, 0x00044a, 0x00044b, 0x00044c, 0x00044d, 0x00044e, ++ 0x00044f, 0x000461, 0x000463, 0x000465, 0x000467, 0x000469, ++ 0x00046b, 0x00046d, 0x00046f, 0x000471, 0x000473, 0x000475, ++ 0x000477, 0x000479, 0x00047b, 0x00047d, 0x00047f, 0x000481, ++ 0x00048b, 0x00048d, 0x00048f, 0x000491, 0x000493, 0x000495, ++ 0x000497, 0x000499, 0x00049b, 0x00049d, 0x00049f, 0x0004a1, ++ 0x0004a3, 0x0004a5, 0x0004a7, 0x0004a9, 0x0004ab, 0x0004ad, ++ 0x0004af, 0x0004b1, 0x0004b3, 0x0004b5, 0x0004b7, 0x0004b9, ++ 0x0004bb, 0x0004bd, 0x0004bf, 0x0004cf, 0x0004c2, 0x0004c4, ++ 0x0004c6, 0x0004c8, 0x0004ca, 0x0004cc, 0x0004ce, 0x0004d1, ++ 0x0004d3, 0x0004d5, 0x0004d7, 0x0004d9, 0x0004db, 0x0004dd, ++ 0x0004df, 0x0004e1, 0x0004e3, 0x0004e5, 0x0004e7, 0x0004e9, ++ 0x0004eb, 0x0004ed, 0x0004ef, 0x0004f1, 0x0004f3, 0x0004f5, ++ 0x0004f7, 0x0004f9, 0x0004fb, 0x0004fd, 0x0004ff, 0x000501, ++ 0x000503, 0x000505, 0x000507, 0x000509, 0x00050b, 0x00050d, ++ 0x00050f, 0x000511, 0x000513, 0x000515, 0x000517, 0x000519, ++ 0x00051b, 0x00051d, 0x00051f, 0x000521, 0x000523, 0x000525, ++ 0x000527, 0x000529, 0x00052b, 0x00052d, 0x00052f, 0x000561, ++ 0x000562, 0x000563, 0x000564, 0x000565, 0x000566, 0x000567, ++ 0x000568, 0x000569, 0x00056a, 0x00056b, 0x00056c, 0x00056d, ++ 0x00056e, 0x00056f, 0x000570, 0x000571, 0x000572, 0x000573, ++ 0x000574, 0x000575, 0x000576, 0x000577, 0x000578, 0x000579, ++ 0x00057a, 0x00057b, 0x00057c, 0x00057d, 0x00057e, 0x00057f, ++ 0x000580, 0x000581, 0x000582, 0x000583, 0x000584, 0x000585, ++ 0x000586, 0x000565, 0x000582, 0x002d00, 0x002d01, 0x002d02, ++ 0x002d03, 0x002d04, 0x002d05, 0x002d06, 0x002d07, 0x002d08, ++ 0x002d09, 0x002d0a, 0x002d0b, 0x002d0c, 0x002d0d, 0x002d0e, ++ 0x002d0f, 0x002d10, 0x002d11, 0x002d12, 0x002d13, 0x002d14, ++ 0x002d15, 0x002d16, 0x002d17, 0x002d18, 0x002d19, 0x002d1a, ++ 0x002d1b, 0x002d1c, 0x002d1d, 0x002d1e, 0x002d1f, 0x002d20, ++ 0x002d21, 0x002d22, 0x002d23, 0x002d24, 0x002d25, 0x002d27, ++ 0x002d2d, 0x0013f0, 0x0013f1, 0x0013f2, 0x0013f3, 0x0013f4, ++ 0x0013f5, 0x000432, 0x000434, 0x00043e, 0x000441, 0x000442, ++ 0x000442, 0x00044a, 0x000463, 0x00a64b, 0x001e01, 0x001e03, ++ 0x001e05, 0x001e07, 0x001e09, 0x001e0b, 0x001e0d, 0x001e0f, ++ 0x001e11, 0x001e13, 0x001e15, 0x001e17, 0x001e19, 0x001e1b, ++ 0x001e1d, 0x001e1f, 0x001e21, 0x001e23, 0x001e25, 0x001e27, ++ 0x001e29, 0x001e2b, 0x001e2d, 0x001e2f, 0x001e31, 0x001e33, ++ 0x001e35, 0x001e37, 0x001e39, 0x001e3b, 0x001e3d, 0x001e3f, ++ 0x001e41, 0x001e43, 0x001e45, 0x001e47, 0x001e49, 0x001e4b, ++ 0x001e4d, 0x001e4f, 0x001e51, 0x001e53, 0x001e55, 0x001e57, ++ 0x001e59, 0x001e5b, 0x001e5d, 0x001e5f, 0x001e61, 0x001e63, ++ 0x001e65, 0x001e67, 0x001e69, 0x001e6b, 0x001e6d, 0x001e6f, ++ 0x001e71, 0x001e73, 0x001e75, 0x001e77, 0x001e79, 0x001e7b, ++ 0x001e7d, 0x001e7f, 0x001e81, 0x001e83, 0x001e85, 0x001e87, ++ 0x001e89, 0x001e8b, 0x001e8d, 0x001e8f, 0x001e91, 0x001e93, ++ 0x001e95, 0x000068, 0x000331, 0x000074, 0x000308, 0x000077, ++ 0x00030a, 0x000079, 0x00030a, 0x000061, 0x0002be, 0x001e61, ++ 0x000073, 0x000073, 0x001ea1, 0x001ea3, 0x001ea5, 0x001ea7, ++ 0x001ea9, 0x001eab, 0x001ead, 0x001eaf, 0x001eb1, 0x001eb3, ++ 0x001eb5, 0x001eb7, 0x001eb9, 0x001ebb, 0x001ebd, 0x001ebf, ++ 0x001ec1, 0x001ec3, 0x001ec5, 0x001ec7, 0x001ec9, 0x001ecb, ++ 0x001ecd, 0x001ecf, 0x001ed1, 0x001ed3, 0x001ed5, 0x001ed7, ++ 0x001ed9, 0x001edb, 0x001edd, 0x001edf, 0x001ee1, 0x001ee3, ++ 0x001ee5, 0x001ee7, 0x001ee9, 0x001eeb, 0x001eed, 0x001eef, ++ 0x001ef1, 0x001ef3, 0x001ef5, 0x001ef7, 0x001ef9, 0x001efb, ++ 0x001efd, 0x001eff, 0x001f00, 0x001f01, 0x001f02, 0x001f03, ++ 0x001f04, 0x001f05, 0x001f06, 0x001f07, 0x001f10, 0x001f11, ++ 0x001f12, 0x001f13, 0x001f14, 0x001f15, 0x001f20, 0x001f21, ++ 0x001f22, 0x001f23, 0x001f24, 0x001f25, 0x001f26, 0x001f27, ++ 0x001f30, 0x001f31, 0x001f32, 0x001f33, 0x001f34, 0x001f35, ++ 0x001f36, 0x001f37, 0x001f40, 0x001f41, 0x001f42, 0x001f43, ++ 0x001f44, 0x001f45, 0x0003c5, 0x000313, 0x0003c5, 0x000313, ++ 0x000300, 0x0003c5, 0x000313, 0x000301, 0x0003c5, 0x000313, ++ 0x000342, 0x001f51, 0x001f53, 0x001f55, 0x001f57, 0x001f60, ++ 0x001f61, 0x001f62, 0x001f63, 0x001f64, 0x001f65, 0x001f66, ++ 0x001f67, 0x001f00, 0x0003b9, 0x001f01, 0x0003b9, 0x001f02, ++ 0x0003b9, 0x001f03, 0x0003b9, 0x001f04, 0x0003b9, 0x001f05, ++ 0x0003b9, 0x001f06, 0x0003b9, 0x001f07, 0x0003b9, 0x001f00, ++ 0x0003b9, 0x001f01, 0x0003b9, 0x001f02, 0x0003b9, 0x001f03, ++ 0x0003b9, 0x001f04, 0x0003b9, 0x001f05, 0x0003b9, 0x001f06, ++ 0x0003b9, 0x001f07, 0x0003b9, 0x001f20, 0x0003b9, 0x001f21, ++ 0x0003b9, 0x001f22, 0x0003b9, 0x001f23, 0x0003b9, 0x001f24, ++ 0x0003b9, 0x001f25, 0x0003b9, 0x001f26, 0x0003b9, 0x001f27, ++ 0x0003b9, 0x001f20, 0x0003b9, 0x001f21, 0x0003b9, 0x001f22, ++ 0x0003b9, 0x001f23, 0x0003b9, 0x001f24, 0x0003b9, 0x001f25, ++ 0x0003b9, 0x001f26, 0x0003b9, 0x001f27, 0x0003b9, 0x001f60, ++ 0x0003b9, 0x001f61, 0x0003b9, 0x001f62, 0x0003b9, 0x001f63, ++ 0x0003b9, 0x001f64, 0x0003b9, 0x001f65, 0x0003b9, 0x001f66, ++ 0x0003b9, 0x001f67, 0x0003b9, 0x001f60, 0x0003b9, 0x001f61, ++ 0x0003b9, 0x001f62, 0x0003b9, 0x001f63, 0x0003b9, 0x001f64, ++ 0x0003b9, 0x001f65, 0x0003b9, 0x001f66, 0x0003b9, 0x001f67, ++ 0x0003b9, 0x001f70, 0x0003b9, 0x0003b1, 0x0003b9, 0x0003ac, ++ 0x0003b9, 0x0003b1, 0x000342, 0x0003b1, 0x000342, 0x0003b9, ++ 0x001fb0, 0x001fb1, 0x001f70, 0x001f71, 0x0003b1, 0x0003b9, ++ 0x0003b9, 0x001f74, 0x0003b9, 0x0003b7, 0x0003b9, 0x0003ae, ++ 0x0003b9, 0x0003b7, 0x000342, 0x0003b7, 0x000342, 0x0003b9, ++ 0x001f72, 0x001f73, 0x001f74, 0x001f75, 0x0003b7, 0x0003b9, ++ 0x0003b9, 0x000308, 0x000300, 0x0003b9, 0x000308, 0x000301, ++ 0x0003b9, 0x000342, 0x0003b9, 0x000308, 0x000342, 0x001fd0, ++ 0x001fd1, 0x001f76, 0x001f77, 0x0003c5, 0x000308, 0x000300, ++ 0x0003c5, 0x000308, 0x000301, 0x0003c1, 0x000313, 0x0003c5, ++ 0x000342, 0x0003c5, 0x000308, 0x000342, 0x001fe0, 0x001fe1, ++ 0x001f7a, 0x001f7b, 0x001fe5, 0x001f7c, 0x0003b9, 0x0003c9, ++ 0x0003b9, 0x0003ce, 0x0003b9, 0x0003c9, 0x000342, 0x0003c9, ++ 0x000342, 0x0003b9, 0x001f78, 0x001f79, 0x001f7c, 0x001f7d, ++ 0x0003c9, 0x0003b9, 0x0003c9, 0x00006b, 0x0000e5, 0x00214e, ++ 0x002170, 0x002171, 0x002172, 0x002173, 0x002174, 0x002175, ++ 0x002176, 0x002177, 0x002178, 0x002179, 0x00217a, 0x00217b, ++ 0x00217c, 0x00217d, 0x00217e, 0x00217f, 0x002184, 0x0024d0, ++ 0x0024d1, 0x0024d2, 0x0024d3, 0x0024d4, 0x0024d5, 0x0024d6, ++ 0x0024d7, 0x0024d8, 0x0024d9, 0x0024da, 0x0024db, 0x0024dc, ++ 0x0024dd, 0x0024de, 0x0024df, 0x0024e0, 0x0024e1, 0x0024e2, ++ 0x0024e3, 0x0024e4, 0x0024e5, 0x0024e6, 0x0024e7, 0x0024e8, ++ 0x0024e9, 0x002c30, 0x002c31, 0x002c32, 0x002c33, 0x002c34, ++ 0x002c35, 0x002c36, 0x002c37, 0x002c38, 0x002c39, 0x002c3a, ++ 0x002c3b, 0x002c3c, 0x002c3d, 0x002c3e, 0x002c3f, 0x002c40, ++ 0x002c41, 0x002c42, 0x002c43, 0x002c44, 0x002c45, 0x002c46, ++ 0x002c47, 0x002c48, 0x002c49, 0x002c4a, 0x002c4b, 0x002c4c, ++ 0x002c4d, 0x002c4e, 0x002c4f, 0x002c50, 0x002c51, 0x002c52, ++ 0x002c53, 0x002c54, 0x002c55, 0x002c56, 0x002c57, 0x002c58, ++ 0x002c59, 0x002c5a, 0x002c5b, 0x002c5c, 0x002c5d, 0x002c5e, ++ 0x002c61, 0x00026b, 0x001d7d, 0x00027d, 0x002c68, 0x002c6a, ++ 0x002c6c, 0x000251, 0x000271, 0x000250, 0x000252, 0x002c73, ++ 0x002c76, 0x00023f, 0x000240, 0x002c81, 0x002c83, 0x002c85, ++ 0x002c87, 0x002c89, 0x002c8b, 0x002c8d, 0x002c8f, 0x002c91, ++ 0x002c93, 0x002c95, 0x002c97, 0x002c99, 0x002c9b, 0x002c9d, ++ 0x002c9f, 0x002ca1, 0x002ca3, 0x002ca5, 0x002ca7, 0x002ca9, ++ 0x002cab, 0x002cad, 0x002caf, 0x002cb1, 0x002cb3, 0x002cb5, ++ 0x002cb7, 0x002cb9, 0x002cbb, 0x002cbd, 0x002cbf, 0x002cc1, ++ 0x002cc3, 0x002cc5, 0x002cc7, 0x002cc9, 0x002ccb, 0x002ccd, ++ 0x002ccf, 0x002cd1, 0x002cd3, 0x002cd5, 0x002cd7, 0x002cd9, ++ 0x002cdb, 0x002cdd, 0x002cdf, 0x002ce1, 0x002ce3, 0x002cec, ++ 0x002cee, 0x002cf3, 0x00a641, 0x00a643, 0x00a645, 0x00a647, ++ 0x00a649, 0x00a64b, 0x00a64d, 0x00a64f, 0x00a651, 0x00a653, ++ 0x00a655, 0x00a657, 0x00a659, 0x00a65b, 0x00a65d, 0x00a65f, ++ 0x00a661, 0x00a663, 0x00a665, 0x00a667, 0x00a669, 0x00a66b, ++ 0x00a66d, 0x00a681, 0x00a683, 0x00a685, 0x00a687, 0x00a689, ++ 0x00a68b, 0x00a68d, 0x00a68f, 0x00a691, 0x00a693, 0x00a695, ++ 0x00a697, 0x00a699, 0x00a69b, 0x00a723, 0x00a725, 0x00a727, ++ 0x00a729, 0x00a72b, 0x00a72d, 0x00a72f, 0x00a733, 0x00a735, ++ 0x00a737, 0x00a739, 0x00a73b, 0x00a73d, 0x00a73f, 0x00a741, ++ 0x00a743, 0x00a745, 0x00a747, 0x00a749, 0x00a74b, 0x00a74d, ++ 0x00a74f, 0x00a751, 0x00a753, 0x00a755, 0x00a757, 0x00a759, ++ 0x00a75b, 0x00a75d, 0x00a75f, 0x00a761, 0x00a763, 0x00a765, ++ 0x00a767, 0x00a769, 0x00a76b, 0x00a76d, 0x00a76f, 0x00a77a, ++ 0x00a77c, 0x001d79, 0x00a77f, 0x00a781, 0x00a783, 0x00a785, ++ 0x00a787, 0x00a78c, 0x000265, 0x00a791, 0x00a793, 0x00a797, ++ 0x00a799, 0x00a79b, 0x00a79d, 0x00a79f, 0x00a7a1, 0x00a7a3, ++ 0x00a7a5, 0x00a7a7, 0x00a7a9, 0x000266, 0x00025c, 0x000261, ++ 0x00026c, 0x00026a, 0x00029e, 0x000287, 0x00029d, 0x00ab53, ++ 0x00a7b5, 0x00a7b7, 0x0013a0, 0x0013a1, 0x0013a2, 0x0013a3, ++ 0x0013a4, 0x0013a5, 0x0013a6, 0x0013a7, 0x0013a8, 0x0013a9, ++ 0x0013aa, 0x0013ab, 0x0013ac, 0x0013ad, 0x0013ae, 0x0013af, ++ 0x0013b0, 0x0013b1, 0x0013b2, 0x0013b3, 0x0013b4, 0x0013b5, ++ 0x0013b6, 0x0013b7, 0x0013b8, 0x0013b9, 0x0013ba, 0x0013bb, ++ 0x0013bc, 0x0013bd, 0x0013be, 0x0013bf, 0x0013c0, 0x0013c1, ++ 0x0013c2, 0x0013c3, 0x0013c4, 0x0013c5, 0x0013c6, 0x0013c7, ++ 0x0013c8, 0x0013c9, 0x0013ca, 0x0013cb, 0x0013cc, 0x0013cd, ++ 0x0013ce, 0x0013cf, 0x0013d0, 0x0013d1, 0x0013d2, 0x0013d3, ++ 0x0013d4, 0x0013d5, 0x0013d6, 0x0013d7, 0x0013d8, 0x0013d9, ++ 0x0013da, 0x0013db, 0x0013dc, 0x0013dd, 0x0013de, 0x0013df, ++ 0x0013e0, 0x0013e1, 0x0013e2, 0x0013e3, 0x0013e4, 0x0013e5, ++ 0x0013e6, 0x0013e7, 0x0013e8, 0x0013e9, 0x0013ea, 0x0013eb, ++ 0x0013ec, 0x0013ed, 0x0013ee, 0x0013ef, 0x000066, 0x000066, ++ 0x000066, 0x000069, 0x000066, 0x00006c, 0x000066, 0x000066, ++ 0x000069, 0x000066, 0x000066, 0x00006c, 0x000073, 0x000074, ++ 0x000073, 0x000074, 0x000574, 0x000576, 0x000574, 0x000565, ++ 0x000574, 0x00056b, 0x00057e, 0x000576, 0x000574, 0x00056d, ++ 0x00ff41, 0x00ff42, 0x00ff43, 0x00ff44, 0x00ff45, 0x00ff46, ++ 0x00ff47, 0x00ff48, 0x00ff49, 0x00ff4a, 0x00ff4b, 0x00ff4c, ++ 0x00ff4d, 0x00ff4e, 0x00ff4f, 0x00ff50, 0x00ff51, 0x00ff52, ++ 0x00ff53, 0x00ff54, 0x00ff55, 0x00ff56, 0x00ff57, 0x00ff58, ++ 0x00ff59, 0x00ff5a, 0x010428, 0x010429, 0x01042a, 0x01042b, ++ 0x01042c, 0x01042d, 0x01042e, 0x01042f, 0x010430, 0x010431, ++ 0x010432, 0x010433, 0x010434, 0x010435, 0x010436, 0x010437, ++ 0x010438, 0x010439, 0x01043a, 0x01043b, 0x01043c, 0x01043d, ++ 0x01043e, 0x01043f, 0x010440, 0x010441, 0x010442, 0x010443, ++ 0x010444, 0x010445, 0x010446, 0x010447, 0x010448, 0x010449, ++ 0x01044a, 0x01044b, 0x01044c, 0x01044d, 0x01044e, 0x01044f, ++ 0x0104d8, 0x0104d9, 0x0104da, 0x0104db, 0x0104dc, 0x0104dd, ++ 0x0104de, 0x0104df, 0x0104e0, 0x0104e1, 0x0104e2, 0x0104e3, ++ 0x0104e4, 0x0104e5, 0x0104e6, 0x0104e7, 0x0104e8, 0x0104e9, ++ 0x0104ea, 0x0104eb, 0x0104ec, 0x0104ed, 0x0104ee, 0x0104ef, ++ 0x0104f0, 0x0104f1, 0x0104f2, 0x0104f3, 0x0104f4, 0x0104f5, ++ 0x0104f6, 0x0104f7, 0x0104f8, 0x0104f9, 0x0104fa, 0x0104fb, ++ 0x010cc0, 0x010cc1, 0x010cc2, 0x010cc3, 0x010cc4, 0x010cc5, ++ 0x010cc6, 0x010cc7, 0x010cc8, 0x010cc9, 0x010cca, 0x010ccb, ++ 0x010ccc, 0x010ccd, 0x010cce, 0x010ccf, 0x010cd0, 0x010cd1, ++ 0x010cd2, 0x010cd3, 0x010cd4, 0x010cd5, 0x010cd6, 0x010cd7, ++ 0x010cd8, 0x010cd9, 0x010cda, 0x010cdb, 0x010cdc, 0x010cdd, ++ 0x010cde, 0x010cdf, 0x010ce0, 0x010ce1, 0x010ce2, 0x010ce3, ++ 0x010ce4, 0x010ce5, 0x010ce6, 0x010ce7, 0x010ce8, 0x010ce9, ++ 0x010cea, 0x010ceb, 0x010cec, 0x010ced, 0x010cee, 0x010cef, ++ 0x010cf0, 0x010cf1, 0x010cf2, 0x0118c0, 0x0118c1, 0x0118c2, ++ 0x0118c3, 0x0118c4, 0x0118c5, 0x0118c6, 0x0118c7, 0x0118c8, ++ 0x0118c9, 0x0118ca, 0x0118cb, 0x0118cc, 0x0118cd, 0x0118ce, ++ 0x0118cf, 0x0118d0, 0x0118d1, 0x0118d2, 0x0118d3, 0x0118d4, ++ 0x0118d5, 0x0118d6, 0x0118d7, 0x0118d8, 0x0118d9, 0x0118da, ++ 0x0118db, 0x0118dc, 0x0118dd, 0x0118de, 0x0118df, 0x01e922, ++ 0x01e923, 0x01e924, 0x01e925, 0x01e926, 0x01e927, 0x01e928, ++ 0x01e929, 0x01e92a, 0x01e92b, 0x01e92c, 0x01e92d, 0x01e92e, ++ 0x01e92f, 0x01e930, 0x01e931, 0x01e932, 0x01e933, 0x01e934, ++ 0x01e935, 0x01e936, 0x01e937, 0x01e938, 0x01e939, 0x01e93a, ++ 0x01e93b, 0x01e93c, 0x01e93d, 0x01e93e, 0x01e93f, 0x01e940, ++ 0x01e941, 0x01e942, 0x01e943, ++}; ++ ++static u8 apfs_ccc_trie[] = { ++ /* Node for range 0x_____ */ ++ 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0____ */ ++ 0x03, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, ++ /* Node for range 0x1____ */ ++ 0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, ++ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0d, 0x0e, 0x00, ++ /* Node for range 0x00___ */ ++ 0x00, 0x00, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, ++ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, ++ /* Node for range 0x01___ */ ++ 0x1c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1e, ++ 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x00, 0x00, ++ /* Node for range 0x02___ */ ++ 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x26, 0x27, 0x00, 0x00, ++ /* Node for range 0x03___ */ ++ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a___ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, ++ 0x2a, 0x2b, 0x2c, 0x2d, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0f___ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x2f, 0x00, ++ /* Node for range 0x10___ */ ++ 0x00, 0x30, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x11___ */ ++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, ++ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, ++ /* Node for range 0x16___ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x3d, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1b___ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, ++ /* Node for range 0x1d___ */ ++ 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e___ */ ++ 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x003__ */ ++ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x004__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x005__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x4d, 0x4e, 0x4f, 0x50, 0x00, 0x00, 0x00, ++ /* Node for range 0x006__ */ ++ 0x00, 0x51, 0x00, 0x00, 0x52, 0x53, 0x00, 0x54, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x56, 0x00, ++ /* Node for range 0x007__ */ ++ 0x00, 0x57, 0x00, 0x58, 0x59, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5b, ++ /* Node for range 0x008__ */ ++ 0x00, 0x5c, 0x5d, 0x00, 0x00, 0x5e, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x60, 0x61, ++ /* Node for range 0x009__ */ ++ 0x00, 0x00, 0x00, 0x62, 0x63, 0x64, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x65, 0x66, 0x00, 0x00, 0x00, ++ /* Node for range 0x00a__ */ ++ 0x00, 0x00, 0x00, 0x67, 0x68, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x69, 0x6a, 0x00, 0x00, 0x00, ++ /* Node for range 0x00b__ */ ++ 0x00, 0x00, 0x00, 0x6b, 0x6c, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, ++ /* Node for range 0x00c__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x70, 0x71, 0x00, 0x00, 0x00, ++ /* Node for range 0x00d__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, ++ /* Node for range 0x00e__ */ ++ 0x00, 0x00, 0x00, 0x74, 0x75, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x76, 0x77, 0x00, 0x00, 0x00, ++ /* Node for range 0x00f__ */ ++ 0x00, 0x78, 0x00, 0x79, 0x00, 0x00, 0x00, 0x7a, ++ 0x7b, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, ++ /* Node for range 0x010__ */ ++ 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, ++ 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x013__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x017__ */ ++ 0x00, 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, ++ /* Node for range 0x018__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x019__ */ ++ 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01a__ */ ++ 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x86, 0x87, ++ 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01b__ */ ++ 0x00, 0x00, 0x00, 0x89, 0x8a, 0x00, 0x8b, 0x8c, ++ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x8f, ++ /* Node for range 0x01c__ */ ++ 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, ++ /* Node for range 0x01d__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x94, 0x95, 0x96, 0x97, ++ /* Node for range 0x020__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x9a, ++ /* Node for range 0x02c__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9c, ++ /* Node for range 0x02d__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x9f, ++ /* Node for range 0x030__ */ ++ 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a6__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa3, ++ 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, ++ /* Node for range 0x0a8__ */ ++ 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0xa8, 0xa9, ++ /* Node for range 0x0a9__ */ ++ 0x00, 0x00, 0xaa, 0x00, 0x00, 0xab, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xac, 0xad, 0x00, 0x00, 0x00, ++ /* Node for range 0x0aa__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xae, 0xaf, 0x00, 0x00, 0xb0, ++ /* Node for range 0x0ab__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, ++ /* Node for range 0x0fb__ */ ++ 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0fe__ */ ++ 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x101__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, ++ /* Node for range 0x102__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, ++ /* Node for range 0x103__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x10a__ */ ++ 0xb7, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, ++ /* Node for range 0x110__ */ ++ 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0xbb, ++ 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x111__ */ ++ 0xbd, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbf, ++ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, ++ /* Node for range 0x112__ */ ++ 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, ++ /* Node for range 0x113__ */ ++ 0x00, 0x00, 0x00, 0xc3, 0xc4, 0x00, 0xc5, 0xc6, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x114__ */ ++ 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, ++ /* Node for range 0x115__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xc9, 0xca, 0x00, 0x00, 0x00, ++ /* Node for range 0x116__ */ ++ 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x117__ */ ++ 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x11c__ */ ++ 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x16a__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, ++ /* Node for range 0x16b__ */ ++ 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1bc__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1d1__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xd3, ++ 0xd4, 0x00, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1d2__ */ ++ 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e0__ */ ++ 0xd7, 0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e8__ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, ++ /* Node for range 0x1e9__ */ ++ 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0030_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0031_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe8, 0xdc, 0xdc, ++ 0xdc, 0xdc, 0xe8, 0xd8, 0xdc, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x0032_ */ ++ 0xdc, 0xca, 0xca, 0xdc, 0xdc, 0xdc, 0xdc, 0xca, ++ 0xca, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x0033_ */ ++ 0xdc, 0xdc, 0xdc, 0xdc, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0xdc, 0xdc, 0xdc, 0xdc, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0034_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xf0, 0xe6, 0xdc, ++ 0xdc, 0xdc, 0xe6, 0xe6, 0xe6, 0xdc, 0xdc, 0x00, ++ /* Node for range 0x0035_ */ ++ 0xe6, 0xe6, 0xe6, 0xdc, 0xdc, 0xdc, 0xdc, 0xe6, ++ 0xe8, 0xdc, 0xdc, 0xe6, 0xe9, 0xea, 0xea, 0xe9, ++ /* Node for range 0x0036_ */ ++ 0xea, 0xea, 0xe9, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0048_ */ ++ 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0059_ */ ++ 0x00, 0xdc, 0xe6, 0xe6, 0xe6, 0xe6, 0xdc, 0xe6, ++ 0xe6, 0xe6, 0xde, 0xdc, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x005a_ */ ++ 0xe6, 0xe6, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, ++ 0xe6, 0xe6, 0xdc, 0xe6, 0xe6, 0xde, 0xe4, 0xe6, ++ /* Node for range 0x005b_ */ ++ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, ++ 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x00, 0x17, ++ /* Node for range 0x005c_ */ ++ 0x00, 0x18, 0x19, 0x00, 0xe6, 0xdc, 0x00, 0x12, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0061_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0x1e, 0x1f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0064_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ++ /* Node for range 0x0065_ */ ++ 0x20, 0x21, 0x22, 0xe6, 0xe6, 0xdc, 0xdc, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xdc, 0xe6, 0xe6, 0xdc, ++ /* Node for range 0x0067_ */ ++ 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x006d_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0xe6, ++ /* Node for range 0x006e_ */ ++ 0xe6, 0xe6, 0xe6, 0xdc, 0xe6, 0x00, 0x00, 0xe6, ++ 0xe6, 0x00, 0xdc, 0xe6, 0xe6, 0xdc, 0x00, 0x00, ++ /* Node for range 0x0071_ */ ++ 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0073_ */ ++ 0xe6, 0xdc, 0xe6, 0xe6, 0xdc, 0xe6, 0xe6, 0xdc, ++ 0xdc, 0xdc, 0xe6, 0xdc, 0xdc, 0xe6, 0xdc, 0xe6, ++ /* Node for range 0x0074_ */ ++ 0xe6, 0xe6, 0xdc, 0xe6, 0xdc, 0xe6, 0xdc, 0xe6, ++ 0xdc, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x007e_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x007f_ */ ++ 0xe6, 0xe6, 0xdc, 0xe6, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0081_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0082_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0xe6, 0xe6, 0xe6, ++ 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, ++ /* Node for range 0x0085_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xdc, 0xdc, 0xdc, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x008d_ */ ++ 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x008e_ */ ++ 0xe6, 0xe6, 0x00, 0xdc, 0xe6, 0xe6, 0xdc, 0xe6, ++ 0xe6, 0xdc, 0xe6, 0xe6, 0xe6, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x008f_ */ ++ 0x1b, 0x1c, 0x1d, 0xe6, 0xe6, 0xe6, 0xdc, 0xe6, ++ 0xe6, 0xdc, 0xdc, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0093_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x0094_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x0095_ */ ++ 0x00, 0xe6, 0xdc, 0xe6, 0xe6, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x009b_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x009c_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00a3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x00a4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00ab_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x00ac_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00b3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x00b4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00bc_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00c4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00c5_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x5b, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00cb_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x00cc_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00d4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x00dc_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00e3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x67, 0x67, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00e4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x6b, 0x6b, 0x6b, 0x6b, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00eb_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x76, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00ec_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x7a, 0x7a, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00f1_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xdc, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00f3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0xdc, ++ 0x00, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00f7_ */ ++ 0x00, 0x81, 0x82, 0x00, 0x84, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, ++ /* Node for range 0x00f8_ */ ++ 0x82, 0x00, 0xe6, 0xe6, 0x09, 0x00, 0xe6, 0xe6, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x00fc_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0103_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, ++ 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0108_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, ++ /* Node for range 0x0135_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0171_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0173_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x017d_ */ ++ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, ++ /* Node for range 0x018a_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0193_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xde, 0xe6, 0xdc, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01a1_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, ++ 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01a6_ */ ++ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01a7_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0xdc, ++ /* Node for range 0x01ab_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xdc, 0xdc, 0xdc, ++ 0xdc, 0xdc, 0xdc, 0xe6, 0xe6, 0xdc, 0x00, 0x00, ++ /* Node for range 0x01b3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01b4_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01b6_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xe6, 0xdc, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x01b7_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01ba_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01be_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01bf_ */ ++ 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01c3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01cd_ */ ++ 0xe6, 0xe6, 0xe6, 0x00, 0x01, 0xdc, 0xdc, 0xdc, ++ 0xdc, 0xdc, 0xe6, 0xe6, 0xdc, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x01ce_ */ ++ 0xe6, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, ++ /* Node for range 0x01cf_ */ ++ 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, ++ 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x01dc_ */ ++ 0xe6, 0xe6, 0xdc, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xdc, 0xe6, 0xe6, 0xea, 0xd6, 0xdc, ++ /* Node for range 0x01dd_ */ ++ 0xca, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x01de_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x01df_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xe6, 0xe9, 0xdc, 0xe6, 0xdc, ++ /* Node for range 0x020d_ */ ++ 0xe6, 0xe6, 0x01, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0x01, 0x01, 0x01, 0xe6, 0xe6, 0x00, 0x00, 0x00, ++ /* Node for range 0x020e_ */ ++ 0x00, 0xe6, 0x00, 0x00, 0x00, 0x01, 0x01, 0xe6, ++ 0xdc, 0xe6, 0x01, 0x01, 0xdc, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x020f_ */ ++ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x02ce_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, ++ /* Node for range 0x02cf_ */ ++ 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x02d7_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x02de_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x02df_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0302_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0xda, 0xe4, 0xe8, 0xde, 0xe0, 0xe0, ++ /* Node for range 0x0309_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a66_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, ++ /* Node for range 0x0a67_ */ ++ 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, ++ /* Node for range 0x0a69_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ /* Node for range 0x0a6f_ */ ++ 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a80_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a8c_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a8e_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x0a8f_ */ ++ 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a92_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xdc, 0xdc, 0xdc, 0x00, 0x00, ++ /* Node for range 0x0a95_ */ ++ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a9b_ */ ++ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0a9c_ */ ++ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0aab_ */ ++ 0xe6, 0x00, 0xe6, 0xe6, 0xdc, 0x00, 0x00, 0xe6, ++ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ /* Node for range 0x0aac_ */ ++ 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0aaf_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x0abe_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x0fb1_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, ++ /* Node for range 0x0fe2_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xdc, ++ 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xe6, 0xe6, ++ /* Node for range 0x101f_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, ++ /* Node for range 0x102e_ */ ++ 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1037_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x10a0_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0xe6, ++ /* Node for range 0x10a3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xe6, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x10ae_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xdc, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1104_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1107_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x110b_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1110_ */ ++ 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1113_ */ ++ 0x00, 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1117_ */ ++ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x111c_ */ ++ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1123_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x07, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x112e_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1133_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, ++ /* Node for range 0x1134_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, ++ /* Node for range 0x1136_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, ++ /* Node for range 0x1137_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1144_ */ ++ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x114c_ */ ++ 0x00, 0x00, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x115b_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x115c_ */ ++ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1163_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x116b_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x07, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1172_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x11c3_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, ++ /* Node for range 0x16af_ */ ++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x16b3_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1bc9_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, ++ /* Node for range 0x1d16_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0x01, ++ 0x01, 0x01, 0x00, 0x00, 0x00, 0xe2, 0xd8, 0xd8, ++ /* Node for range 0x1d17_ */ ++ 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, ++ /* Node for range 0x1d18_ */ ++ 0xdc, 0xdc, 0xdc, 0x00, 0x00, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xdc, 0xdc, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1d1a_ */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, ++ /* Node for range 0x1d24_ */ ++ 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e00_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x1e01_ */ ++ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, ++ /* Node for range 0x1e02_ */ ++ 0xe6, 0xe6, 0x00, 0xe6, 0xe6, 0x00, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e8d_ */ ++ 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Node for range 0x1e94_ */ ++ 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6, 0xe6, ++ 0xe6, 0xe6, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, ++}; +diff --git a/fs/apfs/unicode.h b/fs/apfs/unicode.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/unicode.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#ifndef _APFS_UNICODE_H ++#define _APFS_UNICODE_H ++ ++#include ++ ++/* ++ * This structure helps apfs_normalize_next() to retrieve one normalized ++ * (and case-folded) UTF-32 character at a time from a UTF-8 string. ++ */ ++struct apfs_unicursor { ++ const char *utf8curr; /* Start of UTF-8 to decompose and reorder */ ++ unsigned int total_len; /* Length of the whole UTF-8 string */ ++ int length; /* Length of normalization until next starter */ ++ int last_pos; /* Offset in substring of last char returned */ ++ u8 last_ccc; /* CCC of the last character returned */ ++}; ++ ++extern void apfs_init_unicursor(struct apfs_unicursor *cursor, const char *utf8str, unsigned int total_len); ++extern unicode_t apfs_normalize_next(struct apfs_unicursor *cursor, ++ bool case_fold); ++ ++#endif /* _APFS_UNICODE_H */ +diff --git a/fs/apfs/version.h b/fs/apfs/version.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/version.h +@@ -0,0 +1 @@ ++#define GIT_COMMIT "" +diff --git a/fs/apfs/xattr.c b/fs/apfs/xattr.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/xattr.c +@@ -0,0 +1,914 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2018 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_xattr_from_query - Read the xattr record found by a successful query ++ * @query: the query that found the record ++ * @xattr: Return parameter. The xattr record found. ++ * ++ * Reads the xattr record into @xattr and performs some basic sanity checks ++ * as a protection against crafted filesystems. Returns 0 on success or ++ * -EFSCORRUPTED otherwise. ++ * ++ * The caller must not free @query while @xattr is in use, because @xattr->name ++ * and @xattr->xdata point to data on disk. ++ */ ++static int apfs_xattr_from_query(struct apfs_query *query, ++ struct apfs_xattr *xattr) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_xattr_val *xattr_val; ++ struct apfs_xattr_key *xattr_key; ++ char *raw = query->node->object.data; ++ int datalen = query->len - sizeof(*xattr_val); ++ int namelen = query->key_len - sizeof(*xattr_key); ++ ++ if (namelen < 1 || datalen < 0) { ++ apfs_err(sb, "bad length of name (%d) or data (%d)", namelen, datalen); ++ return -EFSCORRUPTED; ++ } ++ ++ xattr_val = (struct apfs_xattr_val *)(raw + query->off); ++ xattr_key = (struct apfs_xattr_key *)(raw + query->key_off); ++ ++ if (namelen != le16_to_cpu(xattr_key->name_len)) { ++ apfs_err(sb, "inconsistent name length (%d vs %d)", namelen, le16_to_cpu(xattr_key->name_len)); ++ return -EFSCORRUPTED; ++ } ++ ++ /* The xattr name must be NULL-terminated */ ++ if (xattr_key->name[namelen - 1] != 0) { ++ apfs_err(sb, "null termination missing"); ++ return -EFSCORRUPTED; ++ } ++ ++ xattr->has_dstream = le16_to_cpu(xattr_val->flags) & ++ APFS_XATTR_DATA_STREAM; ++ ++ if (xattr->has_dstream && datalen != sizeof(struct apfs_xattr_dstream)) { ++ apfs_err(sb, "bad data length (%d)", datalen); ++ return -EFSCORRUPTED; ++ } ++ if (!xattr->has_dstream && datalen != le16_to_cpu(xattr_val->xdata_len)) { ++ apfs_err(sb, "inconsistent data length (%d vs %d)", datalen, le16_to_cpu(xattr_val->xdata_len)); ++ return -EFSCORRUPTED; ++ } ++ ++ xattr->name = xattr_key->name; ++ xattr->name_len = namelen - 1; /* Don't count the NULL termination */ ++ xattr->xdata = xattr_val->xdata; ++ xattr->xdata_len = datalen; ++ return 0; ++} ++ ++/** ++ * apfs_dstream_from_xattr - Get the dstream info for a dstream xattr ++ * @sb: filesystem superblock ++ * @xattr: in-memory xattr record (already sanity-checked) ++ * @dstream: on return, the data stream info ++ */ ++static void apfs_dstream_from_xattr(struct super_block *sb, struct apfs_xattr *xattr, struct apfs_dstream_info *dstream) ++{ ++ struct apfs_xattr_dstream *xdata = (void *)xattr->xdata; ++ ++ dstream->ds_sb = sb; ++ dstream->ds_inode = NULL; ++ dstream->ds_id = le64_to_cpu(xdata->xattr_obj_id); ++ dstream->ds_size = le64_to_cpu(xdata->dstream.size); ++ dstream->ds_sparse_bytes = 0; /* Irrelevant for xattrs */ ++ ++ dstream->ds_cached_ext.len = 0; ++ dstream->ds_ext_dirty = false; ++ spin_lock_init(&dstream->ds_ext_lock); ++ ++ /* Xattrs can't be cloned */ ++ dstream->ds_shared = false; ++} ++ ++/** ++ * apfs_xattr_extents_read - Read the value of a xattr from its extents ++ * @parent: inode the attribute belongs to ++ * @xattr: the xattr structure ++ * @buffer: where to copy the attribute value ++ * @size: size of @buffer ++ * @only_whole: are partial reads banned? ++ * ++ * Copies the value of @xattr to @buffer, if provided. If @buffer is NULL, just ++ * computes the size of the buffer required. ++ * ++ * Returns the number of bytes used/required, or a negative error code in case ++ * of failure. ++ */ ++static int apfs_xattr_extents_read(struct inode *parent, ++ struct apfs_xattr *xattr, ++ void *buffer, size_t size, bool only_whole) ++{ ++ struct super_block *sb = parent->i_sb; ++ struct apfs_dstream_info *dstream; ++ int length, ret; ++ ++ dstream = kzalloc(sizeof(*dstream), GFP_KERNEL); ++ if (!dstream) ++ return -ENOMEM; ++ apfs_dstream_from_xattr(sb, xattr, dstream); ++ ++ length = dstream->ds_size; ++ if (length < 0 || length < dstream->ds_size) { ++ /* TODO: avoid overflow here for huge compressed files */ ++ apfs_warn(sb, "xattr is too big to read on linux (0x%llx)", dstream->ds_size); ++ ret = -E2BIG; ++ goto out; ++ } ++ ++ if (!buffer) { ++ /* All we want is the length */ ++ ret = length; ++ goto out; ++ } ++ ++ if (only_whole) { ++ if (length > size) { ++ /* xattr won't fit in the buffer */ ++ ret = -ERANGE; ++ goto out; ++ } ++ } else { ++ if (length > size) ++ length = size; ++ } ++ ++ ret = apfs_nonsparse_dstream_read(dstream, buffer, length, 0 /* offset */); ++ if (ret == 0) ++ ret = length; ++ ++out: ++ kfree(dstream); ++ return ret; ++} ++ ++/** ++ * apfs_xattr_inline_read - Read the value of an inline xattr ++ * @xattr: the xattr structure ++ * @buffer: where to copy the attribute value ++ * @size: size of @buffer ++ * @only_whole: are partial reads banned? ++ * ++ * Copies the inline value of @xattr to @buffer, if provided. If @buffer is ++ * NULL, just computes the size of the buffer required. ++ * ++ * Returns the number of bytes used/required, or a negative error code in case ++ * of failure. ++ */ ++static int apfs_xattr_inline_read(struct apfs_xattr *xattr, void *buffer, size_t size, bool only_whole) ++{ ++ int length = xattr->xdata_len; ++ ++ if (!buffer) /* All we want is the length */ ++ return length; ++ if (only_whole) { ++ if (length > size) /* xattr won't fit in the buffer */ ++ return -ERANGE; ++ } else { ++ if (length > size) ++ length = size; ++ } ++ memcpy(buffer, xattr->xdata, length); ++ return length; ++} ++ ++/** ++ * apfs_xattr_get_compressed_data - Get the compressed data in a named attribute ++ * @inode: inode the attribute belongs to ++ * @name: name of the attribute ++ * @cdata: compressed data struct to set on return ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_xattr_get_compressed_data(struct inode *inode, const char *name, struct apfs_compressed_data *cdata) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_xattr xattr; ++ u64 cnid = apfs_ino(inode); ++ int ret; ++ ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_xattr_key(cnid, name, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx (%s)", cnid, name); ++ goto done; ++ } ++ ++ ret = apfs_xattr_from_query(query, &xattr); ++ if (ret) { ++ apfs_err(sb, "bad xattr record in inode 0x%llx", cnid); ++ goto done; ++ } ++ ++ cdata->has_dstream = xattr.has_dstream; ++ if (cdata->has_dstream) { ++ struct apfs_dstream_info *dstream = NULL; ++ ++ dstream = kzalloc(sizeof(*dstream), GFP_KERNEL); ++ if (!dstream) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ apfs_dstream_from_xattr(sb, &xattr, dstream); ++ ++ cdata->dstream = dstream; ++ cdata->size = dstream->ds_size; ++ } else { ++ void *data = NULL; ++ int len; ++ ++ len = xattr.xdata_len; ++ if (len > APFS_XATTR_MAX_EMBEDDED_SIZE) { ++ apfs_err(sb, "inline xattr too big"); ++ ret = -EFSCORRUPTED; ++ goto done; ++ } ++ data = kzalloc(len, GFP_KERNEL); ++ if (!data) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ memcpy(data, xattr.xdata, len); ++ ++ cdata->data = data; ++ cdata->size = len; ++ } ++ ret = 0; ++ ++done: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_release_compressed_data - Clean up a compressed data struct ++ * @cdata: struct to clean up (but not free) ++ */ ++void apfs_release_compressed_data(struct apfs_compressed_data *cdata) ++{ ++ if (!cdata) ++ return; ++ ++ if (cdata->has_dstream) { ++ kfree(cdata->dstream); ++ cdata->dstream = NULL; ++ } else { ++ kfree(cdata->data); ++ cdata->data = NULL; ++ } ++} ++ ++/** ++ * apfs_compressed_data_read - Read from a compressed data struct ++ * @cdata: compressed data struct ++ * @buf: destination buffer ++ * @count: exact number of bytes to read ++ * @offset: dstream offset to read from ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_compressed_data_read(struct apfs_compressed_data *cdata, void *buf, size_t count, u64 offset) ++{ ++ if (cdata->has_dstream) ++ return apfs_nonsparse_dstream_read(cdata->dstream, buf, count, offset); ++ ++ if (offset > cdata->size || count > cdata->size - offset) { ++ apfs_err(NULL, "reading past the end (0x%llx-0x%llx)", offset, (unsigned long long)count); ++ /* No caller is expected to legitimately read out-of-bounds */ ++ return -EFSCORRUPTED; ++ } ++ memcpy(buf, cdata->data + offset, count); ++ return 0; ++} ++ ++/** ++ * __apfs_xattr_get - Find and read a named attribute ++ * @inode: inode the attribute belongs to ++ * @name: name of the attribute ++ * @buffer: where to copy the attribute value ++ * @size: size of @buffer ++ * ++ * This does the same as apfs_xattr_get(), but without taking any locks. ++ */ ++int __apfs_xattr_get(struct inode *inode, const char *name, void *buffer, ++ size_t size) ++{ ++ return ____apfs_xattr_get(inode, name, buffer, size, true /* only_whole */); ++} ++ ++/** ++ * ____apfs_xattr_get - Find and read a named attribute, optionally header only ++ * @inode: inode the attribute belongs to ++ * @name: name of the attribute ++ * @buffer: where to copy the attribute value ++ * @size: size of @buffer ++ * @only_whole: must read complete (no partial header read allowed) ++ */ ++int ____apfs_xattr_get(struct inode *inode, const char *name, void *buffer, ++ size_t size, bool only_whole) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ struct apfs_xattr xattr; ++ u64 cnid = apfs_ino(inode); ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_xattr_key(cnid, name, &query->key); ++ query->flags |= APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ if (ret != -ENODATA) ++ apfs_err(sb, "query failed for id 0x%llx (%s)", cnid, name); ++ goto done; ++ } ++ ++ ret = apfs_xattr_from_query(query, &xattr); ++ if (ret) { ++ apfs_err(sb, "bad xattr record in inode 0x%llx", cnid); ++ goto done; ++ } ++ ++ if (xattr.has_dstream) ++ ret = apfs_xattr_extents_read(inode, &xattr, buffer, size, only_whole); ++ else ++ ret = apfs_xattr_inline_read(&xattr, buffer, size, only_whole); ++ ++done: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_xattr_get - Find and read a named attribute ++ * @inode: inode the attribute belongs to ++ * @name: name of the attribute ++ * @buffer: where to copy the attribute value ++ * @size: size of @buffer ++ * ++ * Finds an extended attribute and copies its value to @buffer, if provided. If ++ * @buffer is NULL, just computes the size of the buffer required. ++ * ++ * Returns the number of bytes used/required, or a negative error code in case ++ * of failure. ++ */ ++static int apfs_xattr_get(struct inode *inode, const char *name, void *buffer, size_t size) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(inode->i_sb); ++ int ret; ++ ++ down_read(&nxi->nx_big_sem); ++ ret = __apfs_xattr_get(inode, name, buffer, size); ++ up_read(&nxi->nx_big_sem); ++ if (ret > XATTR_SIZE_MAX) { ++ apfs_warn(inode->i_sb, "xattr is too big to read on linux (%d)", ret); ++ return -E2BIG; ++ } ++ return ret; ++} ++ ++static int apfs_xattr_osx_get(const struct xattr_handler *handler, ++ struct dentry *unused, struct inode *inode, ++ const char *name, void *buffer, size_t size) ++{ ++ /* Ignore the fake 'osx' prefix */ ++ return apfs_xattr_get(inode, name, buffer, size); ++} ++ ++/** ++ * apfs_delete_xattr - Delete an extended attribute ++ * @query: successful query pointing to the xattr to delete ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++static int apfs_delete_xattr(struct apfs_query *query) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_xattr xattr; ++ struct apfs_dstream_info *dstream; ++ int err; ++ ++ err = apfs_xattr_from_query(query, &xattr); ++ if (err) { ++ apfs_err(sb, "bad xattr record"); ++ return err; ++ } ++ ++ if (!xattr.has_dstream) ++ return apfs_btree_remove(query); ++ ++ dstream = kzalloc(sizeof(*dstream), GFP_KERNEL); ++ if (!dstream) ++ return -ENOMEM; ++ apfs_dstream_from_xattr(sb, &xattr, dstream); ++ ++ /* ++ * Remove the xattr record before truncation, because truncation creates ++ * new queries and makes ours invalid. This stuff is all too subtle, I ++ * really need to add some assertions (TODO). ++ */ ++ err = apfs_btree_remove(query); ++ if (err) { ++ apfs_err(sb, "removal failed"); ++ goto fail; ++ } ++ err = apfs_truncate(dstream, 0); ++ if (err) ++ apfs_err(sb, "truncation failed for dstream 0x%llx", dstream->ds_id); ++ ++fail: ++ kfree(dstream); ++ return err; ++} ++ ++/** ++ * apfs_delete_any_xattr - Delete any single xattr for a given inode ++ * @inode: the vfs inode ++ * ++ * Intended to be called repeatedly, to delete all the xattrs one by one. ++ * Returns -EAGAIN on success until the process is complete, then it returns ++ * 0. Returns other negative error codes in case of failure. ++ */ ++static int apfs_delete_any_xattr(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query; ++ int ret; ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) ++ return -ENOMEM; ++ apfs_init_xattr_key(apfs_ino(inode), NULL /* name */, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_ANY_NAME | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ if (ret == -ENODATA) ++ ret = 0; /* No more xattrs, we are done */ ++ else ++ apfs_err(sb, "query failed for ino 0x%llx", apfs_ino(inode)); ++ goto out; ++ } ++ ++ ret = apfs_delete_xattr(query); ++ if (!ret) ++ ret = -EAGAIN; ++ else ++ apfs_err(sb, "xattr deletion failed"); ++ ++out: ++ apfs_free_query(query); ++ return ret; ++} ++ ++/** ++ * apfs_delete_all_xattrs - Delete all xattrs for a given inode ++ * @inode: the vfs inode ++ * ++ * Returns 0 on success or a negative error code in case of failure. ++ */ ++int apfs_delete_all_xattrs(struct inode *inode) ++{ ++ struct apfs_nxsb_info *nxi = APFS_NXI(inode->i_sb); ++ int ret; ++ ++ lockdep_assert_held_write(&nxi->nx_big_sem); ++ ++ do { ++ ret = apfs_delete_any_xattr(inode); ++ } while (ret == -EAGAIN); ++ ++ return ret; ++} ++ ++/** ++ * apfs_build_xattr_key - Allocate and initialize the key for a xattr record ++ * @name: xattr name ++ * @ino: inode number for xattr's owner ++ * @key_p: on return, a pointer to the new on-disk key structure ++ * ++ * Returns the length of the key, or a negative error code in case of failure. ++ */ ++static int apfs_build_xattr_key(const char *name, u64 ino, struct apfs_xattr_key **key_p) ++{ ++ struct apfs_xattr_key *key; ++ u16 namelen = strlen(name) + 1; /* We count the null-termination */ ++ int key_len; ++ ++ key_len = sizeof(*key) + namelen; ++ key = kmalloc(key_len, GFP_KERNEL); ++ if (!key) ++ return -ENOMEM; ++ ++ apfs_key_set_hdr(APFS_TYPE_XATTR, ino, key); ++ key->name_len = cpu_to_le16(namelen); ++ strscpy(key->name, name, namelen); ++ ++ *key_p = key; ++ return key_len; ++} ++ ++/** ++ * apfs_build_dstream_xattr_val - Allocate and init value for a dstream xattr ++ * @dstream: data stream info ++ * @val_p: on return, a pointer to the new on-disk value structure ++ * ++ * Returns the length of the value, or a negative error code in case of failure. ++ */ ++static int apfs_build_dstream_xattr_val(struct apfs_dstream_info *dstream, struct apfs_xattr_val **val_p) ++{ ++ struct apfs_xattr_val *val; ++ struct apfs_xattr_dstream *dstream_raw; ++ int val_len; ++ ++ val_len = sizeof(*val) + sizeof(*dstream_raw); ++ val = kzalloc(val_len, GFP_KERNEL); ++ if (!val) ++ return -ENOMEM; ++ ++ val->flags = cpu_to_le16(APFS_XATTR_DATA_STREAM); ++ val->xdata_len = cpu_to_le16(sizeof(*dstream_raw)); ++ ++ dstream_raw = (void *)val->xdata; ++ dstream_raw->xattr_obj_id = cpu_to_le64(dstream->ds_id); ++ dstream_raw->dstream.size = cpu_to_le64(dstream->ds_size); ++ dstream_raw->dstream.alloced_size = cpu_to_le64(apfs_alloced_size(dstream)); ++ if (apfs_vol_is_encrypted(dstream->ds_sb)) ++ dstream_raw->dstream.default_crypto_id = cpu_to_le64(dstream->ds_id); ++ ++ *val_p = val; ++ return val_len; ++} ++ ++/** ++ * apfs_build_inline_xattr_val - Allocate and init value for an inline xattr ++ * @value: content of the xattr ++ * @size: size of @value ++ * @val_p: on return, a pointer to the new on-disk value structure ++ * ++ * Returns the length of the value, or a negative error code in case of failure. ++ */ ++static int apfs_build_inline_xattr_val(const void *value, size_t size, struct apfs_xattr_val **val_p) ++{ ++ struct apfs_xattr_val *val; ++ int val_len; ++ ++ val_len = sizeof(*val) + size; ++ val = kmalloc(val_len, GFP_KERNEL); ++ if (!val) ++ return -ENOMEM; ++ ++ val->flags = cpu_to_le16(APFS_XATTR_DATA_EMBEDDED); ++ val->xdata_len = cpu_to_le16(size); ++ memcpy(val->xdata, value, size); ++ ++ *val_p = val; ++ return val_len; ++} ++ ++/** ++ * apfs_create_xattr_dstream - Create the extents for a dstream xattr ++ * @sb: filesystem superblock ++ * @value: value for the attribute ++ * @size: sizeo of @value ++ * ++ * Returns the info for the created data stream, or an error pointer in case ++ * of failure. ++ */ ++static struct apfs_dstream_info *apfs_create_xattr_dstream(struct super_block *sb, const void *value, size_t size) ++{ ++ struct apfs_superblock *vsb_raw = APFS_SB(sb)->s_vsb_raw; ++ struct apfs_dstream_info *dstream; ++ int blkcnt, i; ++ int err; ++ ++ dstream = kzalloc(sizeof(*dstream), GFP_KERNEL); ++ if (!dstream) ++ return ERR_PTR(-ENOMEM); ++ dstream->ds_sb = sb; ++ spin_lock_init(&dstream->ds_ext_lock); ++ ++ apfs_assert_in_transaction(sb, &vsb_raw->apfs_o); ++ dstream->ds_id = le64_to_cpu(vsb_raw->apfs_next_obj_id); ++ le64_add_cpu(&vsb_raw->apfs_next_obj_id, 1); ++ ++ blkcnt = (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; ++ for (i = 0; i < blkcnt; i++) { ++ struct buffer_head *bh; ++ int off, tocopy; ++ u64 bno; ++ ++ err = apfs_dstream_get_new_bno(dstream, i, &bno); ++ if (err) { ++ apfs_err(sb, "failed to get new block in dstream 0x%llx", dstream->ds_id); ++ goto fail; ++ } ++ bh = apfs_sb_bread(sb, bno); ++ if (!bh) { ++ apfs_err(sb, "failed to read new block"); ++ err = -EIO; ++ goto fail; ++ } ++ ++ err = apfs_transaction_join(sb, bh); ++ if (err) { ++ brelse(bh); ++ goto fail; ++ } ++ ++ off = i << sb->s_blocksize_bits; ++ tocopy = min(sb->s_blocksize, (unsigned long)(size - off)); ++ memcpy(bh->b_data, value + off, tocopy); ++ if (tocopy < sb->s_blocksize) ++ memset(bh->b_data + tocopy, 0, sb->s_blocksize - tocopy); ++ brelse(bh); ++ ++ dstream->ds_size += tocopy; ++ } ++ ++ err = apfs_flush_extent_cache(dstream); ++ if (err) { ++ apfs_err(sb, "extent cache flush failed for dstream 0x%llx", dstream->ds_id); ++ goto fail; ++ } ++ return dstream; ++ ++fail: ++ kfree(dstream); ++ return ERR_PTR(err); ++} ++ ++/** ++ * apfs_xattr_dstream_from_query - Extract the dstream from a xattr record ++ * @query: the query that found the record ++ * @dstream_p: on return, the newly allocated dstream info (or NULL if none) ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++static int apfs_xattr_dstream_from_query(struct apfs_query *query, struct apfs_dstream_info **dstream_p) ++{ ++ struct super_block *sb = query->node->object.sb; ++ struct apfs_dstream_info *dstream = NULL; ++ struct apfs_xattr xattr; ++ int err; ++ ++ err = apfs_xattr_from_query(query, &xattr); ++ if (err) { ++ apfs_err(sb, "bad xattr record"); ++ return err; ++ } ++ ++ if (xattr.has_dstream) { ++ dstream = kzalloc(sizeof(*dstream), GFP_KERNEL); ++ if (!dstream) ++ return -ENOMEM; ++ apfs_dstream_from_xattr(sb, &xattr, dstream); ++ } ++ *dstream_p = dstream; ++ return 0; ++} ++ ++/** ++ * apfs_xattr_set - Write a named attribute ++ * @inode: inode the attribute will belong to ++ * @name: name for the attribute ++ * @value: value for the attribute ++ * @size: size of @value ++ * @flags: XATTR_REPLACE and XATTR_CREATE ++ * ++ * Returns 0 on success, or a negative error code in case of failure. ++ */ ++int apfs_xattr_set(struct inode *inode, const char *name, const void *value, ++ size_t size, int flags) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_query *query = NULL; ++ u64 cnid = apfs_ino(inode); ++ int key_len, val_len; ++ struct apfs_xattr_key *raw_key = NULL; ++ struct apfs_xattr_val *raw_val = NULL; ++ struct apfs_dstream_info *dstream = NULL; ++ struct apfs_dstream_info *old_dstream = NULL; ++ int ret; ++ ++ if (size > APFS_XATTR_MAX_EMBEDDED_SIZE) { ++ dstream = apfs_create_xattr_dstream(sb, value, size); ++ if (IS_ERR(dstream)) { ++ apfs_err(sb, "failed to set xattr dstream for ino 0x%llx", apfs_ino(inode)); ++ return PTR_ERR(dstream); ++ } ++ } ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ apfs_init_xattr_key(cnid, name, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_EXACT; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret) { ++ if (ret != -ENODATA) { ++ apfs_err(sb, "query failed for id 0x%llx (%s)", cnid, name); ++ goto done; ++ } else if (flags & XATTR_REPLACE) { ++ goto done; ++ } ++ } else if (flags & XATTR_CREATE) { ++ ret = -EEXIST; ++ goto done; ++ } else if (!value) { ++ ret = apfs_delete_xattr(query); ++ if (ret) ++ apfs_err(sb, "xattr deletion failed"); ++ goto done; ++ } else { ++ /* Remember the old dstream to clean it up later */ ++ ret = apfs_xattr_dstream_from_query(query, &old_dstream); ++ if (ret) { ++ apfs_err(sb, "failed to get the old dstream"); ++ goto done; ++ } ++ } ++ ++ key_len = apfs_build_xattr_key(name, cnid, &raw_key); ++ if (key_len < 0) { ++ ret = key_len; ++ goto done; ++ } ++ ++ if (dstream) ++ val_len = apfs_build_dstream_xattr_val(dstream, &raw_val); ++ else ++ val_len = apfs_build_inline_xattr_val(value, size, &raw_val); ++ if (val_len < 0) { ++ ret = val_len; ++ goto done; ++ } ++ ++ /* For now this is the only system xattr we support */ ++ if (strcmp(name, APFS_XATTR_NAME_SYMLINK) == 0) ++ raw_val->flags |= cpu_to_le16(APFS_XATTR_FILE_SYSTEM_OWNED); ++ ++ if (ret) ++ ret = apfs_btree_insert(query, raw_key, key_len, raw_val, val_len); ++ else ++ ret = apfs_btree_replace(query, raw_key, key_len, raw_val, val_len); ++ if (ret) { ++ apfs_err(sb, "insertion/update failed for id 0x%llx (%s)", cnid, name); ++ goto done; ++ } ++ ++ if (old_dstream) { ++ ret = apfs_truncate(old_dstream, 0); ++ if (ret) ++ apfs_err(sb, "truncation failed for dstream 0x%llx", old_dstream->ds_id); ++ } ++ ++done: ++ kfree(dstream); ++ kfree(old_dstream); ++ kfree(raw_val); ++ kfree(raw_key); ++ apfs_free_query(query); ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++static int apfs_xattr_osx_set(const struct xattr_handler *handler, ++ struct dentry *unused, struct inode *inode, const char *name, ++ const void *value, size_t size, int flags) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6) ++static int apfs_xattr_osx_set(const struct xattr_handler *handler, ++ struct user_namespace *mnt_userns, struct dentry *unused, ++ struct inode *inode, const char *name, const void *value, ++ size_t size, int flags) ++#else ++static int apfs_xattr_osx_set(const struct xattr_handler *handler, ++ struct mnt_idmap *idmap, struct dentry *unused, ++ struct inode *inode, const char *name, const void *value, ++ size_t size, int flags) ++#endif ++{ ++ struct super_block *sb = inode->i_sb; ++ int err; ++ ++ err = apfs_transaction_start(sb, value ? APFS_TRANS_REG : APFS_TRANS_DEL); ++ if (err) ++ return err; ++ ++ /* Ignore the fake 'osx' prefix */ ++ err = apfs_xattr_set(inode, name, value, size, flags); ++ if (err) ++ goto fail; ++ ++ err = apfs_transaction_commit(sb); ++ if (!err) ++ return 0; ++ ++fail: ++ apfs_transaction_abort(sb); ++ return err; ++} ++ ++static const struct xattr_handler apfs_xattr_osx_handler = { ++ .prefix = XATTR_MAC_OSX_PREFIX, ++ .get = apfs_xattr_osx_get, ++ .set = apfs_xattr_osx_set, ++}; ++ ++/* On-disk xattrs have no namespace; use a fake 'osx' prefix in the kernel */ ++const struct xattr_handler *apfs_xattr_handlers[] = { ++ &apfs_xattr_osx_handler, ++ NULL ++}; ++ ++ssize_t apfs_listxattr(struct dentry *dentry, char *buffer, size_t size) ++{ ++ struct inode *inode = d_inode(dentry); ++ struct super_block *sb = inode->i_sb; ++ struct apfs_sb_info *sbi = APFS_SB(sb); ++ struct apfs_nxsb_info *nxi = APFS_NXI(sb); ++ struct apfs_query *query; ++ u64 cnid = apfs_ino(inode); ++ size_t free = size; ++ ssize_t ret; ++ ++ down_read(&nxi->nx_big_sem); ++ ++ query = apfs_alloc_query(sbi->s_cat_root, NULL /* parent */); ++ if (!query) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ /* We want all the xattrs for the cnid, regardless of the name */ ++ apfs_init_xattr_key(cnid, NULL /* name */, &query->key); ++ query->flags = APFS_QUERY_CAT | APFS_QUERY_MULTIPLE | APFS_QUERY_EXACT; ++ ++ while (1) { ++ struct apfs_xattr xattr; ++ ++ ret = apfs_btree_query(sb, &query); ++ if (ret == -ENODATA) { /* Got all the xattrs */ ++ ret = size - free; ++ break; ++ } ++ if (ret) { ++ apfs_err(sb, "query failed for id 0x%llx", cnid); ++ break; ++ } ++ ++ ret = apfs_xattr_from_query(query, &xattr); ++ if (ret) { ++ apfs_err(sb, "bad xattr key in inode %llx", cnid); ++ break; ++ } ++ ++ if (buffer) { ++ /* Prepend the fake 'osx' prefix before listing */ ++ if (xattr.name_len + XATTR_MAC_OSX_PREFIX_LEN + 1 > ++ free) { ++ ret = -ERANGE; ++ break; ++ } ++ memcpy(buffer, XATTR_MAC_OSX_PREFIX, ++ XATTR_MAC_OSX_PREFIX_LEN); ++ buffer += XATTR_MAC_OSX_PREFIX_LEN; ++ memcpy(buffer, xattr.name, xattr.name_len + 1); ++ buffer += xattr.name_len + 1; ++ } ++ free -= xattr.name_len + XATTR_MAC_OSX_PREFIX_LEN + 1; ++ } ++ ++fail: ++ apfs_free_query(query); ++ up_read(&nxi->nx_big_sem); ++ return ret; ++} +diff --git a/fs/apfs/xfield.c b/fs/apfs/xfield.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/xfield.c +@@ -0,0 +1,171 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2019 Ernesto A. Fernández ++ */ ++ ++#include ++#include ++#include "apfs.h" ++ ++/** ++ * apfs_find_xfield - Find an extended field value in an inode or dentry record ++ * @xfields: pointer to the on-disk xfield collection for the record ++ * @len: length of the collection ++ * @xtype: type of the xfield to retrieve ++ * @xval: on return, a pointer to the wanted on-disk xfield value ++ * ++ * Returns the length of @xval on success, or 0 if no matching xfield was found; ++ * the caller must check that the expected structures fit before casting @xval. ++ */ ++int apfs_find_xfield(u8 *xfields, int len, u8 xtype, char **xval) ++{ ++ struct apfs_xf_blob *blob; ++ struct apfs_x_field *xfield; ++ int count; ++ int rest = len; ++ int i; ++ ++ if (!len) ++ return 0; /* No xfield data */ ++ ++ rest -= sizeof(*blob); ++ if (rest < 0) ++ return 0; /* Corruption */ ++ blob = (struct apfs_xf_blob *)xfields; ++ ++ count = le16_to_cpu(blob->xf_num_exts); ++ rest -= count * sizeof(*xfield); ++ if (rest < 0) ++ return 0; /* Corruption */ ++ xfield = (struct apfs_x_field *)blob->xf_data; ++ ++ for (i = 0; i < count; ++i) { ++ int xlen; ++ ++ /* Attribute length is padded to a multiple of 8 */ ++ xlen = round_up(le16_to_cpu(xfield[i].x_size), 8); ++ if (xlen > rest) ++ return 0; /* Corruption */ ++ ++ if (xfield[i].x_type == xtype) { ++ *xval = (char *)xfields + len - rest; ++ return xlen; ++ } ++ rest -= xlen; ++ } ++ return 0; ++} ++ ++/** ++ * apfs_init_xfields - Set an empty collection of xfields in a buffer ++ * @buffer: buffer to hold the xfields ++ * @buflen: length of the buffer; should be enough to fit an xfield blob ++ * ++ * Returns 0 on success, or -1 if the buffer isn't long enough. ++ */ ++int apfs_init_xfields(u8 *buffer, int buflen) ++{ ++ struct apfs_xf_blob *blob; ++ ++ if (buflen < sizeof(*blob)) ++ return -1; ++ blob = (struct apfs_xf_blob *)buffer; ++ ++ blob->xf_num_exts = 0; ++ blob->xf_used_data = 0; ++ return 0; ++} ++ ++/** ++ * apfs_insert_xfield - Add a new xfield to an in-memory collection ++ * @buffer: buffer holding the collection of xfields ++ * @buflen: length of the buffer; should be enough to fit the new xfield ++ * @xkey: metadata for the new xfield ++ * @xval: value for the new xfield ++ * ++ * Returns the new length of the collection, or 0 if it the allocation would ++ * overflow @buffer. ++ */ ++int apfs_insert_xfield(u8 *buffer, int buflen, const struct apfs_x_field *xkey, ++ const void *xval) ++{ ++ struct apfs_xf_blob *blob; ++ struct apfs_x_field *curr_xkey; ++ void *curr_xval; ++ int count; ++ int rest = buflen; ++ u16 used_data; ++ int xlen, padded_xlen; ++ int meta_len, total_len; ++ int i; ++ ++ xlen = le16_to_cpu(xkey->x_size); ++ padded_xlen = round_up(xlen, 8); ++ ++ if (!buflen) ++ return 0; ++ ++ rest -= sizeof(*blob); ++ if (rest < 0) ++ return 0; ++ blob = (struct apfs_xf_blob *)buffer; ++ used_data = le16_to_cpu(blob->xf_used_data); ++ ++ count = le16_to_cpu(blob->xf_num_exts); ++ rest -= count * sizeof(*curr_xkey); ++ if (rest < 0) ++ return 0; ++ meta_len = buflen - rest; ++ curr_xkey = (struct apfs_x_field *)blob->xf_data; ++ ++ for (i = 0; i < count; ++i, ++curr_xkey) { ++ int curr_xlen; ++ ++ /* Attribute length is padded to a multiple of 8 */ ++ curr_xlen = round_up(le16_to_cpu(curr_xkey->x_size), 8); ++ if (curr_xlen > rest) ++ return 0; ++ if (curr_xkey->x_type != xkey->x_type) { ++ rest -= curr_xlen; ++ continue; ++ } ++ ++ /* The xfield already exists, so just resize it and set it */ ++ memcpy(curr_xkey, xkey, sizeof(*curr_xkey)); ++ if (padded_xlen > rest) ++ return 0; ++ curr_xval = buffer + buflen - rest; ++ rest -= max(padded_xlen, curr_xlen); ++ memmove(curr_xval + padded_xlen, curr_xval + curr_xlen, rest); ++ memcpy(curr_xval, xval, xlen); ++ memset(curr_xval + xlen, 0, padded_xlen - xlen); ++ used_data += padded_xlen - curr_xlen; ++ ++ goto done; ++ } ++ ++ /* Create a metadata entry for the new xfield */ ++ rest -= sizeof(*curr_xkey); ++ if (rest < 0) ++ return 0; ++ meta_len += sizeof(*curr_xkey); ++ memmove(curr_xkey + 1, curr_xkey, buflen - meta_len); ++ memcpy(curr_xkey, xkey, sizeof(*curr_xkey)); ++ ++count; ++ ++ /* Now set the xfield value */ ++ if (padded_xlen > rest) ++ return 0; ++ curr_xval = buffer + buflen - rest; ++ memcpy(curr_xval, xval, xlen); ++ memset(curr_xval + xlen, 0, padded_xlen - xlen); ++ used_data += padded_xlen; ++ ++done: ++ total_len = used_data + meta_len; ++ if (total_len > buflen) ++ return 0; ++ blob->xf_num_exts = cpu_to_le16(count); ++ blob->xf_used_data = cpu_to_le16(used_data); ++ return total_len; ++} +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.12/8002-Necessary-modifications-to-build-APFS-with-the-kerne.patch b/patch/kernel/archive/uefi-x86-6.12/8002-Necessary-modifications-to-build-APFS-with-the-kerne.patch new file mode 100644 index 000000000..2a285fa62 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.12/8002-Necessary-modifications-to-build-APFS-with-the-kerne.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg <85610623+AdityaGarg8@users.noreply.github.com> +Date: Sun, 10 Nov 2024 15:31:18 +0530 +Subject: Necessary modifications to build APFS with the kernel + +--- + fs/Kconfig | 1 + + fs/Makefile | 1 + + fs/apfs/Kconfig | 13 ++++++ + fs/apfs/Makefile | 22 +--------- + 4 files changed, 17 insertions(+), 20 deletions(-) + +diff --git a/fs/Kconfig b/fs/Kconfig +index 111111111111..222222222222 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -321,6 +321,7 @@ source "fs/affs/Kconfig" + source "fs/ecryptfs/Kconfig" + source "fs/hfs/Kconfig" + source "fs/hfsplus/Kconfig" ++source "fs/apfs/Kconfig" + source "fs/befs/Kconfig" + source "fs/bfs/Kconfig" + source "fs/efs/Kconfig" +diff --git a/fs/Makefile b/fs/Makefile +index 111111111111..222222222222 100644 +--- a/fs/Makefile ++++ b/fs/Makefile +@@ -120,6 +120,7 @@ obj-$(CONFIG_DEBUG_FS) += debugfs/ + obj-$(CONFIG_TRACING) += tracefs/ + obj-$(CONFIG_OCFS2_FS) += ocfs2/ + obj-$(CONFIG_BTRFS_FS) += btrfs/ ++obj-$(CONFIG_APFS_FS) += apfs/ + obj-$(CONFIG_GFS2_FS) += gfs2/ + obj-$(CONFIG_F2FS_FS) += f2fs/ + obj-$(CONFIG_BCACHEFS_FS) += bcachefs/ +diff --git a/fs/apfs/Kconfig b/fs/apfs/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/fs/apfs/Kconfig +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++config APFS_FS ++ tristate "Apple file system support" ++ select LIBCRC32C ++ select ZLIB_INFLATE ++ select NLS ++ select BUFFER_HEAD ++ select FS_IOMAP ++ select LEGACY_DIRECT_IO ++ help ++ If you say Y here, you will be able to mount APFS partitions ++ with read-only access. Write access is experimental and will ++ corrupt your container. +diff --git a/fs/apfs/Makefile b/fs/apfs/Makefile +index 111111111111..222222222222 100644 +--- a/fs/apfs/Makefile ++++ b/fs/apfs/Makefile +@@ -1,28 +1,10 @@ + # SPDX-License-Identifier: GPL-2.0-only + # +-# Makefile for the out-of-tree Linux APFS module. ++# Makefile for the Linux APFS module. + # + +-KERNELRELEASE ?= $(shell uname -r) +-KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build +-PWD := $(shell pwd) +- +-obj-m = apfs.o ++obj-$(CONFIG_APFS_FS) = apfs.o + apfs-y := btree.o compress.o dir.o extents.o file.o inode.o key.o libzbitmap.o \ + lzfse/lzfse_decode.o lzfse/lzfse_decode_base.o lzfse/lzfse_fse.o \ + lzfse/lzvn_decode_base.o message.o namei.o node.o object.o snapshot.o \ + spaceman.o super.o symlink.o transaction.o unicode.o xattr.o xfield.o +- +-# If you want mounts to be writable by default, run the build as: +-# make CONFIG=-DCONFIG_APFS_RW_ALWAYS +-# This is risky and not generally recommended. +-ccflags-y += $(CONFIG) +- +-default: +- ./genver.sh +- make -C $(KERNEL_DIR) M=$(PWD) +-install: +- make -C $(KERNEL_DIR) M=$(PWD) modules_install +-clean: +- rm -f version.h +- make -C $(KERNEL_DIR) M=$(PWD) clean +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/1001-Add-apple-bce-driver.patch b/patch/kernel/archive/uefi-x86-6.18/1001-Add-apple-bce-driver.patch new file mode 100644 index 000000000..89df97945 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/1001-Add-apple-bce-driver.patch @@ -0,0 +1,5864 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Sat, 25 Oct 2025 08:13:34 +0000 +Subject: Add apple-bce driver + +--- + drivers/staging/apple-bce/Makefile | 28 + + drivers/staging/apple-bce/apple_bce.c | 445 ++++++ + drivers/staging/apple-bce/apple_bce.h | 41 + + drivers/staging/apple-bce/audio/audio.c | 711 +++++++++ + drivers/staging/apple-bce/audio/audio.h | 125 ++ + drivers/staging/apple-bce/audio/description.h | 42 + + drivers/staging/apple-bce/audio/pcm.c | 308 ++++ + drivers/staging/apple-bce/audio/pcm.h | 16 + + drivers/staging/apple-bce/audio/protocol.c | 347 +++++ + drivers/staging/apple-bce/audio/protocol.h | 147 ++ + drivers/staging/apple-bce/audio/protocol_bce.c | 226 +++ + drivers/staging/apple-bce/audio/protocol_bce.h | 72 + + drivers/staging/apple-bce/mailbox.c | 155 ++ + drivers/staging/apple-bce/mailbox.h | 53 + + drivers/staging/apple-bce/queue.c | 415 +++++ + drivers/staging/apple-bce/queue.h | 177 +++ + drivers/staging/apple-bce/queue_dma.c | 220 +++ + drivers/staging/apple-bce/queue_dma.h | 50 + + drivers/staging/apple-bce/vhci/command.h | 204 +++ + drivers/staging/apple-bce/vhci/queue.c | 268 ++++ + drivers/staging/apple-bce/vhci/queue.h | 76 + + drivers/staging/apple-bce/vhci/transfer.c | 661 ++++++++ + drivers/staging/apple-bce/vhci/transfer.h | 73 + + drivers/staging/apple-bce/vhci/vhci.c | 763 ++++++++++ + drivers/staging/apple-bce/vhci/vhci.h | 52 + + 25 files changed, 5675 insertions(+) + +diff --git a/drivers/staging/apple-bce/Makefile b/drivers/staging/apple-bce/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/Makefile +@@ -0,0 +1,28 @@ ++modname := apple-bce ++obj-m += $(modname).o ++ ++apple-bce-objs := apple_bce.o mailbox.o queue.o queue_dma.o vhci/vhci.o vhci/queue.o vhci/transfer.o audio/audio.o audio/protocol.o audio/protocol_bce.o audio/pcm.o ++ ++MY_CFLAGS += -DWITHOUT_NVME_PATCH ++#MY_CFLAGS += -g -DDEBUG ++ccflags-y += ${MY_CFLAGS} ++CC += ${MY_CFLAGS} ++ ++KVERSION := $(KERNELRELEASE) ++ifeq ($(origin KERNELRELEASE), undefined) ++KVERSION := $(shell uname -r) ++endif ++ ++KDIR := /lib/modules/$(KVERSION)/build ++PWD := $(shell pwd) ++ ++.PHONY: all ++ ++all: ++ $(MAKE) -C $(KDIR) M=$(PWD) modules ++ ++clean: ++ $(MAKE) -C $(KDIR) M=$(PWD) clean ++ ++install: ++ $(MAKE) -C $(KDIR) M=$(PWD) modules_install +diff --git a/drivers/staging/apple-bce/apple_bce.c b/drivers/staging/apple-bce/apple_bce.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/apple_bce.c +@@ -0,0 +1,445 @@ ++#include "apple_bce.h" ++#include ++#include ++#include "audio/audio.h" ++#include ++ ++static dev_t bce_chrdev; ++static struct class *bce_class; ++ ++struct apple_bce_device *global_bce; ++ ++static int bce_create_command_queues(struct apple_bce_device *bce); ++static void bce_free_command_queues(struct apple_bce_device *bce); ++static irqreturn_t bce_handle_mb_irq(int irq, void *dev); ++static irqreturn_t bce_handle_dma_irq(int irq, void *dev); ++static int bce_fw_version_handshake(struct apple_bce_device *bce); ++static int bce_register_command_queue(struct apple_bce_device *bce, struct bce_queue_memcfg *cfg, int is_sq); ++ ++static int apple_bce_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct apple_bce_device *bce = NULL; ++ int status = 0; ++ int nvec; ++ ++ pr_info("apple-bce: capturing our device\n"); ++ ++ if (pci_enable_device(dev)) ++ return -ENODEV; ++ if (pci_request_regions(dev, "apple-bce")) { ++ status = -ENODEV; ++ goto fail; ++ } ++ pci_set_master(dev); ++ nvec = pci_alloc_irq_vectors(dev, 1, 8, PCI_IRQ_MSI); ++ if (nvec < 5) { ++ status = -EINVAL; ++ goto fail; ++ } ++ ++ bce = kzalloc(sizeof(struct apple_bce_device), GFP_KERNEL); ++ if (!bce) { ++ status = -ENOMEM; ++ goto fail; ++ } ++ ++ bce->pci = dev; ++ pci_set_drvdata(dev, bce); ++ ++ bce->devt = bce_chrdev; ++ bce->dev = device_create(bce_class, &dev->dev, bce->devt, NULL, "apple-bce"); ++ if (IS_ERR_OR_NULL(bce->dev)) { ++ status = PTR_ERR(bce_class); ++ goto fail; ++ } ++ ++ bce->reg_mem_mb = pci_iomap(dev, 4, 0); ++ bce->reg_mem_dma = pci_iomap(dev, 2, 0); ++ ++ if (IS_ERR_OR_NULL(bce->reg_mem_mb) || IS_ERR_OR_NULL(bce->reg_mem_dma)) { ++ dev_warn(&dev->dev, "apple-bce: Failed to pci_iomap required regions\n"); ++ goto fail; ++ } ++ ++ bce_mailbox_init(&bce->mbox, bce->reg_mem_mb); ++ bce_timestamp_init(&bce->timestamp, bce->reg_mem_mb); ++ ++ spin_lock_init(&bce->queues_lock); ++ ida_init(&bce->queue_ida); ++ ++ if ((status = pci_request_irq(dev, 0, bce_handle_mb_irq, NULL, dev, "bce_mbox"))) ++ goto fail; ++ if ((status = pci_request_irq(dev, 4, NULL, bce_handle_dma_irq, dev, "bce_dma"))) ++ goto fail_interrupt_0; ++ ++ if ((status = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(37)))) { ++ dev_warn(&dev->dev, "dma: Setting mask failed\n"); ++ goto fail_interrupt; ++ } ++ ++ /* Gets the function 0's interface. This is needed because Apple only accepts DMA on our function if function 0 ++ is a bus master, so we need to work around this. */ ++ bce->pci0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); ++#ifndef WITHOUT_NVME_PATCH ++ if ((status = pci_enable_device_mem(bce->pci0))) { ++ dev_warn(&dev->dev, "apple-bce: failed to enable function 0\n"); ++ goto fail_dev0; ++ } ++#endif ++ pci_set_master(bce->pci0); ++ ++ bce_timestamp_start(&bce->timestamp, true); ++ ++ if ((status = bce_fw_version_handshake(bce))) ++ goto fail_ts; ++ pr_info("apple-bce: handshake done\n"); ++ ++ if ((status = bce_create_command_queues(bce))) { ++ pr_info("apple-bce: Creating command queues failed\n"); ++ goto fail_ts; ++ } ++ ++ global_bce = bce; ++ ++ bce_vhci_create(bce, &bce->vhci); ++ ++ return 0; ++ ++fail_ts: ++ bce_timestamp_stop(&bce->timestamp); ++#ifndef WITHOUT_NVME_PATCH ++ pci_disable_device(bce->pci0); ++fail_dev0: ++#endif ++ pci_dev_put(bce->pci0); ++fail_interrupt: ++ pci_free_irq(dev, 4, dev); ++fail_interrupt_0: ++ pci_free_irq(dev, 0, dev); ++fail: ++ if (bce && bce->dev) { ++ device_destroy(bce_class, bce->devt); ++ ++ if (!IS_ERR_OR_NULL(bce->reg_mem_mb)) ++ pci_iounmap(dev, bce->reg_mem_mb); ++ if (!IS_ERR_OR_NULL(bce->reg_mem_dma)) ++ pci_iounmap(dev, bce->reg_mem_dma); ++ ++ kfree(bce); ++ } ++ ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++static int bce_create_command_queues(struct apple_bce_device *bce) ++{ ++ int status; ++ struct bce_queue_memcfg *cfg; ++ ++ bce->cmd_cq = bce_alloc_cq(bce, 0, 0x20); ++ bce->cmd_cmdq = bce_alloc_cmdq(bce, 1, 0x20); ++ if (bce->cmd_cq == NULL || bce->cmd_cmdq == NULL) { ++ status = -ENOMEM; ++ goto err; ++ } ++ bce->queues[0] = (struct bce_queue *) bce->cmd_cq; ++ bce->queues[1] = (struct bce_queue *) bce->cmd_cmdq->sq; ++ ++ cfg = kzalloc(sizeof(struct bce_queue_memcfg), GFP_KERNEL); ++ if (!cfg) { ++ status = -ENOMEM; ++ goto err; ++ } ++ bce_get_cq_memcfg(bce->cmd_cq, cfg); ++ if ((status = bce_register_command_queue(bce, cfg, false))) ++ goto err; ++ bce_get_sq_memcfg(bce->cmd_cmdq->sq, bce->cmd_cq, cfg); ++ if ((status = bce_register_command_queue(bce, cfg, true))) ++ goto err; ++ kfree(cfg); ++ ++ return 0; ++ ++err: ++ if (bce->cmd_cq) ++ bce_free_cq(bce, bce->cmd_cq); ++ if (bce->cmd_cmdq) ++ bce_free_cmdq(bce, bce->cmd_cmdq); ++ return status; ++} ++ ++static void bce_free_command_queues(struct apple_bce_device *bce) ++{ ++ bce_free_cq(bce, bce->cmd_cq); ++ bce_free_cmdq(bce, bce->cmd_cmdq); ++ bce->cmd_cq = NULL; ++ bce->queues[0] = NULL; ++} ++ ++static irqreturn_t bce_handle_mb_irq(int irq, void *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ bce_mailbox_handle_interrupt(&bce->mbox); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t bce_handle_dma_irq(int irq, void *dev) ++{ ++ int i; ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ spin_lock(&bce->queues_lock); ++ for (i = 0; i < BCE_MAX_QUEUE_COUNT; i++) ++ if (bce->queues[i] && bce->queues[i]->type == BCE_QUEUE_CQ) ++ bce_handle_cq_completions(bce, (struct bce_queue_cq *) bce->queues[i]); ++ spin_unlock(&bce->queues_lock); ++ return IRQ_HANDLED; ++} ++ ++static int bce_fw_version_handshake(struct apple_bce_device *bce) ++{ ++ u64 result; ++ int status; ++ ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_SET_FW_PROTOCOL_VERSION, BC_PROTOCOL_VERSION), ++ &result))) ++ return status; ++ if (BCE_MB_TYPE(result) != BCE_MB_SET_FW_PROTOCOL_VERSION || ++ BCE_MB_VALUE(result) != BC_PROTOCOL_VERSION) { ++ pr_err("apple-bce: FW version handshake failed %x:%llx\n", BCE_MB_TYPE(result), BCE_MB_VALUE(result)); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int bce_register_command_queue(struct apple_bce_device *bce, struct bce_queue_memcfg *cfg, int is_sq) ++{ ++ int status; ++ int cmd_type; ++ u64 result; ++ // OS X uses an bidirectional direction, but that's not really needed ++ dma_addr_t a = dma_map_single(&bce->pci->dev, cfg, sizeof(struct bce_queue_memcfg), DMA_TO_DEVICE); ++ if (dma_mapping_error(&bce->pci->dev, a)) ++ return -ENOMEM; ++ cmd_type = is_sq ? BCE_MB_REGISTER_COMMAND_SQ : BCE_MB_REGISTER_COMMAND_CQ; ++ status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(cmd_type, a), &result); ++ dma_unmap_single(&bce->pci->dev, a, sizeof(struct bce_queue_memcfg), DMA_TO_DEVICE); ++ if (status) ++ return status; ++ if (BCE_MB_TYPE(result) != BCE_MB_REGISTER_COMMAND_QUEUE_REPLY) ++ return -EINVAL; ++ return 0; ++} ++ ++static void apple_bce_remove(struct pci_dev *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(dev); ++ bce->is_being_removed = true; ++ ++ bce_vhci_destroy(&bce->vhci); ++ ++ bce_timestamp_stop(&bce->timestamp); ++#ifndef WITHOUT_NVME_PATCH ++ pci_disable_device(bce->pci0); ++#endif ++ pci_dev_put(bce->pci0); ++ pci_free_irq(dev, 0, dev); ++ pci_free_irq(dev, 4, dev); ++ bce_free_command_queues(bce); ++ pci_iounmap(dev, bce->reg_mem_mb); ++ pci_iounmap(dev, bce->reg_mem_dma); ++ device_destroy(bce_class, bce->devt); ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ kfree(bce); ++} ++ ++static int bce_save_state_and_sleep(struct apple_bce_device *bce) ++{ ++ int attempt, status = 0; ++ u64 resp; ++ dma_addr_t dma_addr; ++ void *dma_ptr = NULL; ++ size_t size = max(PAGE_SIZE, 4096UL); ++ ++ for (attempt = 0; attempt < 5; ++attempt) { ++ pr_debug("apple-bce: suspend: attempt %i, buffer size %li\n", attempt, size); ++ dma_ptr = dma_alloc_coherent(&bce->pci->dev, size, &dma_addr, GFP_KERNEL); ++ if (!dma_ptr) { ++ pr_err("apple-bce: suspend failed (data alloc failed)\n"); ++ break; ++ } ++ BUG_ON((dma_addr % 4096) != 0); ++ status = bce_mailbox_send(&bce->mbox, ++ BCE_MB_MSG(BCE_MB_SAVE_STATE_AND_SLEEP, (dma_addr & ~(4096LLU - 1)) | (size / 4096)), &resp); ++ if (status) { ++ pr_err("apple-bce: suspend failed (mailbox send)\n"); ++ break; ++ } ++ if (BCE_MB_TYPE(resp) == BCE_MB_SAVE_RESTORE_STATE_COMPLETE) { ++ bce->saved_data_dma_addr = dma_addr; ++ bce->saved_data_dma_ptr = dma_ptr; ++ bce->saved_data_dma_size = size; ++ return 0; ++ } else if (BCE_MB_TYPE(resp) == BCE_MB_SAVE_STATE_AND_SLEEP_FAILURE) { ++ dma_free_coherent(&bce->pci->dev, size, dma_ptr, dma_addr); ++ /* The 0x10ff magic value was extracted from Apple's driver */ ++ size = (BCE_MB_VALUE(resp) + 0x10ff) & ~(4096LLU - 1); ++ pr_debug("apple-bce: suspend: device requested a larger buffer (%li)\n", size); ++ continue; ++ } else { ++ pr_err("apple-bce: suspend failed (invalid device response)\n"); ++ status = -EINVAL; ++ break; ++ } ++ } ++ if (dma_ptr) ++ dma_free_coherent(&bce->pci->dev, size, dma_ptr, dma_addr); ++ if (!status) ++ return bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_SLEEP_NO_STATE, 0), &resp); ++ return status; ++} ++ ++static int bce_restore_state_and_wake(struct apple_bce_device *bce) ++{ ++ int status; ++ u64 resp; ++ if (!bce->saved_data_dma_ptr) { ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_RESTORE_NO_STATE, 0), &resp))) { ++ pr_err("apple-bce: resume with no state failed (mailbox send)\n"); ++ return status; ++ } ++ if (BCE_MB_TYPE(resp) != BCE_MB_RESTORE_NO_STATE) { ++ pr_err("apple-bce: resume with no state failed (invalid device response)\n"); ++ return -EINVAL; ++ } ++ return 0; ++ } ++ ++ if ((status = bce_mailbox_send(&bce->mbox, BCE_MB_MSG(BCE_MB_RESTORE_STATE_AND_WAKE, ++ (bce->saved_data_dma_addr & ~(4096LLU - 1)) | (bce->saved_data_dma_size / 4096)), &resp))) { ++ pr_err("apple-bce: resume with state failed (mailbox send)\n"); ++ goto finish_with_state; ++ } ++ if (BCE_MB_TYPE(resp) != BCE_MB_SAVE_RESTORE_STATE_COMPLETE) { ++ pr_err("apple-bce: resume with state failed (invalid device response)\n"); ++ status = -EINVAL; ++ goto finish_with_state; ++ } ++ ++finish_with_state: ++ dma_free_coherent(&bce->pci->dev, bce->saved_data_dma_size, bce->saved_data_dma_ptr, bce->saved_data_dma_addr); ++ bce->saved_data_dma_ptr = NULL; ++ return status; ++} ++ ++static int apple_bce_suspend(struct device *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(to_pci_dev(dev)); ++ int status; ++ ++ bce_timestamp_stop(&bce->timestamp); ++ ++ if ((status = bce_save_state_and_sleep(bce))) ++ return status; ++ ++ return 0; ++} ++ ++static int apple_bce_resume(struct device *dev) ++{ ++ struct apple_bce_device *bce = pci_get_drvdata(to_pci_dev(dev)); ++ int status; ++ ++ pci_set_master(bce->pci); ++ pci_set_master(bce->pci0); ++ ++ if ((status = bce_restore_state_and_wake(bce))) ++ return status; ++ ++ bce_timestamp_start(&bce->timestamp, false); ++ ++ return 0; ++} ++ ++static struct pci_device_id apple_bce_ids[ ] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x1801) }, ++ { 0, }, ++}; ++ ++MODULE_DEVICE_TABLE(pci, apple_bce_ids); ++ ++struct dev_pm_ops apple_bce_pci_driver_pm = { ++ .suspend = apple_bce_suspend, ++ .resume = apple_bce_resume ++}; ++struct pci_driver apple_bce_pci_driver = { ++ .name = "apple-bce", ++ .id_table = apple_bce_ids, ++ .probe = apple_bce_probe, ++ .remove = apple_bce_remove, ++ .driver = { ++ .pm = &apple_bce_pci_driver_pm ++ } ++}; ++ ++ ++static int __init apple_bce_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&bce_chrdev, 0, 1, "apple-bce"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ bce_class = class_create(THIS_MODULE, "apple-bce"); ++#else ++ bce_class = class_create("apple-bce"); ++#endif ++ if (IS_ERR(bce_class)) { ++ result = PTR_ERR(bce_class); ++ goto fail_class; ++ } ++ if ((result = bce_vhci_module_init())) { ++ pr_err("apple-bce: bce-vhci init failed"); ++ goto fail_class; ++ } ++ ++ result = pci_register_driver(&apple_bce_pci_driver); ++ if (result) ++ goto fail_drv; ++ ++ aaudio_module_init(); ++ ++ return 0; ++ ++fail_drv: ++ pci_unregister_driver(&apple_bce_pci_driver); ++fail_class: ++ class_destroy(bce_class); ++fail_chrdev: ++ unregister_chrdev_region(bce_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++static void __exit apple_bce_module_exit(void) ++{ ++ pci_unregister_driver(&apple_bce_pci_driver); ++ ++ aaudio_module_exit(); ++ bce_vhci_module_exit(); ++ class_destroy(bce_class); ++ unregister_chrdev_region(bce_chrdev, 1); ++} ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("MrARM"); ++MODULE_DESCRIPTION("Apple BCE Driver"); ++MODULE_VERSION("0.01"); ++module_init(apple_bce_module_init); ++module_exit(apple_bce_module_exit); +diff --git a/drivers/staging/apple-bce/apple_bce.h b/drivers/staging/apple-bce/apple_bce.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/apple_bce.h +@@ -0,0 +1,41 @@ ++#ifndef APPLE_BCE_H ++#define APPLE_BCE_H ++ ++#include ++#include ++#include "mailbox.h" ++#include "queue.h" ++#include "vhci/vhci.h" ++ ++#define BC_PROTOCOL_VERSION 0x20001 ++#define BCE_MAX_QUEUE_COUNT 0x100 ++ ++#define BCE_QUEUE_USER_MIN 2 ++#define BCE_QUEUE_USER_MAX (BCE_MAX_QUEUE_COUNT - 1) ++ ++struct apple_bce_device { ++ struct pci_dev *pci, *pci0; ++ dev_t devt; ++ struct device *dev; ++ void __iomem *reg_mem_mb; ++ void __iomem *reg_mem_dma; ++ struct bce_mailbox mbox; ++ struct bce_timestamp timestamp; ++ struct bce_queue *queues[BCE_MAX_QUEUE_COUNT]; ++ struct spinlock queues_lock; ++ struct ida queue_ida; ++ struct bce_queue_cq *cmd_cq; ++ struct bce_queue_cmdq *cmd_cmdq; ++ struct bce_queue_sq *int_sq_list[BCE_MAX_QUEUE_COUNT]; ++ bool is_being_removed; ++ ++ dma_addr_t saved_data_dma_addr; ++ void *saved_data_dma_ptr; ++ size_t saved_data_dma_size; ++ ++ struct bce_vhci vhci; ++}; ++ ++extern struct apple_bce_device *global_bce; ++ ++#endif //APPLE_BCE_H +diff --git a/drivers/staging/apple-bce/audio/audio.c b/drivers/staging/apple-bce/audio/audio.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/audio.c +@@ -0,0 +1,711 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "audio.h" ++#include "pcm.h" ++#include ++ ++static int aaudio_alsa_index = SNDRV_DEFAULT_IDX1; ++static char *aaudio_alsa_id = SNDRV_DEFAULT_STR1; ++ ++static dev_t aaudio_chrdev; ++static struct class *aaudio_class; ++ ++static int aaudio_init_cmd(struct aaudio_device *a); ++static int aaudio_init_bs(struct aaudio_device *a); ++static void aaudio_init_dev(struct aaudio_device *a, aaudio_device_id_t dev_id); ++static void aaudio_free_dev(struct aaudio_subdevice *sdev); ++ ++static int aaudio_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct aaudio_device *aaudio = NULL; ++ struct aaudio_subdevice *sdev = NULL; ++ int status = 0; ++ u32 cfg; ++ ++ pr_info("aaudio: capturing our device\n"); ++ ++ if (pci_enable_device(dev)) ++ return -ENODEV; ++ if (pci_request_regions(dev, "aaudio")) { ++ status = -ENODEV; ++ goto fail; ++ } ++ pci_set_master(dev); ++ ++ aaudio = kzalloc(sizeof(struct aaudio_device), GFP_KERNEL); ++ if (!aaudio) { ++ status = -ENOMEM; ++ goto fail; ++ } ++ ++ aaudio->bce = global_bce; ++ if (!aaudio->bce) { ++ dev_warn(&dev->dev, "aaudio: No BCE available\n"); ++ status = -EINVAL; ++ goto fail; ++ } ++ ++ aaudio->pci = dev; ++ pci_set_drvdata(dev, aaudio); ++ ++ aaudio->devt = aaudio_chrdev; ++ aaudio->dev = device_create(aaudio_class, &dev->dev, aaudio->devt, NULL, "aaudio"); ++ if (IS_ERR_OR_NULL(aaudio->dev)) { ++ status = PTR_ERR(aaudio_class); ++ goto fail; ++ } ++ device_link_add(aaudio->dev, aaudio->bce->dev, DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER); ++ ++ init_completion(&aaudio->remote_alive); ++ INIT_LIST_HEAD(&aaudio->subdevice_list); ++ ++ /* Init: set an unknown flag in the bitset */ ++ if (pci_read_config_dword(dev, 4, &cfg)) ++ dev_warn(&dev->dev, "aaudio: pci_read_config_dword fail\n"); ++ if (pci_write_config_dword(dev, 4, cfg | 6u)) ++ dev_warn(&dev->dev, "aaudio: pci_write_config_dword fail\n"); ++ ++ dev_info(aaudio->dev, "aaudio: bs len = %llx\n", pci_resource_len(dev, 0)); ++ aaudio->reg_mem_bs_dma = pci_resource_start(dev, 0); ++ aaudio->reg_mem_bs = pci_iomap(dev, 0, 0); ++ aaudio->reg_mem_cfg = pci_iomap(dev, 4, 0); ++ ++ aaudio->reg_mem_gpr = (u32 __iomem *) ((u8 __iomem *) aaudio->reg_mem_cfg + 0xC000); ++ ++ if (IS_ERR_OR_NULL(aaudio->reg_mem_bs) || IS_ERR_OR_NULL(aaudio->reg_mem_cfg)) { ++ dev_warn(&dev->dev, "aaudio: Failed to pci_iomap required regions\n"); ++ goto fail; ++ } ++ ++ if (aaudio_bce_init(aaudio)) { ++ dev_warn(&dev->dev, "aaudio: Failed to init BCE command transport\n"); ++ goto fail; ++ } ++ ++ if (snd_card_new(aaudio->dev, aaudio_alsa_index, aaudio_alsa_id, THIS_MODULE, 0, &aaudio->card)) { ++ dev_err(&dev->dev, "aaudio: Failed to create ALSA card\n"); ++ goto fail; ++ } ++ ++ strcpy(aaudio->card->shortname, "Apple T2 Audio"); ++ strcpy(aaudio->card->longname, "Apple T2 Audio"); ++ strcpy(aaudio->card->mixername, "Apple T2 Audio"); ++ /* Dynamic alsa ids start at 100 */ ++ aaudio->next_alsa_id = 100; ++ ++ if (aaudio_init_cmd(aaudio)) { ++ dev_err(&dev->dev, "aaudio: Failed to initialize over BCE\n"); ++ goto fail_snd; ++ } ++ ++ if (aaudio_init_bs(aaudio)) { ++ dev_err(&dev->dev, "aaudio: Failed to initialize BufferStruct\n"); ++ goto fail_snd; ++ } ++ ++ if ((status = aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_ON))) { ++ dev_err(&dev->dev, "Failed to set remote access\n"); ++ return status; ++ } ++ ++ if (snd_card_register(aaudio->card)) { ++ dev_err(&dev->dev, "aaudio: Failed to register ALSA sound device\n"); ++ goto fail_snd; ++ } ++ ++ list_for_each_entry(sdev, &aaudio->subdevice_list, list) { ++ struct aaudio_buffer_struct_device *dev = &aaudio->bs->devices[sdev->buf_id]; ++ ++ if (sdev->out_stream_cnt == 1 && !strcmp(dev->name, "Speaker")) { ++ struct snd_pcm_hardware *hw = sdev->out_streams[0].alsa_hw_desc; ++ ++ snprintf(aaudio->card->driver, sizeof(aaudio->card->driver) / sizeof(char), "AppleT2x%d", hw->channels_min); ++ } ++ } ++ ++ return 0; ++ ++fail_snd: ++ snd_card_free(aaudio->card); ++fail: ++ if (aaudio && aaudio->dev) ++ device_destroy(aaudio_class, aaudio->devt); ++ kfree(aaudio); ++ ++ if (!IS_ERR_OR_NULL(aaudio->reg_mem_bs)) ++ pci_iounmap(dev, aaudio->reg_mem_bs); ++ if (!IS_ERR_OR_NULL(aaudio->reg_mem_cfg)) ++ pci_iounmap(dev, aaudio->reg_mem_cfg); ++ ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++ ++ ++static void aaudio_remove(struct pci_dev *dev) ++{ ++ struct aaudio_subdevice *sdev; ++ struct aaudio_device *aaudio = pci_get_drvdata(dev); ++ ++ snd_card_free(aaudio->card); ++ while (!list_empty(&aaudio->subdevice_list)) { ++ sdev = list_first_entry(&aaudio->subdevice_list, struct aaudio_subdevice, list); ++ list_del(&sdev->list); ++ aaudio_free_dev(sdev); ++ } ++ pci_iounmap(dev, aaudio->reg_mem_bs); ++ pci_iounmap(dev, aaudio->reg_mem_cfg); ++ device_destroy(aaudio_class, aaudio->devt); ++ pci_free_irq_vectors(dev); ++ pci_release_regions(dev); ++ pci_disable_device(dev); ++ kfree(aaudio); ++} ++ ++static int aaudio_suspend(struct device *dev) ++{ ++ struct aaudio_device *aaudio = pci_get_drvdata(to_pci_dev(dev)); ++ ++ if (aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_OFF)) ++ dev_warn(aaudio->dev, "Failed to reset remote access\n"); ++ ++ pci_disable_device(aaudio->pci); ++ return 0; ++} ++ ++static int aaudio_resume(struct device *dev) ++{ ++ int status; ++ struct aaudio_device *aaudio = pci_get_drvdata(to_pci_dev(dev)); ++ ++ if ((status = pci_enable_device(aaudio->pci))) ++ return status; ++ pci_set_master(aaudio->pci); ++ ++ if ((status = aaudio_cmd_set_remote_access(aaudio, AAUDIO_REMOTE_ACCESS_ON))) { ++ dev_err(aaudio->dev, "Failed to set remote access\n"); ++ return status; ++ } ++ ++ return 0; ++} ++ ++static int aaudio_init_cmd(struct aaudio_device *a) ++{ ++ int status; ++ struct aaudio_send_ctx sctx; ++ struct aaudio_msg buf; ++ u64 dev_cnt, dev_i; ++ aaudio_device_id_t *dev_l; ++ ++ if ((status = aaudio_send(a, &sctx, 500, ++ aaudio_msg_write_alive_notification, 1, 3))) { ++ dev_err(a->dev, "Sending alive notification failed\n"); ++ return status; ++ } ++ ++ if (wait_for_completion_timeout(&a->remote_alive, msecs_to_jiffies(500)) == 0) { ++ dev_err(a->dev, "Timed out waiting for remote\n"); ++ return -ETIMEDOUT; ++ } ++ dev_info(a->dev, "Continuing init\n"); ++ ++ buf = aaudio_reply_alloc(); ++ if ((status = aaudio_cmd_get_device_list(a, &buf, &dev_l, &dev_cnt))) { ++ dev_err(a->dev, "Failed to get device list\n"); ++ aaudio_reply_free(&buf); ++ return status; ++ } ++ for (dev_i = 0; dev_i < dev_cnt; ++dev_i) ++ aaudio_init_dev(a, dev_l[dev_i]); ++ aaudio_reply_free(&buf); ++ ++ return 0; ++} ++ ++static void aaudio_init_stream_info(struct aaudio_subdevice *sdev, struct aaudio_stream *strm); ++static void aaudio_handle_jack_connection_change(struct aaudio_subdevice *sdev); ++ ++static void aaudio_init_dev(struct aaudio_device *a, aaudio_device_id_t dev_id) ++{ ++ struct aaudio_subdevice *sdev; ++ struct aaudio_msg buf = aaudio_reply_alloc(); ++ u64 uid_len, stream_cnt, i; ++ aaudio_object_id_t *stream_list; ++ char *uid; ++ ++ sdev = kzalloc(sizeof(struct aaudio_subdevice), GFP_KERNEL); ++ ++ if (aaudio_cmd_get_property(a, &buf, dev_id, dev_id, AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_UID, 0), ++ NULL, 0, (void **) &uid, &uid_len) || uid_len > AAUDIO_DEVICE_MAX_UID_LEN) { ++ dev_err(a->dev, "Failed to get device uid for device %llx\n", dev_id); ++ goto fail; ++ } ++ dev_info(a->dev, "Remote device %llx %.*s\n", dev_id, (int) uid_len, uid); ++ ++ sdev->a = a; ++ INIT_LIST_HEAD(&sdev->list); ++ sdev->dev_id = dev_id; ++ sdev->buf_id = AAUDIO_BUFFER_ID_NONE; ++ strncpy(sdev->uid, uid, uid_len); ++ sdev->uid[uid_len + 1] = '\0'; ++ ++ if (aaudio_cmd_get_primitive_property(a, dev_id, dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_INPUT, AAUDIO_PROP_LATENCY, 0), NULL, 0, &sdev->in_latency, sizeof(u32))) ++ dev_warn(a->dev, "Failed to query device input latency\n"); ++ if (aaudio_cmd_get_primitive_property(a, dev_id, dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_LATENCY, 0), NULL, 0, &sdev->out_latency, sizeof(u32))) ++ dev_warn(a->dev, "Failed to query device output latency\n"); ++ ++ if (aaudio_cmd_get_input_stream_list(a, &buf, dev_id, &stream_list, &stream_cnt)) { ++ dev_err(a->dev, "Failed to get input stream list for device %llx\n", dev_id); ++ goto fail; ++ } ++ if (stream_cnt > AAUDIO_DEIVCE_MAX_INPUT_STREAMS) { ++ dev_warn(a->dev, "Device %s input stream count %llu is larger than the supported count of %u\n", ++ sdev->uid, stream_cnt, AAUDIO_DEIVCE_MAX_INPUT_STREAMS); ++ stream_cnt = AAUDIO_DEIVCE_MAX_INPUT_STREAMS; ++ } ++ sdev->in_stream_cnt = stream_cnt; ++ for (i = 0; i < stream_cnt; i++) { ++ sdev->in_streams[i].id = stream_list[i]; ++ sdev->in_streams[i].buffer_cnt = 0; ++ aaudio_init_stream_info(sdev, &sdev->in_streams[i]); ++ sdev->in_streams[i].latency += sdev->in_latency; ++ } ++ ++ if (aaudio_cmd_get_output_stream_list(a, &buf, dev_id, &stream_list, &stream_cnt)) { ++ dev_err(a->dev, "Failed to get output stream list for device %llx\n", dev_id); ++ goto fail; ++ } ++ if (stream_cnt > AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS) { ++ dev_warn(a->dev, "Device %s input stream count %llu is larger than the supported count of %u\n", ++ sdev->uid, stream_cnt, AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS); ++ stream_cnt = AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS; ++ } ++ sdev->out_stream_cnt = stream_cnt; ++ for (i = 0; i < stream_cnt; i++) { ++ sdev->out_streams[i].id = stream_list[i]; ++ sdev->out_streams[i].buffer_cnt = 0; ++ aaudio_init_stream_info(sdev, &sdev->out_streams[i]); ++ sdev->out_streams[i].latency += sdev->in_latency; ++ } ++ ++ if (sdev->is_pcm) ++ aaudio_create_pcm(sdev); ++ /* Headphone Jack status */ ++ if (!strcmp(sdev->uid, "Codec Output")) { ++ if (snd_jack_new(a->card, sdev->uid, SND_JACK_HEADPHONE, &sdev->jack, true, false)) ++ dev_warn(a->dev, "Failed to create an attached jack for %s\n", sdev->uid); ++ aaudio_cmd_property_listener(a, sdev->dev_id, sdev->dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_JACK_PLUGGED, 0)); ++ aaudio_handle_jack_connection_change(sdev); ++ } ++ ++ aaudio_reply_free(&buf); ++ ++ list_add_tail(&sdev->list, &a->subdevice_list); ++ return; ++ ++fail: ++ aaudio_reply_free(&buf); ++ kfree(sdev); ++} ++ ++static void aaudio_init_stream_info(struct aaudio_subdevice *sdev, struct aaudio_stream *strm) ++{ ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, strm->id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_PHYS_FORMAT, 0), NULL, 0, ++ &strm->desc, sizeof(strm->desc))) ++ dev_warn(sdev->a->dev, "Failed to query stream descriptor\n"); ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, strm->id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_GLOBAL, AAUDIO_PROP_LATENCY, 0), NULL, 0, &strm->latency, sizeof(u32))) ++ dev_warn(sdev->a->dev, "Failed to query stream latency\n"); ++ if (strm->desc.format_id == AAUDIO_FORMAT_LPCM) ++ sdev->is_pcm = true; ++} ++ ++static void aaudio_free_dev(struct aaudio_subdevice *sdev) ++{ ++ size_t i; ++ for (i = 0; i < sdev->in_stream_cnt; i++) { ++ if (sdev->in_streams[i].alsa_hw_desc) ++ kfree(sdev->in_streams[i].alsa_hw_desc); ++ if (sdev->in_streams[i].buffers) ++ kfree(sdev->in_streams[i].buffers); ++ } ++ for (i = 0; i < sdev->out_stream_cnt; i++) { ++ if (sdev->out_streams[i].alsa_hw_desc) ++ kfree(sdev->out_streams[i].alsa_hw_desc); ++ if (sdev->out_streams[i].buffers) ++ kfree(sdev->out_streams[i].buffers); ++ } ++ kfree(sdev); ++} ++ ++static struct aaudio_subdevice *aaudio_find_dev_by_dev_id(struct aaudio_device *a, aaudio_device_id_t dev_id) ++{ ++ struct aaudio_subdevice *sdev; ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (dev_id == sdev->dev_id) ++ return sdev; ++ } ++ return NULL; ++} ++ ++static struct aaudio_subdevice *aaudio_find_dev_by_uid(struct aaudio_device *a, const char *uid) ++{ ++ struct aaudio_subdevice *sdev; ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (!strcmp(uid, sdev->uid)) ++ return sdev; ++ } ++ return NULL; ++} ++ ++static void aaudio_init_bs_stream(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm); ++static void aaudio_init_bs_stream_host(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm); ++ ++static int aaudio_init_bs(struct aaudio_device *a) ++{ ++ int i, j; ++ struct aaudio_buffer_struct_device *dev; ++ struct aaudio_subdevice *sdev; ++ u32 ver, sig, bs_base; ++ ++ ver = ioread32(&a->reg_mem_gpr[0]); ++ if (ver < 3) { ++ dev_err(a->dev, "aaudio: Bad GPR version (%u)", ver); ++ return -EINVAL; ++ } ++ sig = ioread32(&a->reg_mem_gpr[1]); ++ if (sig != AAUDIO_SIG) { ++ dev_err(a->dev, "aaudio: Bad GPR sig (%x)", sig); ++ return -EINVAL; ++ } ++ bs_base = ioread32(&a->reg_mem_gpr[2]); ++ a->bs = (struct aaudio_buffer_struct *) ((u8 *) a->reg_mem_bs + bs_base); ++ if (a->bs->signature != AAUDIO_SIG) { ++ dev_err(a->dev, "aaudio: Bad BufferStruct sig (%x)", a->bs->signature); ++ return -EINVAL; ++ } ++ dev_info(a->dev, "aaudio: BufferStruct ver = %i\n", a->bs->version); ++ dev_info(a->dev, "aaudio: Num devices = %i\n", a->bs->num_devices); ++ for (i = 0; i < a->bs->num_devices; i++) { ++ dev = &a->bs->devices[i]; ++ dev_info(a->dev, "aaudio: Device %i %s\n", i, dev->name); ++ ++ sdev = aaudio_find_dev_by_uid(a, dev->name); ++ if (!sdev) { ++ dev_err(a->dev, "aaudio: Subdevice not found for BufferStruct device %s\n", dev->name); ++ continue; ++ } ++ sdev->buf_id = (u8) i; ++ dev->num_input_streams = 0; ++ for (j = 0; j < dev->num_output_streams; j++) { ++ dev_info(a->dev, "aaudio: Device %i Stream %i: Output; Buffer Count = %i\n", i, j, ++ dev->output_streams[j].num_buffers); ++ if (j < sdev->out_stream_cnt) ++ aaudio_init_bs_stream(a, &sdev->out_streams[j], &dev->output_streams[j]); ++ } ++ } ++ ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (sdev->buf_id != AAUDIO_BUFFER_ID_NONE) ++ continue; ++ sdev->buf_id = i; ++ dev_info(a->dev, "aaudio: Created device %i %s\n", i, sdev->uid); ++ strcpy(a->bs->devices[i].name, sdev->uid); ++ a->bs->devices[i].num_input_streams = 0; ++ a->bs->devices[i].num_output_streams = 0; ++ a->bs->num_devices = ++i; ++ } ++ list_for_each_entry(sdev, &a->subdevice_list, list) { ++ if (sdev->in_stream_cnt == 1) { ++ dev_info(a->dev, "aaudio: Device %i Host Stream; Input\n", sdev->buf_id); ++ aaudio_init_bs_stream_host(a, &sdev->in_streams[0], &a->bs->devices[sdev->buf_id].input_streams[0]); ++ a->bs->devices[sdev->buf_id].num_input_streams = 1; ++ wmb(); ++ ++ if (aaudio_cmd_set_input_stream_address_ranges(a, sdev->dev_id)) { ++ dev_err(a->dev, "aaudio: Failed to set input stream address ranges\n"); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static void aaudio_init_bs_stream(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm) ++{ ++ size_t i; ++ strm->buffer_cnt = bs_strm->num_buffers; ++ if (bs_strm->num_buffers > AAUDIO_DEIVCE_MAX_BUFFER_COUNT) { ++ dev_warn(a->dev, "BufferStruct buffer count %u exceeds driver limit of %u\n", bs_strm->num_buffers, ++ AAUDIO_DEIVCE_MAX_BUFFER_COUNT); ++ strm->buffer_cnt = AAUDIO_DEIVCE_MAX_BUFFER_COUNT; ++ } ++ if (!strm->buffer_cnt) ++ return; ++ strm->buffers = kmalloc_array(strm->buffer_cnt, sizeof(struct aaudio_dma_buf), GFP_KERNEL); ++ if (!strm->buffers) { ++ dev_err(a->dev, "Buffer list allocation failed\n"); ++ return; ++ } ++ for (i = 0; i < strm->buffer_cnt; i++) { ++ strm->buffers[i].dma_addr = a->reg_mem_bs_dma + (dma_addr_t) bs_strm->buffers[i].address; ++ strm->buffers[i].ptr = a->reg_mem_bs + bs_strm->buffers[i].address; ++ strm->buffers[i].size = bs_strm->buffers[i].size; ++ } ++ ++ if (strm->buffer_cnt == 1) { ++ strm->alsa_hw_desc = kmalloc(sizeof(struct snd_pcm_hardware), GFP_KERNEL); ++ if (aaudio_create_hw_info(&strm->desc, strm->alsa_hw_desc, strm->buffers[0].size)) { ++ kfree(strm->alsa_hw_desc); ++ strm->alsa_hw_desc = NULL; ++ } ++ } ++} ++ ++static void aaudio_init_bs_stream_host(struct aaudio_device *a, struct aaudio_stream *strm, ++ struct aaudio_buffer_struct_stream *bs_strm) ++{ ++ size_t size; ++ dma_addr_t dma_addr; ++ void *dma_ptr; ++ size = strm->desc.bytes_per_packet * 16640; ++ dma_ptr = dma_alloc_coherent(&a->pci->dev, size, &dma_addr, GFP_KERNEL); ++ if (!dma_ptr) { ++ dev_err(a->dev, "dma_alloc_coherent failed\n"); ++ return; ++ } ++ bs_strm->buffers[0].address = dma_addr; ++ bs_strm->buffers[0].size = size; ++ bs_strm->num_buffers = 1; ++ ++ memset(dma_ptr, 0, size); ++ ++ strm->buffer_cnt = 1; ++ strm->buffers = kmalloc_array(strm->buffer_cnt, sizeof(struct aaudio_dma_buf), GFP_KERNEL); ++ if (!strm->buffers) { ++ dev_err(a->dev, "Buffer list allocation failed\n"); ++ return; ++ } ++ strm->buffers[0].dma_addr = dma_addr; ++ strm->buffers[0].ptr = dma_ptr; ++ strm->buffers[0].size = size; ++ ++ strm->alsa_hw_desc = kmalloc(sizeof(struct snd_pcm_hardware), GFP_KERNEL); ++ if (aaudio_create_hw_info(&strm->desc, strm->alsa_hw_desc, strm->buffers[0].size)) { ++ kfree(strm->alsa_hw_desc); ++ strm->alsa_hw_desc = NULL; ++ } ++} ++ ++static void aaudio_handle_prop_change(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++void aaudio_handle_notification(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_send_ctx sctx; ++ struct aaudio_msg_base base; ++ if (aaudio_msg_read_base(msg, &base)) ++ return; ++ switch (base.msg) { ++ case AAUDIO_MSG_NOTIFICATION_BOOT: ++ dev_info(a->dev, "Received boot notification from remote\n"); ++ ++ /* Resend the alive notify */ ++ if (aaudio_send(a, &sctx, 500, ++ aaudio_msg_write_alive_notification, 1, 3)) { ++ pr_err("Sending alive notification failed\n"); ++ } ++ break; ++ case AAUDIO_MSG_NOTIFICATION_ALIVE: ++ dev_info(a->dev, "Received alive notification from remote\n"); ++ complete_all(&a->remote_alive); ++ break; ++ case AAUDIO_MSG_PROPERTY_CHANGED: ++ aaudio_handle_prop_change(a, msg); ++ break; ++ default: ++ dev_info(a->dev, "Unhandled notification %i", base.msg); ++ break; ++ } ++} ++ ++struct aaudio_prop_change_work_struct { ++ struct work_struct ws; ++ struct aaudio_device *a; ++ aaudio_device_id_t dev; ++ aaudio_object_id_t obj; ++ struct aaudio_prop_addr prop; ++}; ++ ++static void aaudio_handle_jack_connection_change(struct aaudio_subdevice *sdev) ++{ ++ u32 plugged; ++ if (!sdev->jack) ++ return; ++ /* NOTE: Apple made the plug status scoped to the input and output streams. This makes no sense for us, so I just ++ * always pick the OUTPUT status. */ ++ if (aaudio_cmd_get_primitive_property(sdev->a, sdev->dev_id, sdev->dev_id, ++ AAUDIO_PROP(AAUDIO_PROP_SCOPE_OUTPUT, AAUDIO_PROP_JACK_PLUGGED, 0), NULL, 0, &plugged, sizeof(plugged))) { ++ dev_err(sdev->a->dev, "Failed to get jack enable status\n"); ++ return; ++ } ++ dev_dbg(sdev->a->dev, "Jack is now %s\n", plugged ? "plugged" : "unplugged"); ++ snd_jack_report(sdev->jack, plugged ? sdev->jack->type : 0); ++} ++ ++void aaudio_handle_prop_change_work(struct work_struct *ws) ++{ ++ struct aaudio_prop_change_work_struct *work = container_of(ws, struct aaudio_prop_change_work_struct, ws); ++ struct aaudio_subdevice *sdev; ++ ++ sdev = aaudio_find_dev_by_dev_id(work->a, work->dev); ++ if (!sdev) { ++ dev_err(work->a->dev, "Property notification change: device not found\n"); ++ goto done; ++ } ++ dev_dbg(work->a->dev, "Property changed for device: %s\n", sdev->uid); ++ ++ if (work->prop.scope == AAUDIO_PROP_SCOPE_OUTPUT && work->prop.selector == AAUDIO_PROP_JACK_PLUGGED) { ++ aaudio_handle_jack_connection_change(sdev); ++ } ++ ++done: ++ kfree(work); ++} ++ ++void aaudio_handle_prop_change(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ /* NOTE: This is a scheduled work because this callback will generally need to query device information and this ++ * is not possible when we are in the reply parsing code's context. */ ++ struct aaudio_prop_change_work_struct *work; ++ work = kmalloc(sizeof(struct aaudio_prop_change_work_struct), GFP_KERNEL); ++ work->a = a; ++ INIT_WORK(&work->ws, aaudio_handle_prop_change_work); ++ aaudio_msg_read_property_changed(msg, &work->dev, &work->obj, &work->prop); ++ schedule_work(&work->ws); ++} ++ ++#define aaudio_send_cmd_response(a, sctx, msg, fn, ...) \ ++ if (aaudio_send_with_tag(a, sctx, ((struct aaudio_msg_header *) msg->data)->tag, 500, fn, ##__VA_ARGS__)) \ ++ pr_err("aaudio: Failed to reply to a command\n"); ++ ++void aaudio_handle_cmd_timestamp(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ ktime_t time_os = ktime_get_boottime(); ++ struct aaudio_send_ctx sctx; ++ struct aaudio_subdevice *sdev; ++ u64 devid, timestamp, update_seed; ++ aaudio_msg_read_update_timestamp(msg, &devid, ×tamp, &update_seed); ++ dev_dbg(a->dev, "Received timestamp update for dev=%llx ts=%llx seed=%llx\n", devid, timestamp, update_seed); ++ ++ sdev = aaudio_find_dev_by_dev_id(a, devid); ++ aaudio_handle_timestamp(sdev, time_os, timestamp); ++ ++ aaudio_send_cmd_response(a, &sctx, msg, ++ aaudio_msg_write_update_timestamp_response); ++} ++ ++void aaudio_handle_command(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_msg_base base; ++ if (aaudio_msg_read_base(msg, &base)) ++ return; ++ switch (base.msg) { ++ case AAUDIO_MSG_UPDATE_TIMESTAMP: ++ aaudio_handle_cmd_timestamp(a, msg); ++ break; ++ default: ++ dev_info(a->dev, "Unhandled device command %i", base.msg); ++ break; ++ } ++} ++ ++static struct pci_device_id aaudio_ids[ ] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x1803) }, ++ { 0, }, ++}; ++ ++struct dev_pm_ops aaudio_pci_driver_pm = { ++ .suspend = aaudio_suspend, ++ .resume = aaudio_resume ++}; ++struct pci_driver aaudio_pci_driver = { ++ .name = "aaudio", ++ .id_table = aaudio_ids, ++ .probe = aaudio_probe, ++ .remove = aaudio_remove, ++ .driver = { ++ .pm = &aaudio_pci_driver_pm ++ } ++}; ++ ++ ++int aaudio_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&aaudio_chrdev, 0, 1, "aaudio"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ aaudio_class = class_create(THIS_MODULE, "aaudio"); ++#else ++ aaudio_class = class_create("aaudio"); ++#endif ++ if (IS_ERR(aaudio_class)) { ++ result = PTR_ERR(aaudio_class); ++ goto fail_class; ++ } ++ ++ result = pci_register_driver(&aaudio_pci_driver); ++ if (result) ++ goto fail_drv; ++ return 0; ++ ++fail_drv: ++ pci_unregister_driver(&aaudio_pci_driver); ++fail_class: ++ class_destroy(aaudio_class); ++fail_chrdev: ++ unregister_chrdev_region(aaudio_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++ ++void aaudio_module_exit(void) ++{ ++ pci_unregister_driver(&aaudio_pci_driver); ++ class_destroy(aaudio_class); ++ unregister_chrdev_region(aaudio_chrdev, 1); ++} ++ ++struct aaudio_alsa_pcm_id_mapping aaudio_alsa_id_mappings[] = { ++ {"Speaker", 0}, ++ {"Digital Mic", 1}, ++ {"Codec Output", 2}, ++ {"Codec Input", 3}, ++ {"Bridge Loopback", 4}, ++ {} ++}; ++ ++module_param_named(index, aaudio_alsa_index, int, 0444); ++MODULE_PARM_DESC(index, "Index value for Apple Internal Audio soundcard."); ++module_param_named(id, aaudio_alsa_id, charp, 0444); ++MODULE_PARM_DESC(id, "ID string for Apple Internal Audio soundcard."); +diff --git a/drivers/staging/apple-bce/audio/audio.h b/drivers/staging/apple-bce/audio/audio.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/audio.h +@@ -0,0 +1,125 @@ ++#ifndef AAUDIO_H ++#define AAUDIO_H ++ ++#include ++#include ++#include "../apple_bce.h" ++#include "protocol_bce.h" ++#include "description.h" ++ ++#define AAUDIO_SIG 0x19870423 ++ ++#define AAUDIO_DEVICE_MAX_UID_LEN 128 ++#define AAUDIO_DEIVCE_MAX_INPUT_STREAMS 1 ++#define AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS 1 ++#define AAUDIO_DEIVCE_MAX_BUFFER_COUNT 1 ++ ++#define AAUDIO_BUFFER_ID_NONE 0xffu ++ ++struct snd_card; ++struct snd_pcm; ++struct snd_pcm_hardware; ++struct snd_jack; ++ ++struct __attribute__((packed)) __attribute__((aligned(4))) aaudio_buffer_struct_buffer { ++ size_t address; ++ size_t size; ++ size_t pad[4]; ++}; ++struct aaudio_buffer_struct_stream { ++ u8 num_buffers; ++ struct aaudio_buffer_struct_buffer buffers[100]; ++ char filler[32]; ++}; ++struct aaudio_buffer_struct_device { ++ char name[128]; ++ u8 num_input_streams; ++ u8 num_output_streams; ++ struct aaudio_buffer_struct_stream input_streams[5]; ++ struct aaudio_buffer_struct_stream output_streams[5]; ++ char filler[128]; ++}; ++struct aaudio_buffer_struct { ++ u32 version; ++ u32 signature; ++ u32 flags; ++ u8 num_devices; ++ struct aaudio_buffer_struct_device devices[20]; ++}; ++ ++struct aaudio_device; ++struct aaudio_dma_buf { ++ dma_addr_t dma_addr; ++ void *ptr; ++ size_t size; ++}; ++struct aaudio_stream { ++ aaudio_object_id_t id; ++ size_t buffer_cnt; ++ struct aaudio_dma_buf *buffers; ++ ++ struct aaudio_apple_description desc; ++ struct snd_pcm_hardware *alsa_hw_desc; ++ u32 latency; ++ ++ bool waiting_for_first_ts; ++ ++ ktime_t remote_timestamp; ++ snd_pcm_sframes_t frame_min; ++ int started; ++}; ++struct aaudio_subdevice { ++ struct aaudio_device *a; ++ struct list_head list; ++ aaudio_device_id_t dev_id; ++ u32 in_latency, out_latency; ++ u8 buf_id; ++ int alsa_id; ++ char uid[AAUDIO_DEVICE_MAX_UID_LEN + 1]; ++ size_t in_stream_cnt; ++ struct aaudio_stream in_streams[AAUDIO_DEIVCE_MAX_INPUT_STREAMS]; ++ size_t out_stream_cnt; ++ struct aaudio_stream out_streams[AAUDIO_DEIVCE_MAX_OUTPUT_STREAMS]; ++ bool is_pcm; ++ struct snd_pcm *pcm; ++ struct snd_jack *jack; ++}; ++struct aaudio_alsa_pcm_id_mapping { ++ const char *name; ++ int alsa_id; ++}; ++ ++struct aaudio_device { ++ struct pci_dev *pci; ++ dev_t devt; ++ struct device *dev; ++ void __iomem *reg_mem_bs; ++ dma_addr_t reg_mem_bs_dma; ++ void __iomem *reg_mem_cfg; ++ ++ u32 __iomem *reg_mem_gpr; ++ ++ struct aaudio_buffer_struct *bs; ++ ++ struct apple_bce_device *bce; ++ struct aaudio_bce bcem; ++ ++ struct snd_card *card; ++ ++ struct list_head subdevice_list; ++ int next_alsa_id; ++ ++ struct completion remote_alive; ++}; ++ ++void aaudio_handle_notification(struct aaudio_device *a, struct aaudio_msg *msg); ++void aaudio_handle_prop_change_work(struct work_struct *ws); ++void aaudio_handle_cmd_timestamp(struct aaudio_device *a, struct aaudio_msg *msg); ++void aaudio_handle_command(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++int aaudio_module_init(void); ++void aaudio_module_exit(void); ++ ++extern struct aaudio_alsa_pcm_id_mapping aaudio_alsa_id_mappings[]; ++ ++#endif //AAUDIO_H +diff --git a/drivers/staging/apple-bce/audio/description.h b/drivers/staging/apple-bce/audio/description.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/description.h +@@ -0,0 +1,42 @@ ++#ifndef AAUDIO_DESCRIPTION_H ++#define AAUDIO_DESCRIPTION_H ++ ++#include ++ ++struct aaudio_apple_description { ++ u64 sample_rate_double; ++ u32 format_id; ++ u32 format_flags; ++ u32 bytes_per_packet; ++ u32 frames_per_packet; ++ u32 bytes_per_frame; ++ u32 channels_per_frame; ++ u32 bits_per_channel; ++ u32 reserved; ++}; ++ ++enum { ++ AAUDIO_FORMAT_LPCM = 0x6c70636d // 'lpcm' ++}; ++ ++enum { ++ AAUDIO_FORMAT_FLAG_FLOAT = 1, ++ AAUDIO_FORMAT_FLAG_BIG_ENDIAN = 2, ++ AAUDIO_FORMAT_FLAG_SIGNED = 4, ++ AAUDIO_FORMAT_FLAG_PACKED = 8, ++ AAUDIO_FORMAT_FLAG_ALIGNED_HIGH = 16, ++ AAUDIO_FORMAT_FLAG_NON_INTERLEAVED = 32, ++ AAUDIO_FORMAT_FLAG_NON_MIXABLE = 64 ++}; ++ ++static inline u64 aaudio_double_to_u64(u64 d) ++{ ++ u8 sign = (u8) ((d >> 63) & 1); ++ s32 exp = (s32) ((d >> 52) & 0x7ff) - 1023; ++ u64 fr = d & ((1LL << 52) - 1); ++ if (sign || exp < 0) ++ return 0; ++ return (u64) ((1LL << exp) + (fr >> (52 - exp))); ++} ++ ++#endif //AAUDIO_DESCRIPTION_H +diff --git a/drivers/staging/apple-bce/audio/pcm.c b/drivers/staging/apple-bce/audio/pcm.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/pcm.c +@@ -0,0 +1,308 @@ ++#include "pcm.h" ++#include "audio.h" ++ ++static u64 aaudio_get_alsa_fmtbit(struct aaudio_apple_description *desc) ++{ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_FLOAT) { ++ if (desc->bits_per_channel == 32) { ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) ++ return SNDRV_PCM_FMTBIT_FLOAT_BE; ++ else ++ return SNDRV_PCM_FMTBIT_FLOAT_LE; ++ } else if (desc->bits_per_channel == 64) { ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) ++ return SNDRV_PCM_FMTBIT_FLOAT64_BE; ++ else ++ return SNDRV_PCM_FMTBIT_FLOAT64_LE; ++ } else { ++ pr_err("aaudio: unsupported bits per channel for float format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++#define DEFINE_BPC_OPTION(val, b) \ ++ case val: \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_BIG_ENDIAN) { \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) \ ++ return SNDRV_PCM_FMTBIT_S ## b ## BE; \ ++ else \ ++ return SNDRV_PCM_FMTBIT_U ## b ## BE; \ ++ } else { \ ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) \ ++ return SNDRV_PCM_FMTBIT_S ## b ## LE; \ ++ else \ ++ return SNDRV_PCM_FMTBIT_U ## b ## LE; \ ++ } ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_PACKED) { ++ switch (desc->bits_per_channel) { ++ case 8: ++ case 16: ++ case 32: ++ break; ++ DEFINE_BPC_OPTION(24, 24_3) ++ default: ++ pr_err("aaudio: unsupported bits per channel for packed format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_ALIGNED_HIGH) { ++ switch (desc->bits_per_channel) { ++ DEFINE_BPC_OPTION(24, 32_) ++ default: ++ pr_err("aaudio: unsupported bits per channel for high-aligned format: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++ } ++ switch (desc->bits_per_channel) { ++ case 8: ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_SIGNED) ++ return SNDRV_PCM_FMTBIT_S8; ++ else ++ return SNDRV_PCM_FMTBIT_U8; ++ DEFINE_BPC_OPTION(16, 16_) ++ DEFINE_BPC_OPTION(24, 24_) ++ DEFINE_BPC_OPTION(32, 32_) ++ default: ++ pr_err("aaudio: unsupported bits per channel: %u\n", desc->bits_per_channel); ++ return 0; ++ } ++} ++int aaudio_create_hw_info(struct aaudio_apple_description *desc, struct snd_pcm_hardware *alsa_hw, ++ size_t buf_size) ++{ ++ uint rate; ++ alsa_hw->info = (SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_DOUBLE); ++ if (desc->format_flags & AAUDIO_FORMAT_FLAG_NON_MIXABLE) ++ pr_warn("aaudio: unsupported hw flag: NON_MIXABLE\n"); ++ if (!(desc->format_flags & AAUDIO_FORMAT_FLAG_NON_INTERLEAVED)) ++ alsa_hw->info |= SNDRV_PCM_INFO_INTERLEAVED; ++ alsa_hw->formats = aaudio_get_alsa_fmtbit(desc); ++ if (!alsa_hw->formats) ++ return -EINVAL; ++ rate = (uint) aaudio_double_to_u64(desc->sample_rate_double); ++ alsa_hw->rates = snd_pcm_rate_to_rate_bit(rate); ++ alsa_hw->rate_min = rate; ++ alsa_hw->rate_max = rate; ++ alsa_hw->channels_min = desc->channels_per_frame; ++ alsa_hw->channels_max = desc->channels_per_frame; ++ alsa_hw->buffer_bytes_max = buf_size; ++ alsa_hw->period_bytes_min = desc->bytes_per_packet; ++ alsa_hw->period_bytes_max = desc->bytes_per_packet; ++ alsa_hw->periods_min = (uint) (buf_size / desc->bytes_per_packet); ++ alsa_hw->periods_max = (uint) (buf_size / desc->bytes_per_packet); ++ pr_debug("aaudio_create_hw_info: format = %llu, rate = %u/%u. channels = %u, periods = %u, period size = %lu\n", ++ alsa_hw->formats, alsa_hw->rate_min, alsa_hw->rates, alsa_hw->channels_min, alsa_hw->periods_min, ++ alsa_hw->period_bytes_min); ++ return 0; ++} ++ ++static struct aaudio_stream *aaudio_pcm_stream(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ return &sdev->out_streams[substream->number]; ++ else ++ return &sdev->in_streams[substream->number]; ++} ++ ++static int aaudio_pcm_open(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_open\n"); ++ substream->runtime->hw = *aaudio_pcm_stream(substream)->alsa_hw_desc; ++ ++ return 0; ++} ++ ++static int aaudio_pcm_close(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_close\n"); ++ return 0; ++} ++ ++static int aaudio_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ return 0; ++} ++ ++static int aaudio_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) ++{ ++ struct aaudio_stream *astream = aaudio_pcm_stream(substream); ++ pr_debug("aaudio_pcm_hw_params\n"); ++ ++ if (!astream->buffer_cnt || !astream->buffers) ++ return -EINVAL; ++ ++ substream->runtime->dma_area = astream->buffers[0].ptr; ++ substream->runtime->dma_addr = astream->buffers[0].dma_addr; ++ substream->runtime->dma_bytes = astream->buffers[0].size; ++ return 0; ++} ++ ++static int aaudio_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ pr_debug("aaudio_pcm_hw_free\n"); ++ return 0; ++} ++ ++static void aaudio_pcm_start(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ void *buf; ++ size_t s; ++ ktime_t time_start, time_end; ++ bool back_buffer; ++ time_start = ktime_get(); ++ ++ back_buffer = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); ++ ++ if (back_buffer) { ++ s = frames_to_bytes(substream->runtime, substream->runtime->control->appl_ptr); ++ buf = kmalloc(s, GFP_KERNEL); ++ memcpy_fromio(buf, substream->runtime->dma_area, s); ++ time_end = ktime_get(); ++ pr_debug("aaudio: Backed up the buffer in %lluns [%li]\n", ktime_to_ns(time_end - time_start), ++ substream->runtime->control->appl_ptr); ++ } ++ ++ stream->waiting_for_first_ts = true; ++ stream->frame_min = stream->latency; ++ ++ aaudio_cmd_start_io(sdev->a, sdev->dev_id); ++ if (back_buffer) ++ memcpy_toio(substream->runtime->dma_area, buf, s); ++ ++ time_end = ktime_get(); ++ pr_debug("aaudio: Started the audio device in %lluns\n", ktime_to_ns(time_end - time_start)); ++} ++ ++static int aaudio_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream); ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ pr_debug("aaudio_pcm_trigger %x\n", cmd); ++ ++ /* We only supports triggers on the #0 buffer */ ++ if (substream->number != 0) ++ return 0; ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ aaudio_pcm_start(substream); ++ stream->started = 1; ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ aaudio_cmd_stop_io(sdev->a, sdev->dev_id); ++ stream->started = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static snd_pcm_uframes_t aaudio_pcm_pointer(struct snd_pcm_substream *substream) ++{ ++ struct aaudio_stream *stream = aaudio_pcm_stream(substream); ++ ktime_t time_from_start; ++ snd_pcm_sframes_t frames; ++ snd_pcm_sframes_t buffer_time_length; ++ ++ if (!stream->started || stream->waiting_for_first_ts) { ++ pr_warn("aaudio_pcm_pointer while not started\n"); ++ return 0; ++ } ++ ++ /* Approximate the pointer based on the last received timestamp */ ++ time_from_start = ktime_get_boottime() - stream->remote_timestamp; ++ buffer_time_length = NSEC_PER_SEC * substream->runtime->buffer_size / substream->runtime->rate; ++ frames = (ktime_to_ns(time_from_start) % buffer_time_length) * substream->runtime->buffer_size / buffer_time_length; ++ if (ktime_to_ns(time_from_start) < buffer_time_length) { ++ if (frames < stream->frame_min) ++ frames = stream->frame_min; ++ else ++ stream->frame_min = 0; ++ } else { ++ if (ktime_to_ns(time_from_start) < 2 * buffer_time_length) ++ stream->frame_min = frames; ++ else ++ stream->frame_min = 0; /* Heavy desync */ ++ } ++ frames -= stream->latency; ++ if (frames < 0) ++ frames += ((-frames - 1) / substream->runtime->buffer_size + 1) * substream->runtime->buffer_size; ++ return (snd_pcm_uframes_t) frames; ++} ++ ++static struct snd_pcm_ops aaudio_pcm_ops = { ++ .open = aaudio_pcm_open, ++ .close = aaudio_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = aaudio_pcm_hw_params, ++ .hw_free = aaudio_pcm_hw_free, ++ .prepare = aaudio_pcm_prepare, ++ .trigger = aaudio_pcm_trigger, ++ .pointer = aaudio_pcm_pointer, ++ .mmap = snd_pcm_lib_mmap_iomem ++}; ++ ++int aaudio_create_pcm(struct aaudio_subdevice *sdev) ++{ ++ struct snd_pcm *pcm; ++ struct aaudio_alsa_pcm_id_mapping *id_mapping; ++ int err; ++ ++ if (!sdev->is_pcm || (sdev->in_stream_cnt == 0 && sdev->out_stream_cnt == 0)) { ++ return -EINVAL; ++ } ++ ++ for (id_mapping = aaudio_alsa_id_mappings; id_mapping->name; id_mapping++) { ++ if (!strcmp(sdev->uid, id_mapping->name)) { ++ sdev->alsa_id = id_mapping->alsa_id; ++ break; ++ } ++ } ++ if (!id_mapping->name) ++ sdev->alsa_id = sdev->a->next_alsa_id++; ++ err = snd_pcm_new(sdev->a->card, sdev->uid, sdev->alsa_id, ++ (int) sdev->out_stream_cnt, (int) sdev->in_stream_cnt, &pcm); ++ if (err < 0) ++ return err; ++ pcm->private_data = sdev; ++ pcm->nonatomic = 1; ++ sdev->pcm = pcm; ++ strcpy(pcm->name, sdev->uid); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaudio_pcm_ops); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaudio_pcm_ops); ++ return 0; ++} ++ ++static void aaudio_handle_stream_timestamp(struct snd_pcm_substream *substream, ktime_t timestamp) ++{ ++ unsigned long flags; ++ struct aaudio_stream *stream; ++ ++ stream = aaudio_pcm_stream(substream); ++ snd_pcm_stream_lock_irqsave(substream, flags); ++ stream->remote_timestamp = timestamp; ++ if (stream->waiting_for_first_ts) { ++ stream->waiting_for_first_ts = false; ++ snd_pcm_stream_unlock_irqrestore(substream, flags); ++ return; ++ } ++ snd_pcm_stream_unlock_irqrestore(substream, flags); ++ snd_pcm_period_elapsed(substream); ++} ++ ++void aaudio_handle_timestamp(struct aaudio_subdevice *sdev, ktime_t os_timestamp, u64 dev_timestamp) ++{ ++ struct snd_pcm_substream *substream; ++ ++ substream = sdev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; ++ if (substream) ++ aaudio_handle_stream_timestamp(substream, dev_timestamp); ++ substream = sdev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; ++ if (substream) ++ aaudio_handle_stream_timestamp(substream, os_timestamp); ++} +diff --git a/drivers/staging/apple-bce/audio/pcm.h b/drivers/staging/apple-bce/audio/pcm.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/pcm.h +@@ -0,0 +1,16 @@ ++#ifndef AAUDIO_PCM_H ++#define AAUDIO_PCM_H ++ ++#include ++#include ++ ++struct aaudio_subdevice; ++struct aaudio_apple_description; ++struct snd_pcm_hardware; ++ ++int aaudio_create_hw_info(struct aaudio_apple_description *desc, struct snd_pcm_hardware *alsa_hw, size_t buf_size); ++int aaudio_create_pcm(struct aaudio_subdevice *sdev); ++ ++void aaudio_handle_timestamp(struct aaudio_subdevice *sdev, ktime_t os_timestamp, u64 dev_timestamp); ++ ++#endif //AAUDIO_PCM_H +diff --git a/drivers/staging/apple-bce/audio/protocol.c b/drivers/staging/apple-bce/audio/protocol.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol.c +@@ -0,0 +1,347 @@ ++#include "protocol.h" ++#include "protocol_bce.h" ++#include "audio.h" ++ ++int aaudio_msg_read_base(struct aaudio_msg *msg, struct aaudio_msg_base *base) ++{ ++ if (msg->size < sizeof(struct aaudio_msg_header) + sizeof(struct aaudio_msg_base) * 2) ++ return -EINVAL; ++ *base = *((struct aaudio_msg_base *) ((struct aaudio_msg_header *) msg->data + 1)); ++ return 0; ++} ++ ++#define READ_START(type) \ ++ size_t offset = sizeof(struct aaudio_msg_header) + sizeof(struct aaudio_msg_base); (void)offset; \ ++ if (((struct aaudio_msg_base *) ((struct aaudio_msg_header *) msg->data + 1))->msg != type) \ ++ return -EINVAL; ++#define READ_DEVID_VAR(devid) *devid = ((struct aaudio_msg_header *) msg->data)->device_id ++#define READ_VAL(type) ({ offset += sizeof(type); *((type *) ((u8 *) msg->data + offset - sizeof(type))); }) ++#define READ_VAR(type, var) *var = READ_VAL(type) ++ ++int aaudio_msg_read_start_io_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_START_IO_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_stop_io_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_STOP_IO_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_update_timestamp(struct aaudio_msg *msg, aaudio_device_id_t *devid, ++ u64 *timestamp, u64 *update_seed) ++{ ++ READ_START(AAUDIO_MSG_UPDATE_TIMESTAMP); ++ READ_DEVID_VAR(devid); ++ READ_VAR(u64, timestamp); ++ READ_VAR(u64, update_seed); ++ return 0; ++} ++ ++int aaudio_msg_read_get_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop, void **data, u64 *data_size) ++{ ++ READ_START(AAUDIO_MSG_GET_PROPERTY_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ READ_VAR(u64, data_size); ++ *data = ((u8 *) msg->data + offset); ++ /* offset += data_size; */ ++ return 0; ++} ++ ++int aaudio_msg_read_set_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj) ++{ ++ READ_START(AAUDIO_MSG_SET_PROPERTY_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ return 0; ++} ++ ++int aaudio_msg_read_property_listener_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop) ++{ ++ READ_START(AAUDIO_MSG_PROPERTY_LISTENER_RESPONSE); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ return 0; ++} ++ ++int aaudio_msg_read_property_changed(struct aaudio_msg *msg, aaudio_device_id_t *devid, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop) ++{ ++ READ_START(AAUDIO_MSG_PROPERTY_CHANGED); ++ READ_DEVID_VAR(devid); ++ READ_VAR(aaudio_object_id_t, obj); ++ READ_VAR(u32, &prop->element); ++ READ_VAR(u32, &prop->scope); ++ READ_VAR(u32, &prop->selector); ++ return 0; ++} ++ ++int aaudio_msg_read_set_input_stream_address_ranges_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_get_input_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_INPUT_STREAM_LIST_RESPONSE); ++ READ_VAR(u64, str_cnt); ++ *str_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += str_cnt * sizeof(aaudio_object_id_t); */ ++ return 0; ++} ++ ++int aaudio_msg_read_get_output_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_OUTPUT_STREAM_LIST_RESPONSE); ++ READ_VAR(u64, str_cnt); ++ *str_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += str_cnt * sizeof(aaudio_object_id_t); */ ++ return 0; ++} ++ ++int aaudio_msg_read_set_remote_access_response(struct aaudio_msg *msg) ++{ ++ READ_START(AAUDIO_MSG_SET_REMOTE_ACCESS_RESPONSE); ++ return 0; ++} ++ ++int aaudio_msg_read_get_device_list_response(struct aaudio_msg *msg, aaudio_device_id_t **dev_l, u64 *dev_cnt) ++{ ++ READ_START(AAUDIO_MSG_GET_DEVICE_LIST_RESPONSE); ++ READ_VAR(u64, dev_cnt); ++ *dev_l = (aaudio_device_id_t *) ((u8 *) msg->data + offset); ++ /* offset += dev_cnt * sizeof(aaudio_device_id_t); */ ++ return 0; ++} ++ ++#define WRITE_START_OF_TYPE(typev, devid) \ ++ size_t offset = sizeof(struct aaudio_msg_header); (void) offset; \ ++ ((struct aaudio_msg_header *) msg->data)->type = (typev); \ ++ ((struct aaudio_msg_header *) msg->data)->device_id = (devid); ++#define WRITE_START_COMMAND(devid) WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_COMMAND, devid) ++#define WRITE_START_RESPONSE() WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_RESPONSE, 0) ++#define WRITE_START_NOTIFICATION() WRITE_START_OF_TYPE(AAUDIO_MSG_TYPE_NOTIFICATION, 0) ++#define WRITE_VAL(type, value) { *((type *) ((u8 *) msg->data + offset)) = value; offset += sizeof(value); } ++#define WRITE_BIN(value, size) { memcpy((u8 *) msg->data + offset, value, size); offset += size; } ++#define WRITE_BASE(type) WRITE_VAL(u32, type) WRITE_VAL(u32, 0) ++#define WRITE_END() { msg->size = offset; } ++ ++void aaudio_msg_write_start_io(struct aaudio_msg *msg, aaudio_device_id_t dev) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_START_IO); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_stop_io(struct aaudio_msg *msg, aaudio_device_id_t dev) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_STOP_IO); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_GET_PROPERTY); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_VAL(u64, qualifier_size); ++ WRITE_BIN(qualifier, qualifier_size); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *data, u64 data_size, void *qualifier, u64 qualifier_size) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_SET_PROPERTY); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_VAL(u64, data_size); ++ WRITE_BIN(data, data_size); ++ WRITE_VAL(u64, qualifier_size); ++ WRITE_BIN(qualifier, qualifier_size); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_property_listener(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop) ++{ ++ WRITE_START_COMMAND(dev); ++ WRITE_BASE(AAUDIO_MSG_PROPERTY_LISTENER); ++ WRITE_VAL(aaudio_object_id_t, obj); ++ WRITE_VAL(u32, prop.element); ++ WRITE_VAL(u32, prop.scope); ++ WRITE_VAL(u32, prop.selector); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_input_stream_address_ranges(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_input_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_GET_INPUT_STREAM_LIST); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_output_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid) ++{ ++ WRITE_START_COMMAND(devid); ++ WRITE_BASE(AAUDIO_MSG_GET_OUTPUT_STREAM_LIST); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_set_remote_access(struct aaudio_msg *msg, u64 mode) ++{ ++ WRITE_START_COMMAND(0); ++ WRITE_BASE(AAUDIO_MSG_SET_REMOTE_ACCESS); ++ WRITE_VAL(u64, mode); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_alive_notification(struct aaudio_msg *msg, u32 proto_ver, u32 msg_ver) ++{ ++ WRITE_START_NOTIFICATION(); ++ WRITE_BASE(AAUDIO_MSG_NOTIFICATION_ALIVE); ++ WRITE_VAL(u32, proto_ver); ++ WRITE_VAL(u32, msg_ver); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_update_timestamp_response(struct aaudio_msg *msg) ++{ ++ WRITE_START_RESPONSE(); ++ WRITE_BASE(AAUDIO_MSG_UPDATE_TIMESTAMP_RESPONSE); ++ WRITE_END(); ++} ++ ++void aaudio_msg_write_get_device_list(struct aaudio_msg *msg) ++{ ++ WRITE_START_COMMAND(0); ++ WRITE_BASE(AAUDIO_MSG_GET_DEVICE_LIST); ++ WRITE_END(); ++} ++ ++#define CMD_SHARED_VARS_NO_REPLY \ ++ int status = 0; \ ++ struct aaudio_send_ctx sctx; ++#define CMD_SHARED_VARS \ ++ CMD_SHARED_VARS_NO_REPLY \ ++ struct aaudio_msg reply = aaudio_reply_alloc(); \ ++ struct aaudio_msg *buf = &reply; ++#define CMD_SEND_REQUEST(fn, ...) \ ++ if ((status = aaudio_send_cmd_sync(a, &sctx, buf, 500, fn, ##__VA_ARGS__))) \ ++ return status; ++#define CMD_DEF_SHARED_AND_SEND(fn, ...) \ ++ CMD_SHARED_VARS \ ++ CMD_SEND_REQUEST(fn, ##__VA_ARGS__); ++#define CMD_DEF_SHARED_NO_REPLY_AND_SEND(fn, ...) \ ++ CMD_SHARED_VARS_NO_REPLY \ ++ CMD_SEND_REQUEST(fn, ##__VA_ARGS__); ++#define CMD_HNDL_REPLY_NO_FREE(fn, ...) \ ++ status = fn(buf, ##__VA_ARGS__); \ ++ return status; ++#define CMD_HNDL_REPLY_AND_FREE(fn, ...) \ ++ status = fn(buf, ##__VA_ARGS__); \ ++ aaudio_reply_free(&reply); \ ++ return status; ++ ++int aaudio_cmd_start_io(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_start_io, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_start_io_response); ++} ++int aaudio_cmd_stop_io(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_stop_io, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_stop_io_response); ++} ++int aaudio_cmd_get_property(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void **data, u64 *data_size) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_property, devid, obj, prop, qualifier, qualifier_size); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_property_response, &obj, &prop, data, data_size); ++} ++int aaudio_cmd_get_primitive_property(struct aaudio_device *a, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size) ++{ ++ int status; ++ struct aaudio_msg reply = aaudio_reply_alloc(); ++ void *r_data; ++ u64 r_data_size; ++ if ((status = aaudio_cmd_get_property(a, &reply, devid, obj, prop, qualifier, qualifier_size, ++ &r_data, &r_data_size))) ++ goto finish; ++ if (r_data_size != data_size) { ++ status = -EINVAL; ++ goto finish; ++ } ++ memcpy(data, r_data, data_size); ++finish: ++ aaudio_reply_free(&reply); ++ return status; ++} ++int aaudio_cmd_set_property(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_property, devid, obj, prop, data, data_size, ++ qualifier, qualifier_size); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_property_response, &obj); ++} ++int aaudio_cmd_property_listener(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_property_listener, devid, obj, prop); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_property_listener_response, &obj, &prop); ++} ++int aaudio_cmd_set_input_stream_address_ranges(struct aaudio_device *a, aaudio_device_id_t devid) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_input_stream_address_ranges, devid); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_input_stream_address_ranges_response); ++} ++int aaudio_cmd_get_input_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_input_stream_list, devid); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_input_stream_list_response, str_l, str_cnt); ++} ++int aaudio_cmd_get_output_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_output_stream_list, devid); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_output_stream_list_response, str_l, str_cnt); ++} ++int aaudio_cmd_set_remote_access(struct aaudio_device *a, u64 mode) ++{ ++ CMD_DEF_SHARED_AND_SEND(aaudio_msg_write_set_remote_access, mode); ++ CMD_HNDL_REPLY_AND_FREE(aaudio_msg_read_set_remote_access_response); ++} ++int aaudio_cmd_get_device_list(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t **dev_l, u64 *dev_cnt) ++{ ++ CMD_DEF_SHARED_NO_REPLY_AND_SEND(aaudio_msg_write_get_device_list); ++ CMD_HNDL_REPLY_NO_FREE(aaudio_msg_read_get_device_list_response, dev_l, dev_cnt); ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/audio/protocol.h b/drivers/staging/apple-bce/audio/protocol.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol.h +@@ -0,0 +1,147 @@ ++#ifndef AAUDIO_PROTOCOL_H ++#define AAUDIO_PROTOCOL_H ++ ++#include ++ ++struct aaudio_device; ++ ++typedef u64 aaudio_device_id_t; ++typedef u64 aaudio_object_id_t; ++ ++struct aaudio_msg { ++ void *data; ++ size_t size; ++}; ++ ++struct __attribute__((packed)) aaudio_msg_header { ++ char tag[4]; ++ u8 type; ++ aaudio_device_id_t device_id; // Idk, use zero for commands? ++}; ++struct __attribute__((packed)) aaudio_msg_base { ++ u32 msg; ++ u32 status; ++}; ++ ++struct aaudio_prop_addr { ++ u32 scope; ++ u32 selector; ++ u32 element; ++}; ++#define AAUDIO_PROP(scope, sel, el) (struct aaudio_prop_addr) { scope, sel, el } ++ ++enum { ++ AAUDIO_MSG_TYPE_COMMAND = 1, ++ AAUDIO_MSG_TYPE_RESPONSE = 2, ++ AAUDIO_MSG_TYPE_NOTIFICATION = 3 ++}; ++ ++enum { ++ AAUDIO_MSG_START_IO = 0, ++ AAUDIO_MSG_START_IO_RESPONSE = 1, ++ AAUDIO_MSG_STOP_IO = 2, ++ AAUDIO_MSG_STOP_IO_RESPONSE = 3, ++ AAUDIO_MSG_UPDATE_TIMESTAMP = 4, ++ AAUDIO_MSG_GET_PROPERTY = 7, ++ AAUDIO_MSG_GET_PROPERTY_RESPONSE = 8, ++ AAUDIO_MSG_SET_PROPERTY = 9, ++ AAUDIO_MSG_SET_PROPERTY_RESPONSE = 10, ++ AAUDIO_MSG_PROPERTY_LISTENER = 11, ++ AAUDIO_MSG_PROPERTY_LISTENER_RESPONSE = 12, ++ AAUDIO_MSG_PROPERTY_CHANGED = 13, ++ AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES = 18, ++ AAUDIO_MSG_SET_INPUT_STREAM_ADDRESS_RANGES_RESPONSE = 19, ++ AAUDIO_MSG_GET_INPUT_STREAM_LIST = 24, ++ AAUDIO_MSG_GET_INPUT_STREAM_LIST_RESPONSE = 25, ++ AAUDIO_MSG_GET_OUTPUT_STREAM_LIST = 26, ++ AAUDIO_MSG_GET_OUTPUT_STREAM_LIST_RESPONSE = 27, ++ AAUDIO_MSG_SET_REMOTE_ACCESS = 32, ++ AAUDIO_MSG_SET_REMOTE_ACCESS_RESPONSE = 33, ++ AAUDIO_MSG_UPDATE_TIMESTAMP_RESPONSE = 34, ++ ++ AAUDIO_MSG_NOTIFICATION_ALIVE = 100, ++ AAUDIO_MSG_GET_DEVICE_LIST = 101, ++ AAUDIO_MSG_GET_DEVICE_LIST_RESPONSE = 102, ++ AAUDIO_MSG_NOTIFICATION_BOOT = 104 ++}; ++ ++enum { ++ AAUDIO_REMOTE_ACCESS_OFF = 0, ++ AAUDIO_REMOTE_ACCESS_ON = 2 ++}; ++ ++enum { ++ AAUDIO_PROP_SCOPE_GLOBAL = 0x676c6f62, // 'glob' ++ AAUDIO_PROP_SCOPE_INPUT = 0x696e7074, // 'inpt' ++ AAUDIO_PROP_SCOPE_OUTPUT = 0x6f757470 // 'outp' ++}; ++ ++enum { ++ AAUDIO_PROP_UID = 0x75696420, // 'uid ' ++ AAUDIO_PROP_BOOL_VALUE = 0x6263766c, // 'bcvl' ++ AAUDIO_PROP_JACK_PLUGGED = 0x6a61636b, // 'jack' ++ AAUDIO_PROP_SEL_VOLUME = 0x64656176, // 'deav' ++ AAUDIO_PROP_LATENCY = 0x6c746e63, // 'ltnc' ++ AAUDIO_PROP_PHYS_FORMAT = 0x70667420 // 'pft ' ++}; ++ ++int aaudio_msg_read_base(struct aaudio_msg *msg, struct aaudio_msg_base *base); ++ ++int aaudio_msg_read_start_io_response(struct aaudio_msg *msg); ++int aaudio_msg_read_stop_io_response(struct aaudio_msg *msg); ++int aaudio_msg_read_update_timestamp(struct aaudio_msg *msg, aaudio_device_id_t *devid, ++ u64 *timestamp, u64 *update_seed); ++int aaudio_msg_read_get_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop, void **data, u64 *data_size); ++int aaudio_msg_read_set_property_response(struct aaudio_msg *msg, aaudio_object_id_t *obj); ++int aaudio_msg_read_property_listener_response(struct aaudio_msg *msg,aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop); ++int aaudio_msg_read_property_changed(struct aaudio_msg *msg, aaudio_device_id_t *devid, aaudio_object_id_t *obj, ++ struct aaudio_prop_addr *prop); ++int aaudio_msg_read_set_input_stream_address_ranges_response(struct aaudio_msg *msg); ++int aaudio_msg_read_get_input_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_msg_read_get_output_stream_list_response(struct aaudio_msg *msg, aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_msg_read_set_remote_access_response(struct aaudio_msg *msg); ++int aaudio_msg_read_get_device_list_response(struct aaudio_msg *msg, aaudio_device_id_t **dev_l, u64 *dev_cnt); ++ ++void aaudio_msg_write_start_io(struct aaudio_msg *msg, aaudio_device_id_t dev); ++void aaudio_msg_write_stop_io(struct aaudio_msg *msg, aaudio_device_id_t dev); ++void aaudio_msg_write_get_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size); ++void aaudio_msg_write_set_property(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *data, u64 data_size, void *qualifier, u64 qualifier_size); ++void aaudio_msg_write_property_listener(struct aaudio_msg *msg, aaudio_device_id_t dev, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop); ++void aaudio_msg_write_set_input_stream_address_ranges(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_get_input_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_get_output_stream_list(struct aaudio_msg *msg, aaudio_device_id_t devid); ++void aaudio_msg_write_set_remote_access(struct aaudio_msg *msg, u64 mode); ++void aaudio_msg_write_alive_notification(struct aaudio_msg *msg, u32 proto_ver, u32 msg_ver); ++void aaudio_msg_write_update_timestamp_response(struct aaudio_msg *msg); ++void aaudio_msg_write_get_device_list(struct aaudio_msg *msg); ++ ++ ++int aaudio_cmd_start_io(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_stop_io(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_get_property(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void **data, u64 *data_size); ++int aaudio_cmd_get_primitive_property(struct aaudio_device *a, ++ aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size); ++int aaudio_cmd_set_property(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop, void *qualifier, u64 qualifier_size, void *data, u64 data_size); ++int aaudio_cmd_property_listener(struct aaudio_device *a, aaudio_device_id_t devid, aaudio_object_id_t obj, ++ struct aaudio_prop_addr prop); ++int aaudio_cmd_set_input_stream_address_ranges(struct aaudio_device *a, aaudio_device_id_t devid); ++int aaudio_cmd_get_input_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_cmd_get_output_stream_list(struct aaudio_device *a, struct aaudio_msg *buf, aaudio_device_id_t devid, ++ aaudio_object_id_t **str_l, u64 *str_cnt); ++int aaudio_cmd_set_remote_access(struct aaudio_device *a, u64 mode); ++int aaudio_cmd_get_device_list(struct aaudio_device *a, struct aaudio_msg *buf, ++ aaudio_device_id_t **dev_l, u64 *dev_cnt); ++ ++ ++ ++#endif //AAUDIO_PROTOCOL_H +diff --git a/drivers/staging/apple-bce/audio/protocol_bce.c b/drivers/staging/apple-bce/audio/protocol_bce.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol_bce.c +@@ -0,0 +1,226 @@ ++#include "protocol_bce.h" ++ ++#include "audio.h" ++ ++static void aaudio_bce_out_queue_completion(struct bce_queue_sq *sq); ++static void aaudio_bce_in_queue_completion(struct bce_queue_sq *sq); ++static int aaudio_bce_queue_init(struct aaudio_device *dev, struct aaudio_bce_queue *q, const char *name, int direction, ++ bce_sq_completion cfn); ++void aaudio_bce_in_queue_submit_pending(struct aaudio_bce_queue *q, size_t count); ++ ++int aaudio_bce_init(struct aaudio_device *dev) ++{ ++ int status; ++ struct aaudio_bce *bce = &dev->bcem; ++ bce->cq = bce_create_cq(dev->bce, 0x80); ++ spin_lock_init(&bce->spinlock); ++ if (!bce->cq) ++ return -EINVAL; ++ if ((status = aaudio_bce_queue_init(dev, &bce->qout, "com.apple.BridgeAudio.IntelToARM", DMA_TO_DEVICE, ++ aaudio_bce_out_queue_completion))) { ++ return status; ++ } ++ if ((status = aaudio_bce_queue_init(dev, &bce->qin, "com.apple.BridgeAudio.ARMToIntel", DMA_FROM_DEVICE, ++ aaudio_bce_in_queue_completion))) { ++ return status; ++ } ++ aaudio_bce_in_queue_submit_pending(&bce->qin, bce->qin.el_count); ++ return 0; ++} ++ ++int aaudio_bce_queue_init(struct aaudio_device *dev, struct aaudio_bce_queue *q, const char *name, int direction, ++ bce_sq_completion cfn) ++{ ++ q->cq = dev->bcem.cq; ++ q->el_size = AAUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ q->el_count = AAUDIO_BCE_QUEUE_ELEMENT_COUNT; ++ /* NOTE: The Apple impl uses 0x80 as the queue size, however we use 21 (in fact 20) to simplify the impl */ ++ q->sq = bce_create_sq(dev->bce, q->cq, name, (u32) (q->el_count + 1), direction, cfn, dev); ++ if (!q->sq) ++ return -EINVAL; ++ ++ q->data = dma_alloc_coherent(&dev->bce->pci->dev, q->el_size * q->el_count, &q->dma_addr, GFP_KERNEL); ++ if (!q->data) { ++ bce_destroy_sq(dev->bce, q->sq); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static void aaudio_send_create_tag(struct aaudio_bce *b, int *tagn, char tag[4]) ++{ ++ char tag_zero[5]; ++ b->tag_num = (b->tag_num + 1) % AAUDIO_BCE_QUEUE_TAG_COUNT; ++ *tagn = b->tag_num; ++ snprintf(tag_zero, 5, "S%03d", b->tag_num); ++ *((u32 *) tag) = *((u32 *) tag_zero); ++} ++ ++int __aaudio_send_prepare(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, char *tag) ++{ ++ int status; ++ size_t index; ++ void *dptr; ++ struct aaudio_msg_header *header; ++ if ((status = bce_reserve_submission(b->qout.sq, &ctx->timeout))) ++ return status; ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ index = b->qout.data_tail; ++ dptr = (u8 *) b->qout.data + index * b->qout.el_size; ++ ctx->msg.data = dptr; ++ header = dptr; ++ if (tag) ++ *((u32 *) header->tag) = *((u32 *) tag); ++ else ++ aaudio_send_create_tag(b, &ctx->tag_n, header->tag); ++ return 0; ++} ++ ++void __aaudio_send(struct aaudio_bce *b, struct aaudio_send_ctx *ctx) ++{ ++ struct bce_qe_submission *s = bce_next_submission(b->qout.sq); ++#ifdef DEBUG ++ pr_debug("aaudio: Sending command data\n"); ++ print_hex_dump(KERN_DEBUG, "aaudio:OUT ", DUMP_PREFIX_NONE, 32, 1, ctx->msg.data, ctx->msg.size, true); ++#endif ++ bce_set_submission_single(s, b->qout.dma_addr + (dma_addr_t) (ctx->msg.data - b->qout.data), ctx->msg.size); ++ bce_submit_to_device(b->qout.sq); ++ b->qout.data_tail = (b->qout.data_tail + 1) % b->qout.el_count; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++} ++ ++int __aaudio_send_cmd_sync(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, struct aaudio_msg *reply) ++{ ++ struct aaudio_bce_queue_entry ent; ++ DECLARE_COMPLETION_ONSTACK(cmpl); ++ ent.msg = reply; ++ ent.cmpl = &cmpl; ++ b->pending_entries[ctx->tag_n] = &ent; ++ __aaudio_send(b, ctx); /* unlocks the spinlock */ ++ ctx->timeout = wait_for_completion_timeout(&cmpl, ctx->timeout); ++ if (ctx->timeout == 0) { ++ /* Remove the pending queue entry; this will be normally handled by the completion route but ++ * during a timeout it won't */ ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ if (b->pending_entries[ctx->tag_n] == &ent) ++ b->pending_entries[ctx->tag_n] = NULL; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static void aaudio_handle_reply(struct aaudio_bce *b, struct aaudio_msg *reply) ++{ ++ const char *tag; ++ int tagn; ++ unsigned long irq_flags; ++ char tag_zero[5]; ++ struct aaudio_bce_queue_entry *entry; ++ ++ tag = ((struct aaudio_msg_header *) reply->data)->tag; ++ if (tag[0] != 'S') { ++ pr_err("aaudio_handle_reply: Unexpected tag: %.4s\n", tag); ++ return; ++ } ++ *((u32 *) tag_zero) = *((u32 *) tag); ++ tag_zero[4] = 0; ++ if (kstrtoint(&tag_zero[1], 10, &tagn)) { ++ pr_err("aaudio_handle_reply: Tag parse failed: %.4s\n", tag); ++ return; ++ } ++ ++ spin_lock_irqsave(&b->spinlock, irq_flags); ++ entry = b->pending_entries[tagn]; ++ if (entry) { ++ if (reply->size < entry->msg->size) ++ entry->msg->size = reply->size; ++ memcpy(entry->msg->data, reply->data, entry->msg->size); ++ complete(entry->cmpl); ++ ++ b->pending_entries[tagn] = NULL; ++ } else { ++ pr_err("aaudio_handle_reply: No queued item found for tag: %.4s\n", tag); ++ } ++ spin_unlock_irqrestore(&b->spinlock, irq_flags); ++} ++ ++static void aaudio_bce_out_queue_completion(struct bce_queue_sq *sq) ++{ ++ while (bce_next_completion(sq)) { ++ //pr_info("aaudio: Send confirmed\n"); ++ bce_notify_submission_complete(sq); ++ } ++} ++ ++static void aaudio_bce_in_queue_handle_msg(struct aaudio_device *a, struct aaudio_msg *msg); ++ ++static void aaudio_bce_in_queue_completion(struct bce_queue_sq *sq) ++{ ++ struct aaudio_msg msg; ++ struct aaudio_device *dev = sq->userdata; ++ struct aaudio_bce_queue *q = &dev->bcem.qin; ++ struct bce_sq_completion_data *c; ++ size_t cnt = 0; ++ ++ mb(); ++ while ((c = bce_next_completion(sq))) { ++ msg.data = (u8 *) q->data + q->data_head * q->el_size; ++ msg.size = c->data_size; ++#ifdef DEBUG ++ pr_debug("aaudio: Received command data %llx\n", c->data_size); ++ print_hex_dump(KERN_DEBUG, "aaudio:IN ", DUMP_PREFIX_NONE, 32, 1, msg.data, min(msg.size, 128UL), true); ++#endif ++ aaudio_bce_in_queue_handle_msg(dev, &msg); ++ ++ q->data_head = (q->data_head + 1) % q->el_count; ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ aaudio_bce_in_queue_submit_pending(q, cnt); ++} ++ ++static void aaudio_bce_in_queue_handle_msg(struct aaudio_device *a, struct aaudio_msg *msg) ++{ ++ struct aaudio_msg_header *header = (struct aaudio_msg_header *) msg->data; ++ if (msg->size < sizeof(struct aaudio_msg_header)) { ++ pr_err("aaudio: Msg size smaller than header (%lx)", msg->size); ++ return; ++ } ++ if (header->type == AAUDIO_MSG_TYPE_RESPONSE) { ++ aaudio_handle_reply(&a->bcem, msg); ++ } else if (header->type == AAUDIO_MSG_TYPE_COMMAND) { ++ aaudio_handle_command(a, msg); ++ } else if (header->type == AAUDIO_MSG_TYPE_NOTIFICATION) { ++ aaudio_handle_notification(a, msg); ++ } ++} ++ ++void aaudio_bce_in_queue_submit_pending(struct aaudio_bce_queue *q, size_t count) ++{ ++ struct bce_qe_submission *s; ++ while (count--) { ++ if (bce_reserve_submission(q->sq, NULL)) { ++ pr_err("aaudio: Failed to reserve an event queue submission\n"); ++ break; ++ } ++ s = bce_next_submission(q->sq); ++ bce_set_submission_single(s, q->dma_addr + (dma_addr_t) (q->data_tail * q->el_size), q->el_size); ++ q->data_tail = (q->data_tail + 1) % q->el_count; ++ } ++ bce_submit_to_device(q->sq); ++} ++ ++struct aaudio_msg aaudio_reply_alloc(void) ++{ ++ struct aaudio_msg ret; ++ ret.size = AAUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ ret.data = kmalloc(ret.size, GFP_KERNEL); ++ return ret; ++} ++ ++void aaudio_reply_free(struct aaudio_msg *reply) ++{ ++ kfree(reply->data); ++} +diff --git a/drivers/staging/apple-bce/audio/protocol_bce.h b/drivers/staging/apple-bce/audio/protocol_bce.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/audio/protocol_bce.h +@@ -0,0 +1,72 @@ ++#ifndef AAUDIO_PROTOCOL_BCE_H ++#define AAUDIO_PROTOCOL_BCE_H ++ ++#include "protocol.h" ++#include "../queue.h" ++ ++#define AAUDIO_BCE_QUEUE_ELEMENT_SIZE 0x1000 ++#define AAUDIO_BCE_QUEUE_ELEMENT_COUNT 20 ++ ++#define AAUDIO_BCE_QUEUE_TAG_COUNT 1000 ++ ++struct aaudio_device; ++ ++struct aaudio_bce_queue_entry { ++ struct aaudio_msg *msg; ++ struct completion *cmpl; ++}; ++struct aaudio_bce_queue { ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq; ++ void *data; ++ dma_addr_t dma_addr; ++ size_t data_head, data_tail; ++ size_t el_size, el_count; ++}; ++struct aaudio_bce { ++ struct bce_queue_cq *cq; ++ struct aaudio_bce_queue qin; ++ struct aaudio_bce_queue qout; ++ int tag_num; ++ struct aaudio_bce_queue_entry *pending_entries[AAUDIO_BCE_QUEUE_TAG_COUNT]; ++ struct spinlock spinlock; ++}; ++ ++struct aaudio_send_ctx { ++ int status; ++ int tag_n; ++ unsigned long irq_flags; ++ struct aaudio_msg msg; ++ unsigned long timeout; ++}; ++ ++int aaudio_bce_init(struct aaudio_device *dev); ++int __aaudio_send_prepare(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, char *tag); ++void __aaudio_send(struct aaudio_bce *b, struct aaudio_send_ctx *ctx); ++int __aaudio_send_cmd_sync(struct aaudio_bce *b, struct aaudio_send_ctx *ctx, struct aaudio_msg *reply); ++ ++#define aaudio_send_with_tag(a, ctx, tag, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __aaudio_send_prepare(&(a)->bcem, (ctx), (tag)); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ __aaudio_send(&(a)->bcem, (ctx)); \ ++ } \ ++ (ctx)->status; \ ++}) ++#define aaudio_send(a, ctx, tout, fn, ...) aaudio_send_with_tag(a, ctx, NULL, tout, fn, ##__VA_ARGS__) ++ ++#define aaudio_send_cmd_sync(a, ctx, reply, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __aaudio_send_prepare(&(a)->bcem, (ctx), NULL); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ (ctx)->status = __aaudio_send_cmd_sync(&(a)->bcem, (ctx), (reply)); \ ++ } \ ++ (ctx)->status; \ ++}) ++ ++struct aaudio_msg aaudio_reply_alloc(void); ++void aaudio_reply_free(struct aaudio_msg *reply); ++ ++#endif //AAUDIO_PROTOCOL_BCE_H +diff --git a/drivers/staging/apple-bce/mailbox.c b/drivers/staging/apple-bce/mailbox.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/mailbox.c +@@ -0,0 +1,155 @@ ++#include "mailbox.h" ++#include ++#include "apple_bce.h" ++#include ++ ++#define REG_MBOX_OUT_BASE 0x820 ++#define REG_MBOX_REPLY_COUNTER 0x108 ++#define REG_MBOX_REPLY_BASE 0x810 ++#define REG_TIMESTAMP_BASE 0xC000 ++ ++#define BCE_MBOX_TIMEOUT_MS 200 ++ ++void bce_mailbox_init(struct bce_mailbox *mb, void __iomem *reg_mb) ++{ ++ mb->reg_mb = reg_mb; ++ init_completion(&mb->mb_completion); ++} ++ ++int bce_mailbox_send(struct bce_mailbox *mb, u64 msg, u64* recv) ++{ ++ u32 __iomem *regb; ++ ++ if (atomic_cmpxchg(&mb->mb_status, 0, 1) != 0) { ++ return -EEXIST; // We don't support two messages at once ++ } ++ reinit_completion(&mb->mb_completion); ++ ++ pr_debug("bce_mailbox_send: %llx\n", msg); ++ regb = (u32*) ((u8*) mb->reg_mb + REG_MBOX_OUT_BASE); ++ iowrite32((u32) msg, regb); ++ iowrite32((u32) (msg >> 32), regb + 1); ++ iowrite32(0, regb + 2); ++ iowrite32(0, regb + 3); ++ ++ wait_for_completion_timeout(&mb->mb_completion, msecs_to_jiffies(BCE_MBOX_TIMEOUT_MS)); ++ if (atomic_read(&mb->mb_status) != 2) { // Didn't get the reply ++ atomic_set(&mb->mb_status, 0); ++ return -ETIMEDOUT; ++ } ++ ++ *recv = mb->mb_result; ++ pr_debug("bce_mailbox_send: reply %llx\n", *recv); ++ ++ atomic_set(&mb->mb_status, 0); ++ return 0; ++} ++ ++static int bce_mailbox_retrive_response(struct bce_mailbox *mb) ++{ ++ u32 __iomem *regb; ++ u32 lo, hi; ++ int count, counter; ++ u32 res = ioread32((u8*) mb->reg_mb + REG_MBOX_REPLY_COUNTER); ++ count = (res >> 20) & 0xf; ++ counter = count; ++ pr_debug("bce_mailbox_retrive_response count=%i\n", count); ++ while (counter--) { ++ regb = (u32*) ((u8*) mb->reg_mb + REG_MBOX_REPLY_BASE); ++ lo = ioread32(regb); ++ hi = ioread32(regb + 1); ++ ioread32(regb + 2); ++ ioread32(regb + 3); ++ pr_debug("bce_mailbox_retrive_response %llx\n", ((u64) hi << 32) | lo); ++ mb->mb_result = ((u64) hi << 32) | lo; ++ } ++ return count > 0 ? 0 : -ENODATA; ++} ++ ++int bce_mailbox_handle_interrupt(struct bce_mailbox *mb) ++{ ++ int status = bce_mailbox_retrive_response(mb); ++ if (!status) { ++ atomic_set(&mb->mb_status, 2); ++ complete(&mb->mb_completion); ++ } ++ return status; ++} ++ ++static void bc_send_timestamp(struct timer_list *tl); ++ ++void bce_timestamp_init(struct bce_timestamp *ts, void __iomem *reg) ++{ ++ u32 __iomem *regb; ++ ++ spin_lock_init(&ts->stop_sl); ++ ts->stopped = false; ++ ++ ts->reg = reg; ++ ++ regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ ioread32(regb); ++ mb(); ++ ++ timer_setup(&ts->timer, bc_send_timestamp, 0); ++} ++ ++void bce_timestamp_start(struct bce_timestamp *ts, bool is_initial) ++{ ++ unsigned long flags; ++ u32 __iomem *regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ if (is_initial) { ++ iowrite32((u32) -4, regb + 2); ++ iowrite32((u32) -1, regb); ++ } else { ++ iowrite32((u32) -3, regb + 2); ++ iowrite32((u32) -1, regb); ++ } ++ ++ spin_lock_irqsave(&ts->stop_sl, flags); ++ ts->stopped = false; ++ spin_unlock_irqrestore(&ts->stop_sl, flags); ++ mod_timer(&ts->timer, jiffies + msecs_to_jiffies(150)); ++} ++ ++void bce_timestamp_stop(struct bce_timestamp *ts) ++{ ++ unsigned long flags; ++ u32 __iomem *regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ ++ spin_lock_irqsave(&ts->stop_sl, flags); ++ ts->stopped = true; ++ spin_unlock_irqrestore(&ts->stop_sl, flags); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,15,0) ++ del_timer_sync(&ts->timer); ++#else ++ timer_delete_sync(&ts->timer); ++#endif ++ iowrite32((u32) -2, regb + 2); ++ iowrite32((u32) -1, regb); ++} ++ ++static void bc_send_timestamp(struct timer_list *tl) ++{ ++ struct bce_timestamp *ts; ++ unsigned long flags; ++ u32 __iomem *regb; ++ ktime_t bt; ++ ++ ts = container_of(tl, struct bce_timestamp, timer); ++ regb = (u32*) ((u8*) ts->reg + REG_TIMESTAMP_BASE); ++ local_irq_save(flags); ++ ioread32(regb + 2); ++ mb(); ++ bt = ktime_get_boottime(); ++ iowrite32((u32) bt, regb + 2); ++ iowrite32((u32) (bt >> 32), regb); ++ ++ spin_lock(&ts->stop_sl); ++ if (!ts->stopped) ++ mod_timer(&ts->timer, jiffies + msecs_to_jiffies(150)); ++ spin_unlock(&ts->stop_sl); ++ local_irq_restore(flags); ++} +diff --git a/drivers/staging/apple-bce/mailbox.h b/drivers/staging/apple-bce/mailbox.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/mailbox.h +@@ -0,0 +1,53 @@ ++#ifndef BCE_MAILBOX_H ++#define BCE_MAILBOX_H ++ ++#include ++#include ++#include ++ ++struct bce_mailbox { ++ void __iomem *reg_mb; ++ ++ atomic_t mb_status; // possible statuses: 0 (no msg), 1 (has active msg), 2 (got reply) ++ struct completion mb_completion; ++ uint64_t mb_result; ++}; ++ ++enum bce_message_type { ++ BCE_MB_REGISTER_COMMAND_SQ = 0x7, // to-device ++ BCE_MB_REGISTER_COMMAND_CQ = 0x8, // to-device ++ BCE_MB_REGISTER_COMMAND_QUEUE_REPLY = 0xB, // to-host ++ BCE_MB_SET_FW_PROTOCOL_VERSION = 0xC, // both ++ BCE_MB_SLEEP_NO_STATE = 0x14, // to-device ++ BCE_MB_RESTORE_NO_STATE = 0x15, // to-device ++ BCE_MB_SAVE_STATE_AND_SLEEP = 0x17, // to-device ++ BCE_MB_RESTORE_STATE_AND_WAKE = 0x18, // to-device ++ BCE_MB_SAVE_STATE_AND_SLEEP_FAILURE = 0x19, // from-device ++ BCE_MB_SAVE_RESTORE_STATE_COMPLETE = 0x1A, // from-device ++}; ++ ++#define BCE_MB_MSG(type, value) (((u64) (type) << 58) | ((value) & 0x3FFFFFFFFFFFFFFLL)) ++#define BCE_MB_TYPE(v) ((u32) (v >> 58)) ++#define BCE_MB_VALUE(v) (v & 0x3FFFFFFFFFFFFFFLL) ++ ++void bce_mailbox_init(struct bce_mailbox *mb, void __iomem *reg_mb); ++ ++int bce_mailbox_send(struct bce_mailbox *mb, u64 msg, u64* recv); ++ ++int bce_mailbox_handle_interrupt(struct bce_mailbox *mb); ++ ++ ++struct bce_timestamp { ++ void __iomem *reg; ++ struct timer_list timer; ++ struct spinlock stop_sl; ++ bool stopped; ++}; ++ ++void bce_timestamp_init(struct bce_timestamp *ts, void __iomem *reg); ++ ++void bce_timestamp_start(struct bce_timestamp *ts, bool is_initial); ++ ++void bce_timestamp_stop(struct bce_timestamp *ts); ++ ++#endif //BCEDRIVER_MAILBOX_H +diff --git a/drivers/staging/apple-bce/queue.c b/drivers/staging/apple-bce/queue.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue.c +@@ -0,0 +1,415 @@ ++#include "queue.h" ++#include "apple_bce.h" ++#include ++ ++#define REG_DOORBELL_BASE 0x44000 ++ ++struct bce_queue_cq *bce_alloc_cq(struct apple_bce_device *dev, int qid, u32 el_count) ++{ ++ struct bce_queue_cq *q; ++ q = kzalloc(sizeof(struct bce_queue_cq), GFP_KERNEL); ++ q->qid = qid; ++ q->type = BCE_QUEUE_CQ; ++ q->el_count = el_count; ++ q->data = dma_alloc_coherent(&dev->pci->dev, el_count * sizeof(struct bce_qe_completion), ++ &q->dma_handle, GFP_KERNEL); ++ if (!q->data) { ++ pr_err("DMA queue memory alloc failed\n"); ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_get_cq_memcfg(struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg) ++{ ++ cfg->qid = (u16) cq->qid; ++ cfg->el_count = (u16) cq->el_count; ++ cfg->vector_or_cq = 0; ++ cfg->_pad = 0; ++ cfg->addr = cq->dma_handle; ++ cfg->length = cq->el_count * sizeof(struct bce_qe_completion); ++} ++ ++void bce_free_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ dma_free_coherent(&dev->pci->dev, cq->el_count * sizeof(struct bce_qe_completion), cq->data, cq->dma_handle); ++ kfree(cq); ++} ++ ++static void bce_handle_cq_completion(struct apple_bce_device *dev, struct bce_qe_completion *e, size_t *ce) ++{ ++ struct bce_queue *target; ++ struct bce_queue_sq *target_sq; ++ struct bce_sq_completion_data *cmpl; ++ if (e->qid >= BCE_MAX_QUEUE_COUNT) { ++ pr_err("Device sent a response for qid (%u) >= BCE_MAX_QUEUE_COUNT\n", e->qid); ++ return; ++ } ++ target = dev->queues[e->qid]; ++ if (!target || target->type != BCE_QUEUE_SQ) { ++ pr_err("Device sent a response for qid (%u), which does not exist\n", e->qid); ++ return; ++ } ++ target_sq = (struct bce_queue_sq *) target; ++ if (target_sq->completion_tail != e->completion_index) { ++ pr_err("Completion index mismatch; this is likely going to make this driver unusable\n"); ++ return; ++ } ++ if (!target_sq->has_pending_completions) { ++ target_sq->has_pending_completions = true; ++ dev->int_sq_list[(*ce)++] = target_sq; ++ } ++ cmpl = &target_sq->completion_data[e->completion_index]; ++ cmpl->status = e->status; ++ cmpl->data_size = e->data_size; ++ cmpl->result = e->result; ++ wmb(); ++ target_sq->completion_tail = (target_sq->completion_tail + 1) % target_sq->el_count; ++} ++ ++void bce_handle_cq_completions(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ size_t ce = 0; ++ struct bce_qe_completion *e; ++ struct bce_queue_sq *sq; ++ e = bce_cq_element(cq, cq->index); ++ if (!(e->flags & BCE_COMPLETION_FLAG_PENDING)) ++ return; ++ mb(); ++ while (true) { ++ e = bce_cq_element(cq, cq->index); ++ if (!(e->flags & BCE_COMPLETION_FLAG_PENDING)) ++ break; ++ // pr_info("apple-bce: compl: %i: %i %llx %llx", e->qid, e->status, e->data_size, e->result); ++ bce_handle_cq_completion(dev, e, &ce); ++ e->flags = 0; ++ cq->index = (cq->index + 1) % cq->el_count; ++ } ++ mb(); ++ iowrite32(cq->index, (u32 *) ((u8 *) dev->reg_mem_dma + REG_DOORBELL_BASE) + cq->qid); ++ while (ce) { ++ --ce; ++ sq = dev->int_sq_list[ce]; ++ sq->completion(sq); ++ sq->has_pending_completions = false; ++ } ++} ++ ++ ++struct bce_queue_sq *bce_alloc_sq(struct apple_bce_device *dev, int qid, u32 el_size, u32 el_count, ++ bce_sq_completion compl, void *userdata) ++{ ++ struct bce_queue_sq *q; ++ q = kzalloc(sizeof(struct bce_queue_sq), GFP_KERNEL); ++ q->qid = qid; ++ q->type = BCE_QUEUE_SQ; ++ q->el_size = el_size; ++ q->el_count = el_count; ++ q->data = dma_alloc_coherent(&dev->pci->dev, el_count * el_size, ++ &q->dma_handle, GFP_KERNEL); ++ q->completion = compl; ++ q->userdata = userdata; ++ q->completion_data = kzalloc(sizeof(struct bce_sq_completion_data) * el_count, GFP_KERNEL); ++ q->reg_mem_dma = dev->reg_mem_dma; ++ atomic_set(&q->available_commands, el_count - 1); ++ init_completion(&q->available_command_completion); ++ atomic_set(&q->available_command_completion_waiting_count, 0); ++ if (!q->data) { ++ pr_err("DMA queue memory alloc failed\n"); ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_get_sq_memcfg(struct bce_queue_sq *sq, struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg) ++{ ++ cfg->qid = (u16) sq->qid; ++ cfg->el_count = (u16) sq->el_count; ++ cfg->vector_or_cq = (u16) cq->qid; ++ cfg->_pad = 0; ++ cfg->addr = sq->dma_handle; ++ cfg->length = sq->el_count * sq->el_size; ++} ++ ++void bce_free_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq) ++{ ++ dma_free_coherent(&dev->pci->dev, sq->el_count * sq->el_size, sq->data, sq->dma_handle); ++ kfree(sq); ++} ++ ++int bce_reserve_submission(struct bce_queue_sq *sq, unsigned long *timeout) ++{ ++ while (atomic_dec_if_positive(&sq->available_commands) < 0) { ++ if (!timeout || !*timeout) ++ return -EAGAIN; ++ atomic_inc(&sq->available_command_completion_waiting_count); ++ *timeout = wait_for_completion_timeout(&sq->available_command_completion, *timeout); ++ if (!*timeout) { ++ if (atomic_dec_if_positive(&sq->available_command_completion_waiting_count) < 0) ++ try_wait_for_completion(&sq->available_command_completion); /* consume the pending completion */ ++ } ++ } ++ return 0; ++} ++ ++void bce_cancel_submission_reservation(struct bce_queue_sq *sq) ++{ ++ atomic_inc(&sq->available_commands); ++} ++ ++void *bce_next_submission(struct bce_queue_sq *sq) ++{ ++ void *ret = bce_sq_element(sq, sq->tail); ++ sq->tail = (sq->tail + 1) % sq->el_count; ++ return ret; ++} ++ ++void bce_submit_to_device(struct bce_queue_sq *sq) ++{ ++ mb(); ++ iowrite32(sq->tail, (u32 *) ((u8 *) sq->reg_mem_dma + REG_DOORBELL_BASE) + sq->qid); ++} ++ ++void bce_notify_submission_complete(struct bce_queue_sq *sq) ++{ ++ sq->head = (sq->head + 1) % sq->el_count; ++ atomic_inc(&sq->available_commands); ++ if (atomic_dec_if_positive(&sq->available_command_completion_waiting_count) >= 0) { ++ complete(&sq->available_command_completion); ++ } ++} ++ ++void bce_set_submission_single(struct bce_qe_submission *element, dma_addr_t addr, size_t size) ++{ ++ element->addr = addr; ++ element->length = size; ++ element->segl_addr = element->segl_length = 0; ++} ++ ++static void bce_cmdq_completion(struct bce_queue_sq *q); ++ ++struct bce_queue_cmdq *bce_alloc_cmdq(struct apple_bce_device *dev, int qid, u32 el_count) ++{ ++ struct bce_queue_cmdq *q; ++ q = kzalloc(sizeof(struct bce_queue_cmdq), GFP_KERNEL); ++ q->sq = bce_alloc_sq(dev, qid, BCE_CMD_SIZE, el_count, bce_cmdq_completion, q); ++ if (!q->sq) { ++ kfree(q); ++ return NULL; ++ } ++ spin_lock_init(&q->lck); ++ q->tres = kzalloc(sizeof(struct bce_queue_cmdq_result_el*) * el_count, GFP_KERNEL); ++ if (!q->tres) { ++ kfree(q); ++ return NULL; ++ } ++ return q; ++} ++ ++void bce_free_cmdq(struct apple_bce_device *dev, struct bce_queue_cmdq *cmdq) ++{ ++ bce_free_sq(dev, cmdq->sq); ++ kfree(cmdq->tres); ++ kfree(cmdq); ++} ++ ++void bce_cmdq_completion(struct bce_queue_sq *q) ++{ ++ struct bce_queue_cmdq_result_el *el; ++ struct bce_queue_cmdq *cmdq = q->userdata; ++ struct bce_sq_completion_data *result; ++ ++ spin_lock(&cmdq->lck); ++ while ((result = bce_next_completion(q))) { ++ el = cmdq->tres[cmdq->sq->head]; ++ if (el) { ++ el->result = result->result; ++ el->status = result->status; ++ mb(); ++ complete(&el->cmpl); ++ } else { ++ pr_err("apple-bce: Unexpected command queue completion\n"); ++ } ++ cmdq->tres[cmdq->sq->head] = NULL; ++ bce_notify_submission_complete(q); ++ } ++ spin_unlock(&cmdq->lck); ++} ++ ++static __always_inline void *bce_cmd_start(struct bce_queue_cmdq *cmdq, struct bce_queue_cmdq_result_el *res) ++{ ++ void *ret; ++ unsigned long timeout; ++ init_completion(&res->cmpl); ++ mb(); ++ ++ timeout = msecs_to_jiffies(1000L * 60 * 5); /* wait for up to ~5 minutes */ ++ if (bce_reserve_submission(cmdq->sq, &timeout)) ++ return NULL; ++ ++ spin_lock(&cmdq->lck); ++ cmdq->tres[cmdq->sq->tail] = res; ++ ret = bce_next_submission(cmdq->sq); ++ return ret; ++} ++ ++static __always_inline void bce_cmd_finish(struct bce_queue_cmdq *cmdq, struct bce_queue_cmdq_result_el *res) ++{ ++ bce_submit_to_device(cmdq->sq); ++ spin_unlock(&cmdq->lck); ++ ++ wait_for_completion(&res->cmpl); ++ mb(); ++} ++ ++u32 bce_cmd_register_queue(struct bce_queue_cmdq *cmdq, struct bce_queue_memcfg *cfg, const char *name, bool isdirout) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_register_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_REGISTER_MEMORY_QUEUE; ++ cmd->flags = (u16) ((name ? 2 : 0) | (isdirout ? 1 : 0)); ++ cmd->qid = cfg->qid; ++ cmd->el_count = cfg->el_count; ++ cmd->vector_or_cq = cfg->vector_or_cq; ++ memset(cmd->name, 0, sizeof(cmd->name)); ++ if (name) { ++ cmd->name_len = (u16) min(strlen(name), (size_t) sizeof(cmd->name)); ++ memcpy(cmd->name, name, cmd->name_len); ++ } else { ++ cmd->name_len = 0; ++ } ++ cmd->addr = cfg->addr; ++ cmd->length = cfg->length; ++ ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++u32 bce_cmd_unregister_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_simple_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_UNREGISTER_MEMORY_QUEUE; ++ cmd->flags = 0; ++ cmd->qid = qid; ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++u32 bce_cmd_flush_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid) ++{ ++ struct bce_queue_cmdq_result_el res; ++ struct bce_cmdq_simple_memory_queue_cmd *cmd = bce_cmd_start(cmdq, &res); ++ if (!cmd) ++ return (u32) -1; ++ cmd->cmd = BCE_CMD_FLUSH_MEMORY_QUEUE; ++ cmd->flags = 0; ++ cmd->qid = qid; ++ bce_cmd_finish(cmdq, &res); ++ return res.status; ++} ++ ++ ++struct bce_queue_cq *bce_create_cq(struct apple_bce_device *dev, u32 el_count) ++{ ++ struct bce_queue_cq *cq; ++ struct bce_queue_memcfg cfg; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ int qid = ida_simple_get(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX, GFP_KERNEL); ++#else ++ int qid = ida_alloc_range(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX - 1, GFP_KERNEL); ++#endif ++ if (qid < 0) ++ return NULL; ++ cq = bce_alloc_cq(dev, qid, el_count); ++ if (!cq) ++ return NULL; ++ bce_get_cq_memcfg(cq, &cfg); ++ if (bce_cmd_register_queue(dev->cmd_cmdq, &cfg, NULL, false) != 0) { ++ pr_err("apple-bce: CQ registration failed (%i)", qid); ++ bce_free_cq(dev, cq); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ ida_simple_remove(&dev->queue_ida, (uint) qid); ++#else ++ ida_free(&dev->queue_ida, (uint) qid); ++#endif ++ return NULL; ++ } ++ dev->queues[qid] = (struct bce_queue *) cq; ++ return cq; ++} ++ ++struct bce_queue_sq *bce_create_sq(struct apple_bce_device *dev, struct bce_queue_cq *cq, const char *name, u32 el_count, ++ int direction, bce_sq_completion compl, void *userdata) ++{ ++ struct bce_queue_sq *sq; ++ struct bce_queue_memcfg cfg; ++ int qid; ++ if (cq == NULL) ++ return NULL; /* cq can not be null */ ++ if (name == NULL) ++ return NULL; /* name can not be null */ ++ if (direction != DMA_TO_DEVICE && direction != DMA_FROM_DEVICE) ++ return NULL; /* unsupported direction */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ qid = ida_simple_get(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX, GFP_KERNEL); ++#else ++ qid = ida_alloc_range(&dev->queue_ida, BCE_QUEUE_USER_MIN, BCE_QUEUE_USER_MAX - 1, GFP_KERNEL); ++#endif ++ if (qid < 0) ++ return NULL; ++ sq = bce_alloc_sq(dev, qid, sizeof(struct bce_qe_submission), el_count, compl, userdata); ++ if (!sq) ++ return NULL; ++ bce_get_sq_memcfg(sq, cq, &cfg); ++ if (bce_cmd_register_queue(dev->cmd_cmdq, &cfg, name, direction != DMA_FROM_DEVICE) != 0) { ++ pr_err("apple-bce: SQ registration failed (%i)", qid); ++ bce_free_sq(dev, sq); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ ida_simple_remove(&dev->queue_ida, (uint) qid); ++#else ++ ida_free(&dev->queue_ida, (uint) qid); ++#endif ++ return NULL; ++ } ++ spin_lock(&dev->queues_lock); ++ dev->queues[qid] = (struct bce_queue *) sq; ++ spin_unlock(&dev->queues_lock); ++ return sq; ++} ++ ++void bce_destroy_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq) ++{ ++ if (!dev->is_being_removed && bce_cmd_unregister_memory_queue(dev->cmd_cmdq, (u16) cq->qid)) ++ pr_err("apple-bce: CQ unregister failed"); ++ spin_lock(&dev->queues_lock); ++ dev->queues[cq->qid] = NULL; ++ spin_unlock(&dev->queues_lock); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ ida_simple_remove(&dev->queue_ida, (uint) cq->qid); ++#else ++ ida_free(&dev->queue_ida, (uint) cq->qid); ++#endif ++ bce_free_cq(dev, cq); ++} ++ ++void bce_destroy_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq) ++{ ++ if (!dev->is_being_removed && bce_cmd_unregister_memory_queue(dev->cmd_cmdq, (u16) sq->qid)) ++ pr_err("apple-bce: CQ unregister failed"); ++ spin_lock(&dev->queues_lock); ++ dev->queues[sq->qid] = NULL; ++ spin_unlock(&dev->queues_lock); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0) ++ ida_simple_remove(&dev->queue_ida, (uint) sq->qid); ++#else ++ ida_free(&dev->queue_ida, (uint) sq->qid); ++#endif ++ bce_free_sq(dev, sq); ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/queue.h b/drivers/staging/apple-bce/queue.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue.h +@@ -0,0 +1,177 @@ ++#ifndef BCE_QUEUE_H ++#define BCE_QUEUE_H ++ ++#include ++#include ++ ++#define BCE_CMD_SIZE 0x40 ++ ++struct apple_bce_device; ++ ++enum bce_queue_type { ++ BCE_QUEUE_CQ, BCE_QUEUE_SQ ++}; ++struct bce_queue { ++ int qid; ++ int type; ++}; ++struct bce_queue_cq { ++ int qid; ++ int type; ++ u32 el_count; ++ dma_addr_t dma_handle; ++ void *data; ++ ++ u32 index; ++}; ++struct bce_queue_sq; ++typedef void (*bce_sq_completion)(struct bce_queue_sq *q); ++struct bce_sq_completion_data { ++ u32 status; ++ u64 data_size; ++ u64 result; ++}; ++struct bce_queue_sq { ++ int qid; ++ int type; ++ u32 el_size; ++ u32 el_count; ++ dma_addr_t dma_handle; ++ void *data; ++ void *userdata; ++ void __iomem *reg_mem_dma; ++ ++ atomic_t available_commands; ++ struct completion available_command_completion; ++ atomic_t available_command_completion_waiting_count; ++ u32 head, tail; ++ ++ u32 completion_cidx, completion_tail; ++ struct bce_sq_completion_data *completion_data; ++ bool has_pending_completions; ++ bce_sq_completion completion; ++}; ++ ++struct bce_queue_cmdq_result_el { ++ struct completion cmpl; ++ u32 status; ++ u64 result; ++}; ++struct bce_queue_cmdq { ++ struct bce_queue_sq *sq; ++ struct spinlock lck; ++ struct bce_queue_cmdq_result_el **tres; ++}; ++ ++struct bce_queue_memcfg { ++ u16 qid; ++ u16 el_count; ++ u16 vector_or_cq; ++ u16 _pad; ++ u64 addr; ++ u64 length; ++}; ++ ++enum bce_qe_completion_status { ++ BCE_COMPLETION_SUCCESS = 0, ++ BCE_COMPLETION_ERROR = 1, ++ BCE_COMPLETION_ABORTED = 2, ++ BCE_COMPLETION_NO_SPACE = 3, ++ BCE_COMPLETION_OVERRUN = 4 ++}; ++enum bce_qe_completion_flags { ++ BCE_COMPLETION_FLAG_PENDING = 0x8000 ++}; ++struct bce_qe_completion { ++ u64 result; ++ u64 data_size; ++ u16 qid; ++ u16 completion_index; ++ u16 status; // bce_qe_completion_status ++ u16 flags; // bce_qe_completion_flags ++}; ++ ++struct bce_qe_submission { ++ u64 length; ++ u64 addr; ++ ++ u64 segl_addr; ++ u64 segl_length; ++}; ++ ++enum bce_cmdq_command { ++ BCE_CMD_REGISTER_MEMORY_QUEUE = 0x20, ++ BCE_CMD_UNREGISTER_MEMORY_QUEUE = 0x30, ++ BCE_CMD_FLUSH_MEMORY_QUEUE = 0x40, ++ BCE_CMD_SET_MEMORY_QUEUE_PROPERTY = 0x50 ++}; ++struct bce_cmdq_simple_memory_queue_cmd { ++ u16 cmd; // bce_cmdq_command ++ u16 flags; ++ u16 qid; ++}; ++struct bce_cmdq_register_memory_queue_cmd { ++ u16 cmd; // bce_cmdq_command ++ u16 flags; ++ u16 qid; ++ u16 _pad; ++ u16 el_count; ++ u16 vector_or_cq; ++ u16 _pad2; ++ u16 name_len; ++ char name[0x20]; ++ u64 addr; ++ u64 length; ++}; ++ ++static __always_inline void *bce_sq_element(struct bce_queue_sq *q, int i) { ++ return (void *) ((u8 *) q->data + q->el_size * i); ++} ++static __always_inline void *bce_cq_element(struct bce_queue_cq *q, int i) { ++ return (void *) ((struct bce_qe_completion *) q->data + i); ++} ++ ++static __always_inline struct bce_sq_completion_data *bce_next_completion(struct bce_queue_sq *sq) { ++ struct bce_sq_completion_data *res; ++ rmb(); ++ if (sq->completion_cidx == sq->completion_tail) ++ return NULL; ++ res = &sq->completion_data[sq->completion_cidx]; ++ sq->completion_cidx = (sq->completion_cidx + 1) % sq->el_count; ++ return res; ++} ++ ++struct bce_queue_cq *bce_alloc_cq(struct apple_bce_device *dev, int qid, u32 el_count); ++void bce_get_cq_memcfg(struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg); ++void bce_free_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++void bce_handle_cq_completions(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++ ++struct bce_queue_sq *bce_alloc_sq(struct apple_bce_device *dev, int qid, u32 el_size, u32 el_count, ++ bce_sq_completion compl, void *userdata); ++void bce_get_sq_memcfg(struct bce_queue_sq *sq, struct bce_queue_cq *cq, struct bce_queue_memcfg *cfg); ++void bce_free_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq); ++int bce_reserve_submission(struct bce_queue_sq *sq, unsigned long *timeout); ++void bce_cancel_submission_reservation(struct bce_queue_sq *sq); ++void *bce_next_submission(struct bce_queue_sq *sq); ++void bce_submit_to_device(struct bce_queue_sq *sq); ++void bce_notify_submission_complete(struct bce_queue_sq *sq); ++ ++void bce_set_submission_single(struct bce_qe_submission *element, dma_addr_t addr, size_t size); ++ ++struct bce_queue_cmdq *bce_alloc_cmdq(struct apple_bce_device *dev, int qid, u32 el_count); ++void bce_free_cmdq(struct apple_bce_device *dev, struct bce_queue_cmdq *cmdq); ++ ++u32 bce_cmd_register_queue(struct bce_queue_cmdq *cmdq, struct bce_queue_memcfg *cfg, const char *name, bool isdirout); ++u32 bce_cmd_unregister_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid); ++u32 bce_cmd_flush_memory_queue(struct bce_queue_cmdq *cmdq, u16 qid); ++ ++ ++/* User API - Creates and registers the queue */ ++ ++struct bce_queue_cq *bce_create_cq(struct apple_bce_device *dev, u32 el_count); ++struct bce_queue_sq *bce_create_sq(struct apple_bce_device *dev, struct bce_queue_cq *cq, const char *name, u32 el_count, ++ int direction, bce_sq_completion compl, void *userdata); ++void bce_destroy_cq(struct apple_bce_device *dev, struct bce_queue_cq *cq); ++void bce_destroy_sq(struct apple_bce_device *dev, struct bce_queue_sq *sq); ++ ++#endif //BCEDRIVER_MAILBOX_H +diff --git a/drivers/staging/apple-bce/queue_dma.c b/drivers/staging/apple-bce/queue_dma.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue_dma.c +@@ -0,0 +1,220 @@ ++#include "queue_dma.h" ++#include ++#include ++#include "queue.h" ++ ++static int bce_alloc_scatterlist_from_vm(struct sg_table *tbl, void *data, size_t len); ++static struct bce_segment_list_element_hostinfo *bce_map_segment_list( ++ struct device *dev, struct scatterlist *pages, int pagen); ++static void bce_unmap_segement_list(struct device *dev, struct bce_segment_list_element_hostinfo *list); ++ ++int bce_map_dma_buffer(struct device *dev, struct bce_dma_buffer *buf, struct sg_table scatterlist, ++ enum dma_data_direction dir) ++{ ++ int cnt; ++ ++ buf->direction = dir; ++ buf->scatterlist = scatterlist; ++ buf->seglist_hostinfo = NULL; ++ ++ cnt = dma_map_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ if (cnt != buf->scatterlist.nents) { ++ pr_err("apple-bce: DMA scatter list mapping returned an unexpected count: %i\n", cnt); ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ return -EIO; ++ } ++ if (cnt == 1) ++ return 0; ++ ++ buf->seglist_hostinfo = bce_map_segment_list(dev, buf->scatterlist.sgl, buf->scatterlist.nents); ++ if (!buf->seglist_hostinfo) { ++ pr_err("apple-bce: Creating segment list failed\n"); ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, dir); ++ return -EIO; ++ } ++ return 0; ++} ++ ++int bce_map_dma_buffer_vm(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir) ++{ ++ int status; ++ struct sg_table scatterlist; ++ if ((status = bce_alloc_scatterlist_from_vm(&scatterlist, data, len))) ++ return status; ++ if ((status = bce_map_dma_buffer(dev, buf, scatterlist, dir))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ return 0; ++} ++ ++int bce_map_dma_buffer_km(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir) ++{ ++ /* Kernel memory is continuous which is great for us. */ ++ int status; ++ struct sg_table scatterlist; ++ if ((status = sg_alloc_table(&scatterlist, 1, GFP_KERNEL))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ sg_set_buf(scatterlist.sgl, data, (uint) len); ++ if ((status = bce_map_dma_buffer(dev, buf, scatterlist, dir))) { ++ sg_free_table(&scatterlist); ++ return status; ++ } ++ return 0; ++} ++ ++void bce_unmap_dma_buffer(struct device *dev, struct bce_dma_buffer *buf) ++{ ++ dma_unmap_sg(dev, buf->scatterlist.sgl, buf->scatterlist.nents, buf->direction); ++ bce_unmap_segement_list(dev, buf->seglist_hostinfo); ++} ++ ++ ++static int bce_alloc_scatterlist_from_vm(struct sg_table *tbl, void *data, size_t len) ++{ ++ int status, i; ++ struct page **pages; ++ size_t off, start_page, end_page, page_count; ++ off = (size_t) data % PAGE_SIZE; ++ start_page = (size_t) data / PAGE_SIZE; ++ end_page = ((size_t) data + len - 1) / PAGE_SIZE; ++ page_count = end_page - start_page + 1; ++ ++ if (page_count > PAGE_SIZE / sizeof(struct page *)) ++ pages = vmalloc(page_count * sizeof(struct page *)); ++ else ++ pages = kmalloc(page_count * sizeof(struct page *), GFP_KERNEL); ++ ++ for (i = 0; i < page_count; i++) ++ pages[i] = vmalloc_to_page((void *) ((start_page + i) * PAGE_SIZE)); ++ ++ if ((status = sg_alloc_table_from_pages(tbl, pages, page_count, (unsigned int) off, len, GFP_KERNEL))) { ++ sg_free_table(tbl); ++ } ++ ++ if (page_count > PAGE_SIZE / sizeof(struct page *)) ++ vfree(pages); ++ else ++ kfree(pages); ++ return status; ++} ++ ++#define BCE_ELEMENTS_PER_PAGE ((PAGE_SIZE - sizeof(struct bce_segment_list_header)) \ ++ / sizeof(struct bce_segment_list_element)) ++#define BCE_ELEMENTS_PER_ADDITIONAL_PAGE (PAGE_SIZE / sizeof(struct bce_segment_list_element)) ++ ++static struct bce_segment_list_element_hostinfo *bce_map_segment_list( ++ struct device *dev, struct scatterlist *pages, int pagen) ++{ ++ size_t ptr, pptr = 0; ++ struct bce_segment_list_header theader; /* a temp header, to store the initial seg */ ++ struct bce_segment_list_header *header; ++ struct bce_segment_list_element *el, *el_end; ++ struct bce_segment_list_element_hostinfo *out, *pout, *out_root; ++ struct scatterlist *sg; ++ int i; ++ header = &theader; ++ out = out_root = NULL; ++ el = el_end = NULL; ++ for_each_sg(pages, sg, pagen, i) { ++ if (el >= el_end) { ++ /* allocate a new page, this will be also done for the first element */ ++ ptr = __get_free_page(GFP_KERNEL); ++ if (pptr && ptr == pptr + PAGE_SIZE) { ++ out->page_count++; ++ header->element_count += BCE_ELEMENTS_PER_ADDITIONAL_PAGE; ++ el_end += BCE_ELEMENTS_PER_ADDITIONAL_PAGE; ++ } else { ++ header = (void *) ptr; ++ header->element_count = BCE_ELEMENTS_PER_PAGE; ++ header->data_size = 0; ++ header->next_segl_addr = 0; ++ header->next_segl_length = 0; ++ el = (void *) (header + 1); ++ el_end = el + BCE_ELEMENTS_PER_PAGE; ++ ++ if (out) { ++ out->next = kmalloc(sizeof(struct bce_segment_list_element_hostinfo), GFP_KERNEL); ++ out = out->next; ++ } else { ++ out_root = out = kmalloc(sizeof(struct bce_segment_list_element_hostinfo), GFP_KERNEL); ++ } ++ out->page_start = (void *) ptr; ++ out->page_count = 1; ++ out->dma_start = DMA_MAPPING_ERROR; ++ out->next = NULL; ++ } ++ pptr = ptr; ++ } ++ el->addr = sg->dma_address; ++ el->length = sg->length; ++ header->data_size += el->length; ++ } ++ ++ /* DMA map */ ++ out = out_root; ++ pout = NULL; ++ while (out) { ++ out->dma_start = dma_map_single(dev, out->page_start, out->page_count * PAGE_SIZE, DMA_TO_DEVICE); ++ if (dma_mapping_error(dev, out->dma_start)) ++ goto error; ++ if (pout) { ++ header = pout->page_start; ++ header->next_segl_addr = out->dma_start; ++ header->next_segl_length = out->page_count * PAGE_SIZE; ++ } ++ pout = out; ++ out = out->next; ++ } ++ return out_root; ++ ++ error: ++ bce_unmap_segement_list(dev, out_root); ++ return NULL; ++} ++ ++static void bce_unmap_segement_list(struct device *dev, struct bce_segment_list_element_hostinfo *list) ++{ ++ struct bce_segment_list_element_hostinfo *next; ++ while (list) { ++ if (list->dma_start != DMA_MAPPING_ERROR) ++ dma_unmap_single(dev, list->dma_start, list->page_count * PAGE_SIZE, DMA_TO_DEVICE); ++ next = list->next; ++ kfree(list); ++ list = next; ++ } ++} ++ ++int bce_set_submission_buf(struct bce_qe_submission *element, struct bce_dma_buffer *buf, size_t offset, size_t length) ++{ ++ struct bce_segment_list_element_hostinfo *seg; ++ struct bce_segment_list_header *seg_header; ++ ++ seg = buf->seglist_hostinfo; ++ if (!seg) { ++ element->addr = buf->scatterlist.sgl->dma_address + offset; ++ element->length = length; ++ element->segl_addr = 0; ++ element->segl_length = 0; ++ return 0; ++ } ++ ++ while (seg) { ++ seg_header = seg->page_start; ++ if (offset <= seg_header->data_size) ++ break; ++ offset -= seg_header->data_size; ++ seg = seg->next; ++ } ++ if (!seg) ++ return -EINVAL; ++ element->addr = offset; ++ element->length = buf->scatterlist.sgl->dma_length; ++ element->segl_addr = seg->dma_start; ++ element->segl_length = seg->page_count * PAGE_SIZE; ++ return 0; ++} +\ No newline at end of file +diff --git a/drivers/staging/apple-bce/queue_dma.h b/drivers/staging/apple-bce/queue_dma.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/queue_dma.h +@@ -0,0 +1,50 @@ ++#ifndef BCE_QUEUE_DMA_H ++#define BCE_QUEUE_DMA_H ++ ++#include ++ ++struct bce_qe_submission; ++ ++struct bce_segment_list_header { ++ u64 element_count; ++ u64 data_size; ++ ++ u64 next_segl_addr; ++ u64 next_segl_length; ++}; ++struct bce_segment_list_element { ++ u64 addr; ++ u64 length; ++}; ++ ++struct bce_segment_list_element_hostinfo { ++ struct bce_segment_list_element_hostinfo *next; ++ void *page_start; ++ size_t page_count; ++ dma_addr_t dma_start; ++}; ++ ++ ++struct bce_dma_buffer { ++ enum dma_data_direction direction; ++ struct sg_table scatterlist; ++ struct bce_segment_list_element_hostinfo *seglist_hostinfo; ++}; ++ ++/* NOTE: Takes ownership of the sg_table if it succeeds. Ownership is not transferred on failure. */ ++int bce_map_dma_buffer(struct device *dev, struct bce_dma_buffer *buf, struct sg_table scatterlist, ++ enum dma_data_direction dir); ++ ++/* Creates a buffer from virtual memory (vmalloc) */ ++int bce_map_dma_buffer_vm(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir); ++ ++/* Creates a buffer from kernel memory (kmalloc) */ ++int bce_map_dma_buffer_km(struct device *dev, struct bce_dma_buffer *buf, void *data, size_t len, ++ enum dma_data_direction dir); ++ ++void bce_unmap_dma_buffer(struct device *dev, struct bce_dma_buffer *buf); ++ ++int bce_set_submission_buf(struct bce_qe_submission *element, struct bce_dma_buffer *buf, size_t offset, size_t length); ++ ++#endif //BCE_QUEUE_DMA_H +diff --git a/drivers/staging/apple-bce/vhci/command.h b/drivers/staging/apple-bce/vhci/command.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/command.h +@@ -0,0 +1,204 @@ ++#ifndef BCE_VHCI_COMMAND_H ++#define BCE_VHCI_COMMAND_H ++ ++#include "queue.h" ++#include ++#include ++ ++#define BCE_VHCI_CMD_TIMEOUT_SHORT msecs_to_jiffies(2000) ++#define BCE_VHCI_CMD_TIMEOUT_LONG msecs_to_jiffies(30000) ++ ++#define BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2 2 ++#define BCE_VHCI_BULK_MAX_ACTIVE_URBS (1 << BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2) ++ ++typedef u8 bce_vhci_port_t; ++typedef u8 bce_vhci_device_t; ++ ++enum bce_vhci_command { ++ BCE_VHCI_CMD_CONTROLLER_ENABLE = 1, ++ BCE_VHCI_CMD_CONTROLLER_DISABLE = 2, ++ BCE_VHCI_CMD_CONTROLLER_START = 3, ++ BCE_VHCI_CMD_CONTROLLER_PAUSE = 4, ++ ++ BCE_VHCI_CMD_PORT_POWER_ON = 0x10, ++ BCE_VHCI_CMD_PORT_POWER_OFF = 0x11, ++ BCE_VHCI_CMD_PORT_RESUME = 0x12, ++ BCE_VHCI_CMD_PORT_SUSPEND = 0x13, ++ BCE_VHCI_CMD_PORT_RESET = 0x14, ++ BCE_VHCI_CMD_PORT_DISABLE = 0x15, ++ BCE_VHCI_CMD_PORT_STATUS = 0x16, ++ ++ BCE_VHCI_CMD_DEVICE_CREATE = 0x30, ++ BCE_VHCI_CMD_DEVICE_DESTROY = 0x31, ++ ++ BCE_VHCI_CMD_ENDPOINT_CREATE = 0x40, ++ BCE_VHCI_CMD_ENDPOINT_DESTROY = 0x41, ++ BCE_VHCI_CMD_ENDPOINT_SET_STATE = 0x42, ++ BCE_VHCI_CMD_ENDPOINT_RESET = 0x44, ++ ++ /* Device to host only */ ++ BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE = 0x43, ++ BCE_VHCI_CMD_TRANSFER_REQUEST = 0x1000, ++ BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS = 0x1005 ++}; ++ ++enum bce_vhci_endpoint_state { ++ BCE_VHCI_ENDPOINT_ACTIVE = 0, ++ BCE_VHCI_ENDPOINT_PAUSED = 1, ++ BCE_VHCI_ENDPOINT_STALLED = 2 ++}; ++ ++static inline int bce_vhci_cmd_controller_enable(struct bce_vhci_command_queue *q, u8 busNum, u16 *portMask) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_ENABLE; ++ cmd.param1 = 0x7100u | busNum; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++ if (!status) ++ *portMask = (u16) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_controller_disable(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_DISABLE; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_controller_start(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_START; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_controller_pause(struct bce_vhci_command_queue *q) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_CONTROLLER_PAUSE; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++ ++static inline int bce_vhci_cmd_port_power_on(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_POWER_ON; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_power_off(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_POWER_OFF; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_resume(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_RESUME; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_port_suspend(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_SUSPEND; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++static inline int bce_vhci_cmd_port_reset(struct bce_vhci_command_queue *q, bce_vhci_port_t port, u32 timeout) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_RESET; ++ cmd.param1 = port; ++ cmd.param2 = timeout; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_disable(struct bce_vhci_command_queue *q, bce_vhci_port_t port) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_DISABLE; ++ cmd.param1 = port; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_port_status(struct bce_vhci_command_queue *q, bce_vhci_port_t port, ++ u32 clearFlags, u32 *resStatus) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_PORT_STATUS; ++ cmd.param1 = port; ++ cmd.param2 = clearFlags & 0x560000; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (status >= 0) ++ *resStatus = (u32) res.param2; ++ return status; ++} ++ ++static inline int bce_vhci_cmd_device_create(struct bce_vhci_command_queue *q, bce_vhci_port_t port, ++ bce_vhci_device_t *dev) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_DEVICE_CREATE; ++ cmd.param1 = port; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (!status) ++ *dev = (bce_vhci_device_t) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_device_destroy(struct bce_vhci_command_queue *q, bce_vhci_device_t dev) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_DEVICE_DESTROY; ++ cmd.param1 = dev; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_LONG); ++} ++ ++static inline int bce_vhci_cmd_endpoint_create(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, ++ struct usb_endpoint_descriptor *desc) ++{ ++ struct bce_vhci_message cmd, res; ++ int endpoint_type = usb_endpoint_type(desc); ++ int maxp = usb_endpoint_maxp(desc); ++ int maxp_burst = usb_endpoint_maxp_mult(desc) * maxp; ++ u8 max_active_requests_pow2 = 0; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_CREATE; ++ cmd.param1 = dev | ((desc->bEndpointAddress & 0x8Fu) << 8); ++ if (endpoint_type == USB_ENDPOINT_XFER_BULK) ++ max_active_requests_pow2 = BCE_VHCI_BULK_MAX_ACTIVE_URBS_POW2; ++ cmd.param2 = endpoint_type | ((max_active_requests_pow2 & 0xf) << 4) | (maxp << 16) | ((u64) maxp_burst << 32); ++ if (endpoint_type == USB_ENDPOINT_XFER_INT) ++ cmd.param2 |= (desc->bInterval - 1) << 8; ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_endpoint_destroy(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_DESTROY; ++ cmd.param1 = dev | (endpoint << 8); ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++static inline int bce_vhci_cmd_endpoint_set_state(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint, ++ enum bce_vhci_endpoint_state newState, enum bce_vhci_endpoint_state *retState) ++{ ++ int status; ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_SET_STATE; ++ cmd.param1 = dev | (endpoint << 8); ++ cmd.param2 = (u64) newState; ++ status = bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++ if (status != BCE_VHCI_INTERNAL_ERROR && status != BCE_VHCI_NO_POWER) ++ *retState = (enum bce_vhci_endpoint_state) res.param2; ++ return status; ++} ++static inline int bce_vhci_cmd_endpoint_reset(struct bce_vhci_command_queue *q, bce_vhci_device_t dev, u8 endpoint) ++{ ++ struct bce_vhci_message cmd, res; ++ cmd.cmd = BCE_VHCI_CMD_ENDPOINT_RESET; ++ cmd.param1 = dev | (endpoint << 8); ++ return bce_vhci_command_queue_execute(q, &cmd, &res, BCE_VHCI_CMD_TIMEOUT_SHORT); ++} ++ ++ ++#endif //BCE_VHCI_COMMAND_H +diff --git a/drivers/staging/apple-bce/vhci/queue.c b/drivers/staging/apple-bce/vhci/queue.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/queue.c +@@ -0,0 +1,268 @@ ++#include "queue.h" ++#include "vhci.h" ++#include "../apple_bce.h" ++ ++ ++static void bce_vhci_message_queue_completion(struct bce_queue_sq *sq); ++ ++int bce_vhci_message_queue_create(struct bce_vhci *vhci, struct bce_vhci_message_queue *ret, const char *name) ++{ ++ int status; ++ ret->cq = bce_create_cq(vhci->dev, VHCI_EVENT_QUEUE_EL_COUNT); ++ if (!ret->cq) ++ return -EINVAL; ++ ret->sq = bce_create_sq(vhci->dev, ret->cq, name, VHCI_EVENT_QUEUE_EL_COUNT, DMA_TO_DEVICE, ++ bce_vhci_message_queue_completion, ret); ++ if (!ret->sq) { ++ status = -EINVAL; ++ goto fail_cq; ++ } ++ ret->data = dma_alloc_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ &ret->dma_addr, GFP_KERNEL); ++ if (!ret->data) { ++ status = -EINVAL; ++ goto fail_sq; ++ } ++ return 0; ++ ++fail_sq: ++ bce_destroy_sq(vhci->dev, ret->sq); ++ ret->sq = NULL; ++fail_cq: ++ bce_destroy_cq(vhci->dev, ret->cq); ++ ret->cq = NULL; ++ return status; ++} ++ ++void bce_vhci_message_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_message_queue *q) ++{ ++ if (!q->cq) ++ return; ++ dma_free_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ q->data, q->dma_addr); ++ bce_destroy_sq(vhci->dev, q->sq); ++ bce_destroy_cq(vhci->dev, q->cq); ++} ++ ++void bce_vhci_message_queue_write(struct bce_vhci_message_queue *q, struct bce_vhci_message *req) ++{ ++ int sidx; ++ struct bce_qe_submission *s; ++ sidx = q->sq->tail; ++ s = bce_next_submission(q->sq); ++ pr_debug("bce-vhci: Send message: %x s=%x p1=%x p2=%llx\n", req->cmd, req->status, req->param1, req->param2); ++ q->data[sidx] = *req; ++ bce_set_submission_single(s, q->dma_addr + sizeof(struct bce_vhci_message) * sidx, ++ sizeof(struct bce_vhci_message)); ++ bce_submit_to_device(q->sq); ++} ++ ++static void bce_vhci_message_queue_completion(struct bce_queue_sq *sq) ++{ ++ while (bce_next_completion(sq)) ++ bce_notify_submission_complete(sq); ++} ++ ++ ++ ++static void bce_vhci_event_queue_completion(struct bce_queue_sq *sq); ++ ++int __bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_sq_completion compl) ++{ ++ ret->vhci = vhci; ++ ++ ret->sq = bce_create_sq(vhci->dev, vhci->ev_cq, name, VHCI_EVENT_QUEUE_EL_COUNT, DMA_FROM_DEVICE, compl, ret); ++ if (!ret->sq) ++ return -EINVAL; ++ ret->data = dma_alloc_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ &ret->dma_addr, GFP_KERNEL); ++ if (!ret->data) { ++ bce_destroy_sq(vhci->dev, ret->sq); ++ ret->sq = NULL; ++ return -EINVAL; ++ } ++ ++ init_completion(&ret->queue_empty_completion); ++ bce_vhci_event_queue_submit_pending(ret, VHCI_EVENT_PENDING_COUNT); ++ return 0; ++} ++ ++int bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_vhci_event_queue_callback cb) ++{ ++ ret->cb = cb; ++ return __bce_vhci_event_queue_create(vhci, ret, name, bce_vhci_event_queue_completion); ++} ++ ++void bce_vhci_event_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_event_queue *q) ++{ ++ if (!q->sq) ++ return; ++ dma_free_coherent(&vhci->dev->pci->dev, sizeof(struct bce_vhci_message) * VHCI_EVENT_QUEUE_EL_COUNT, ++ q->data, q->dma_addr); ++ bce_destroy_sq(vhci->dev, q->sq); ++} ++ ++static void bce_vhci_event_queue_completion(struct bce_queue_sq *sq) ++{ ++ struct bce_sq_completion_data *cd; ++ struct bce_vhci_event_queue *ev = sq->userdata; ++ struct bce_vhci_message *msg; ++ size_t cnt = 0; ++ ++ while ((cd = bce_next_completion(sq))) { ++ if (cd->status == BCE_COMPLETION_ABORTED) { /* We flushed the queue */ ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ msg = &ev->data[sq->head]; ++ pr_debug("bce-vhci: Got event: %x s=%x p1=%x p2=%llx\n", msg->cmd, msg->status, msg->param1, msg->param2); ++ ev->cb(ev, msg); ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ bce_vhci_event_queue_submit_pending(ev, cnt); ++ if (atomic_read(&sq->available_commands) == sq->el_count - 1) ++ complete(&ev->queue_empty_completion); ++} ++ ++void bce_vhci_event_queue_submit_pending(struct bce_vhci_event_queue *q, size_t count) ++{ ++ int idx; ++ struct bce_qe_submission *s; ++ while (count--) { ++ if (bce_reserve_submission(q->sq, NULL)) { ++ pr_err("bce-vhci: Failed to reserve an event queue submission\n"); ++ break; ++ } ++ idx = q->sq->tail; ++ s = bce_next_submission(q->sq); ++ bce_set_submission_single(s, ++ q->dma_addr + idx * sizeof(struct bce_vhci_message), sizeof(struct bce_vhci_message)); ++ } ++ bce_submit_to_device(q->sq); ++} ++ ++void bce_vhci_event_queue_pause(struct bce_vhci_event_queue *q) ++{ ++ unsigned long timeout; ++ reinit_completion(&q->queue_empty_completion); ++ if (bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, q->sq->qid)) ++ pr_warn("bce-vhci: failed to flush event queue\n"); ++ timeout = msecs_to_jiffies(5000); ++ while (atomic_read(&q->sq->available_commands) != q->sq->el_count - 1) { ++ timeout = wait_for_completion_timeout(&q->queue_empty_completion, timeout); ++ if (timeout == 0) { ++ pr_err("bce-vhci: waiting for queue to be flushed timed out\n"); ++ break; ++ } ++ } ++} ++ ++void bce_vhci_event_queue_resume(struct bce_vhci_event_queue *q) ++{ ++ if (atomic_read(&q->sq->available_commands) != q->sq->el_count - 1) { ++ pr_err("bce-vhci: resume of a queue with pending submissions\n"); ++ return; ++ } ++ bce_vhci_event_queue_submit_pending(q, VHCI_EVENT_PENDING_COUNT); ++} ++ ++void bce_vhci_command_queue_create(struct bce_vhci_command_queue *ret, struct bce_vhci_message_queue *mq) ++{ ++ ret->mq = mq; ++ ret->completion.result = NULL; ++ init_completion(&ret->completion.completion); ++ spin_lock_init(&ret->completion_lock); ++ mutex_init(&ret->mutex); ++} ++ ++void bce_vhci_command_queue_destroy(struct bce_vhci_command_queue *cq) ++{ ++ spin_lock(&cq->completion_lock); ++ if (cq->completion.result) { ++ memset(cq->completion.result, 0, sizeof(struct bce_vhci_message)); ++ cq->completion.result->status = BCE_VHCI_ABORT; ++ complete(&cq->completion.completion); ++ cq->completion.result = NULL; ++ } ++ spin_unlock(&cq->completion_lock); ++ mutex_lock(&cq->mutex); ++ mutex_unlock(&cq->mutex); ++ mutex_destroy(&cq->mutex); ++} ++ ++void bce_vhci_command_queue_deliver_completion(struct bce_vhci_command_queue *cq, struct bce_vhci_message *msg) ++{ ++ struct bce_vhci_command_queue_completion *c = &cq->completion; ++ ++ spin_lock(&cq->completion_lock); ++ if (c->result) { ++ *c->result = *msg; ++ complete(&c->completion); ++ c->result = NULL; ++ } ++ spin_unlock(&cq->completion_lock); ++} ++ ++static int __bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout) ++{ ++ int status; ++ struct bce_vhci_command_queue_completion *c; ++ struct bce_vhci_message creq; ++ c = &cq->completion; ++ ++ if ((status = bce_reserve_submission(cq->mq->sq, &timeout))) ++ return status; ++ ++ spin_lock(&cq->completion_lock); ++ c->result = res; ++ reinit_completion(&c->completion); ++ spin_unlock(&cq->completion_lock); ++ ++ bce_vhci_message_queue_write(cq->mq, req); ++ ++ if (!wait_for_completion_timeout(&c->completion, timeout)) { ++ /* we ran out of time, send cancellation */ ++ pr_debug("bce-vhci: command timed out req=%x\n", req->cmd); ++ if ((status = bce_reserve_submission(cq->mq->sq, &timeout))) ++ return status; ++ ++ creq = *req; ++ creq.cmd |= 0x4000; ++ bce_vhci_message_queue_write(cq->mq, &creq); ++ ++ if (!wait_for_completion_timeout(&c->completion, 1000)) { ++ pr_err("bce-vhci: Possible desync, cmd cancel timed out\n"); ++ ++ spin_lock(&cq->completion_lock); ++ c->result = NULL; ++ spin_unlock(&cq->completion_lock); ++ return -ETIMEDOUT; ++ } ++ if ((res->cmd & ~0x8000) == creq.cmd) ++ return -ETIMEDOUT; ++ /* reply for the previous command most likely arrived */ ++ } ++ ++ if ((res->cmd & ~0x8000) != req->cmd) { ++ pr_err("bce-vhci: Possible desync, cmd reply mismatch req=%x, res=%x\n", req->cmd, res->cmd); ++ return -EIO; ++ } ++ if (res->status == BCE_VHCI_SUCCESS) ++ return 0; ++ return res->status; ++} ++ ++int bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout) ++{ ++ int status; ++ mutex_lock(&cq->mutex); ++ status = __bce_vhci_command_queue_execute(cq, req, res, timeout); ++ mutex_unlock(&cq->mutex); ++ return status; ++} +diff --git a/drivers/staging/apple-bce/vhci/queue.h b/drivers/staging/apple-bce/vhci/queue.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/queue.h +@@ -0,0 +1,76 @@ ++#ifndef BCE_VHCI_QUEUE_H ++#define BCE_VHCI_QUEUE_H ++ ++#include ++#include "../queue.h" ++ ++#define VHCI_EVENT_QUEUE_EL_COUNT 256 ++#define VHCI_EVENT_PENDING_COUNT 32 ++ ++struct bce_vhci; ++struct bce_vhci_event_queue; ++ ++enum bce_vhci_message_status { ++ BCE_VHCI_SUCCESS = 1, ++ BCE_VHCI_ERROR = 2, ++ BCE_VHCI_USB_PIPE_STALL = 3, ++ BCE_VHCI_ABORT = 4, ++ BCE_VHCI_BAD_ARGUMENT = 5, ++ BCE_VHCI_OVERRUN = 6, ++ BCE_VHCI_INTERNAL_ERROR = 7, ++ BCE_VHCI_NO_POWER = 8, ++ BCE_VHCI_UNSUPPORTED = 9 ++}; ++struct bce_vhci_message { ++ u16 cmd; ++ u16 status; // bce_vhci_message_status ++ u32 param1; ++ u64 param2; ++}; ++ ++struct bce_vhci_message_queue { ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq; ++ struct bce_vhci_message *data; ++ dma_addr_t dma_addr; ++}; ++typedef void (*bce_vhci_event_queue_callback)(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++struct bce_vhci_event_queue { ++ struct bce_vhci *vhci; ++ struct bce_queue_sq *sq; ++ struct bce_vhci_message *data; ++ dma_addr_t dma_addr; ++ bce_vhci_event_queue_callback cb; ++ struct completion queue_empty_completion; ++}; ++struct bce_vhci_command_queue_completion { ++ struct bce_vhci_message *result; ++ struct completion completion; ++}; ++struct bce_vhci_command_queue { ++ struct bce_vhci_message_queue *mq; ++ struct bce_vhci_command_queue_completion completion; ++ struct spinlock completion_lock; ++ struct mutex mutex; ++}; ++ ++int bce_vhci_message_queue_create(struct bce_vhci *vhci, struct bce_vhci_message_queue *ret, const char *name); ++void bce_vhci_message_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_message_queue *q); ++void bce_vhci_message_queue_write(struct bce_vhci_message_queue *q, struct bce_vhci_message *req); ++ ++int __bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_sq_completion compl); ++int bce_vhci_event_queue_create(struct bce_vhci *vhci, struct bce_vhci_event_queue *ret, const char *name, ++ bce_vhci_event_queue_callback cb); ++void bce_vhci_event_queue_destroy(struct bce_vhci *vhci, struct bce_vhci_event_queue *q); ++void bce_vhci_event_queue_submit_pending(struct bce_vhci_event_queue *q, size_t count); ++void bce_vhci_event_queue_pause(struct bce_vhci_event_queue *q); ++void bce_vhci_event_queue_resume(struct bce_vhci_event_queue *q); ++ ++void bce_vhci_command_queue_create(struct bce_vhci_command_queue *ret, struct bce_vhci_message_queue *mq); ++void bce_vhci_command_queue_destroy(struct bce_vhci_command_queue *cq); ++int bce_vhci_command_queue_execute(struct bce_vhci_command_queue *cq, struct bce_vhci_message *req, ++ struct bce_vhci_message *res, unsigned long timeout); ++void bce_vhci_command_queue_deliver_completion(struct bce_vhci_command_queue *cq, struct bce_vhci_message *msg); ++ ++#endif //BCE_VHCI_QUEUE_H +diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/transfer.c +@@ -0,0 +1,661 @@ ++#include "transfer.h" ++#include "../queue.h" ++#include "vhci.h" ++#include "../apple_bce.h" ++#include ++ ++static void bce_vhci_transfer_queue_completion(struct bce_queue_sq *sq); ++static void bce_vhci_transfer_queue_giveback(struct bce_vhci_transfer_queue *q); ++static void bce_vhci_transfer_queue_remove_pending(struct bce_vhci_transfer_queue *q); ++ ++static int bce_vhci_urb_init(struct bce_vhci_urb *vurb); ++static int bce_vhci_urb_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg); ++static int bce_vhci_urb_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c); ++ ++static void bce_vhci_transfer_queue_reset_w(struct work_struct *work); ++ ++void bce_vhci_create_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q, ++ struct usb_host_endpoint *endp, bce_vhci_device_t dev_addr, enum dma_data_direction dir) ++{ ++ char name[0x21]; ++ INIT_LIST_HEAD(&q->evq); ++ INIT_LIST_HEAD(&q->giveback_urb_list); ++ spin_lock_init(&q->urb_lock); ++ mutex_init(&q->pause_lock); ++ q->vhci = vhci; ++ q->endp = endp; ++ q->dev_addr = dev_addr; ++ q->endp_addr = (u8) (endp->desc.bEndpointAddress & 0x8F); ++ q->state = BCE_VHCI_ENDPOINT_ACTIVE; ++ q->active = true; ++ q->stalled = false; ++ q->max_active_requests = 1; ++ if (usb_endpoint_type(&endp->desc) == USB_ENDPOINT_XFER_BULK) ++ q->max_active_requests = BCE_VHCI_BULK_MAX_ACTIVE_URBS; ++ q->remaining_active_requests = q->max_active_requests; ++ q->cq = bce_create_cq(vhci->dev, 0x100); ++ INIT_WORK(&q->w_reset, bce_vhci_transfer_queue_reset_w); ++ q->sq_in = NULL; ++ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { ++ snprintf(name, sizeof(name), "VHC1-%i-%02x", dev_addr, 0x80 | usb_endpoint_num(&endp->desc)); ++ q->sq_in = bce_create_sq(vhci->dev, q->cq, name, 0x100, DMA_FROM_DEVICE, ++ bce_vhci_transfer_queue_completion, q); ++ } ++ q->sq_out = NULL; ++ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) { ++ snprintf(name, sizeof(name), "VHC1-%i-%02x", dev_addr, usb_endpoint_num(&endp->desc)); ++ q->sq_out = bce_create_sq(vhci->dev, q->cq, name, 0x100, DMA_TO_DEVICE, ++ bce_vhci_transfer_queue_completion, q); ++ } ++} ++ ++void bce_vhci_destroy_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q) ++{ ++ bce_vhci_transfer_queue_giveback(q); ++ bce_vhci_transfer_queue_remove_pending(q); ++ if (q->sq_in) ++ bce_destroy_sq(vhci->dev, q->sq_in); ++ if (q->sq_out) ++ bce_destroy_sq(vhci->dev, q->sq_out); ++ bce_destroy_cq(vhci->dev, q->cq); ++} ++ ++static inline bool bce_vhci_transfer_queue_can_init_urb(struct bce_vhci_transfer_queue *q) ++{ ++ return q->remaining_active_requests > 0; ++} ++ ++static void bce_vhci_transfer_queue_defer_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg) ++{ ++ struct bce_vhci_list_message *lm; ++ lm = kmalloc(sizeof(struct bce_vhci_list_message), GFP_KERNEL); ++ INIT_LIST_HEAD(&lm->list); ++ lm->msg = *msg; ++ list_add_tail(&lm->list, &q->evq); ++} ++ ++static void bce_vhci_transfer_queue_giveback(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ struct urb *urb; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while (!list_empty(&q->giveback_urb_list)) { ++ urb = list_first_entry(&q->giveback_urb_list, struct urb, urb_list); ++ list_del(&urb->urb_list); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ usb_hcd_giveback_urb(q->vhci->hcd, urb, urb->status); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++} ++ ++static void bce_vhci_transfer_queue_init_pending_urbs(struct bce_vhci_transfer_queue *q); ++ ++static void bce_vhci_transfer_queue_deliver_pending(struct bce_vhci_transfer_queue *q) ++{ ++ struct urb *urb; ++ struct bce_vhci_list_message *lm; ++ ++ while (!list_empty(&q->endp->urb_list) && !list_empty(&q->evq)) { ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ ++ lm = list_first_entry(&q->evq, struct bce_vhci_list_message, list); ++ if (bce_vhci_urb_update(urb->hcpriv, &lm->msg) == -EAGAIN) ++ break; ++ list_del(&lm->list); ++ kfree(lm); ++ } ++ ++ /* some of the URBs could have been completed, so initialize more URBs if possible */ ++ bce_vhci_transfer_queue_init_pending_urbs(q); ++} ++ ++static void bce_vhci_transfer_queue_remove_pending(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ struct bce_vhci_list_message *lm; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while (!list_empty(&q->evq)) { ++ lm = list_first_entry(&q->evq, struct bce_vhci_list_message, list); ++ list_del(&lm->list); ++ kfree(lm); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++} ++ ++void bce_vhci_transfer_queue_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg) ++{ ++ unsigned long flags; ++ struct bce_vhci_urb *turb; ++ struct urb *urb; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_deliver_pending(q); ++ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && ++ (!list_empty(&q->evq) || list_empty(&q->endp->urb_list))) { ++ bce_vhci_transfer_queue_defer_event(q, msg); ++ goto complete; ++ } ++ if (list_empty(&q->endp->urb_list)) { ++ pr_err("bce-vhci: [%02x] Unexpected transfer queue event\n", q->endp_addr); ++ goto complete; ++ } ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ turb = urb->hcpriv; ++ if (bce_vhci_urb_update(turb, msg) == -EAGAIN) { ++ bce_vhci_transfer_queue_defer_event(q, msg); ++ } else { ++ bce_vhci_transfer_queue_init_pending_urbs(q); ++ } ++ ++complete: ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_giveback(q); ++} ++ ++static void bce_vhci_transfer_queue_completion(struct bce_queue_sq *sq) ++{ ++ unsigned long flags; ++ struct bce_sq_completion_data *c; ++ struct urb *urb; ++ struct bce_vhci_transfer_queue *q = sq->userdata; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ while ((c = bce_next_completion(sq))) { ++ if (c->status == BCE_COMPLETION_ABORTED) { /* We flushed the queue */ ++ pr_debug("bce-vhci: [%02x] Got an abort completion\n", q->endp_addr); ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ if (list_empty(&q->endp->urb_list)) { ++ pr_err("bce-vhci: [%02x] Got a completion while no requests are pending\n", q->endp_addr); ++ continue; ++ } ++ pr_debug("bce-vhci: [%02x] Got a transfer queue completion\n", q->endp_addr); ++ urb = list_first_entry(&q->endp->urb_list, struct urb, urb_list); ++ bce_vhci_urb_transfer_completion(urb->hcpriv, c); ++ bce_notify_submission_complete(sq); ++ } ++ bce_vhci_transfer_queue_deliver_pending(q); ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_giveback(q); ++} ++ ++int bce_vhci_transfer_queue_do_pause(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ int status; ++ u8 endp_addr = (u8) (q->endp->desc.bEndpointAddress & 0x8F); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->active = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ if (q->sq_out) { ++ pr_err("bce-vhci: Not implemented: wait for pending output requests\n"); ++ } ++ bce_vhci_transfer_queue_remove_pending(q); ++ if ((status = bce_vhci_cmd_endpoint_set_state( ++ &q->vhci->cq, q->dev_addr, endp_addr, BCE_VHCI_ENDPOINT_PAUSED, &q->state))) ++ return status; ++ if (q->state != BCE_VHCI_ENDPOINT_PAUSED) ++ return -EINVAL; ++ if (q->sq_in) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_in->qid); ++ if (q->sq_out) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_out->qid); ++ return 0; ++} ++ ++static void bce_vhci_urb_resume(struct bce_vhci_urb *urb); ++ ++int bce_vhci_transfer_queue_do_resume(struct bce_vhci_transfer_queue *q) ++{ ++ unsigned long flags; ++ int status; ++ struct urb *urb, *urbt; ++ struct bce_vhci_urb *vurb; ++ u8 endp_addr = (u8) (q->endp->desc.bEndpointAddress & 0x8F); ++ if ((status = bce_vhci_cmd_endpoint_set_state( ++ &q->vhci->cq, q->dev_addr, endp_addr, BCE_VHCI_ENDPOINT_ACTIVE, &q->state))) ++ return status; ++ if (q->state != BCE_VHCI_ENDPOINT_ACTIVE) ++ return -EINVAL; ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->active = true; ++ list_for_each_entry_safe(urb, urbt, &q->endp->urb_list, urb_list) { ++ vurb = urb->hcpriv; ++ if (vurb->state == BCE_VHCI_URB_INIT_PENDING) { ++ if (!bce_vhci_transfer_queue_can_init_urb(q)) ++ break; ++ bce_vhci_urb_init(vurb); ++ } else { ++ bce_vhci_urb_resume(vurb); ++ } ++ } ++ bce_vhci_transfer_queue_deliver_pending(q); ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ return 0; ++} ++ ++int bce_vhci_transfer_queue_pause(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src) ++{ ++ int ret = 0; ++ mutex_lock(&q->pause_lock); ++ if ((q->paused_by & src) != src) { ++ if (!q->paused_by) ++ ret = bce_vhci_transfer_queue_do_pause(q); ++ if (!ret) ++ q->paused_by |= src; ++ } ++ mutex_unlock(&q->pause_lock); ++ return ret; ++} ++ ++int bce_vhci_transfer_queue_resume(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src) ++{ ++ int ret = 0; ++ mutex_lock(&q->pause_lock); ++ if (q->paused_by & src) { ++ if (!(q->paused_by & ~src)) ++ ret = bce_vhci_transfer_queue_do_resume(q); ++ if (!ret) ++ q->paused_by &= ~src; ++ } ++ mutex_unlock(&q->pause_lock); ++ return ret; ++} ++ ++static void bce_vhci_transfer_queue_reset_w(struct work_struct *work) ++{ ++ unsigned long flags; ++ struct bce_vhci_transfer_queue *q = container_of(work, struct bce_vhci_transfer_queue, w_reset); ++ ++ mutex_lock(&q->pause_lock); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ if (!q->stalled) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ mutex_unlock(&q->pause_lock); ++ return; ++ } ++ q->active = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ q->paused_by |= BCE_VHCI_PAUSE_INTERNAL_WQ; ++ bce_vhci_transfer_queue_remove_pending(q); ++ if (q->sq_in) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_in->qid); ++ if (q->sq_out) ++ bce_cmd_flush_memory_queue(q->vhci->dev->cmd_cmdq, (u16) q->sq_out->qid); ++ bce_vhci_cmd_endpoint_reset(&q->vhci->cq, q->dev_addr, (u8) (q->endp->desc.bEndpointAddress & 0x8F)); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ q->stalled = false; ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ mutex_unlock(&q->pause_lock); ++ bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++} ++ ++void bce_vhci_transfer_queue_request_reset(struct bce_vhci_transfer_queue *q) ++{ ++ queue_work(q->vhci->tq_state_wq, &q->w_reset); ++} ++ ++static void bce_vhci_transfer_queue_init_pending_urbs(struct bce_vhci_transfer_queue *q) ++{ ++ struct urb *urb, *urbt; ++ struct bce_vhci_urb *vurb; ++ list_for_each_entry_safe(urb, urbt, &q->endp->urb_list, urb_list) { ++ vurb = urb->hcpriv; ++ if (!bce_vhci_transfer_queue_can_init_urb(q)) ++ break; ++ if (vurb->state == BCE_VHCI_URB_INIT_PENDING) ++ bce_vhci_urb_init(vurb); ++ } ++} ++ ++ ++ ++static int bce_vhci_urb_data_start(struct bce_vhci_urb *urb, unsigned long *timeout); ++ ++int bce_vhci_urb_create(struct bce_vhci_transfer_queue *q, struct urb *urb) ++{ ++ unsigned long flags; ++ int status = 0; ++ struct bce_vhci_urb *vurb; ++ vurb = kzalloc(sizeof(struct bce_vhci_urb), GFP_KERNEL); ++ urb->hcpriv = vurb; ++ ++ vurb->q = q; ++ vurb->urb = urb; ++ vurb->dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; ++ vurb->is_control = (usb_endpoint_num(&urb->ep->desc) == 0); ++ ++ spin_lock_irqsave(&q->urb_lock, flags); ++ status = usb_hcd_link_urb_to_ep(q->vhci->hcd, urb); ++ if (status) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ urb->hcpriv = NULL; ++ kfree(vurb); ++ return status; ++ } ++ ++ if (q->active) { ++ if (bce_vhci_transfer_queue_can_init_urb(vurb->q)) ++ status = bce_vhci_urb_init(vurb); ++ else ++ vurb->state = BCE_VHCI_URB_INIT_PENDING; ++ } else { ++ if (q->stalled) ++ bce_vhci_transfer_queue_request_reset(q); ++ vurb->state = BCE_VHCI_URB_INIT_PENDING; ++ } ++ if (status) { ++ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb); ++ urb->hcpriv = NULL; ++ kfree(vurb); ++ } else { ++ bce_vhci_transfer_queue_deliver_pending(q); ++ } ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ pr_debug("bce-vhci: [%02x] URB enqueued (dir = %s, size = %i)\n", q->endp_addr, ++ usb_urb_dir_in(urb) ? "IN" : "OUT", urb->transfer_buffer_length); ++ return status; ++} ++ ++static int bce_vhci_urb_init(struct bce_vhci_urb *vurb) ++{ ++ int status = 0; ++ ++ if (vurb->q->remaining_active_requests == 0) { ++ pr_err("bce-vhci: cannot init request (remaining_active_requests = 0)\n"); ++ return -EINVAL; ++ } ++ ++ if (vurb->is_control) { ++ vurb->state = BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST; ++ } else { ++ status = bce_vhci_urb_data_start(vurb, NULL); ++ } ++ ++ if (!status) { ++ --vurb->q->remaining_active_requests; ++ } ++ return status; ++} ++ ++static void bce_vhci_urb_complete(struct bce_vhci_urb *urb, int status) ++{ ++ struct bce_vhci_transfer_queue *q = urb->q; ++ struct bce_vhci *vhci = q->vhci; ++ struct urb *real_urb = urb->urb; ++ pr_debug("bce-vhci: [%02x] URB complete %i\n", q->endp_addr, status); ++ usb_hcd_unlink_urb_from_ep(vhci->hcd, real_urb); ++ real_urb->hcpriv = NULL; ++ real_urb->status = status; ++ if (urb->state != BCE_VHCI_URB_INIT_PENDING) ++ ++urb->q->remaining_active_requests; ++ kfree(urb); ++ list_add_tail(&real_urb->urb_list, &q->giveback_urb_list); ++} ++ ++int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *urb, int status) ++{ ++ struct bce_vhci_urb *vurb; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&q->urb_lock, flags); ++ if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ return ret; ++ } ++ ++ vurb = urb->hcpriv; ++ /* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */ ++ if (vurb->state != BCE_VHCI_URB_INIT_PENDING) { ++ pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ bce_vhci_transfer_queue_pause(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++ spin_lock_irqsave(&q->urb_lock, flags); ++ ++ ++q->remaining_active_requests; ++ } ++ ++ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb); ++ ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ ++ usb_hcd_giveback_urb(q->vhci->hcd, urb, status); ++ ++ if (vurb->state != BCE_VHCI_URB_INIT_PENDING) ++ bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); ++ ++ kfree(vurb); ++ ++ return 0; ++} ++ ++static int bce_vhci_urb_data_transfer_in(struct bce_vhci_urb *urb, unsigned long *timeout) ++{ ++ struct bce_vhci_message msg; ++ struct bce_qe_submission *s; ++ u32 tr_len; ++ int reservation1, reservation2 = -EFAULT; ++ ++ pr_debug("bce-vhci: [%02x] DMA from device %llx %x\n", urb->q->endp_addr, ++ (u64) urb->urb->transfer_dma, urb->urb->transfer_buffer_length); ++ ++ /* Reserve both a message and a submission, so we don't run into issues later. */ ++ reservation1 = bce_reserve_submission(urb->q->vhci->msg_asynchronous.sq, timeout); ++ if (!reservation1) ++ reservation2 = bce_reserve_submission(urb->q->sq_in, timeout); ++ if (reservation1 || reservation2) { ++ pr_err("bce-vhci: Failed to reserve a submission for URB data transfer\n"); ++ if (!reservation1) ++ bce_cancel_submission_reservation(urb->q->vhci->msg_asynchronous.sq); ++ return -ENOMEM; ++ } ++ ++ urb->send_offset = urb->receive_offset; ++ ++ tr_len = urb->urb->transfer_buffer_length - urb->send_offset; ++ ++ spin_lock(&urb->q->vhci->msg_asynchronous_lock); ++ msg.cmd = BCE_VHCI_CMD_TRANSFER_REQUEST; ++ msg.status = 0; ++ msg.param1 = ((urb->urb->ep->desc.bEndpointAddress & 0x8Fu) << 8) | urb->q->dev_addr; ++ msg.param2 = tr_len; ++ bce_vhci_message_queue_write(&urb->q->vhci->msg_asynchronous, &msg); ++ spin_unlock(&urb->q->vhci->msg_asynchronous_lock); ++ ++ s = bce_next_submission(urb->q->sq_in); ++ bce_set_submission_single(s, urb->urb->transfer_dma + urb->send_offset, tr_len); ++ bce_submit_to_device(urb->q->sq_in); ++ ++ urb->state = BCE_VHCI_URB_WAITING_FOR_COMPLETION; ++ return 0; ++} ++ ++static int bce_vhci_urb_data_start(struct bce_vhci_urb *urb, unsigned long *timeout) ++{ ++ if (urb->dir == DMA_TO_DEVICE) { ++ if (urb->urb->transfer_buffer_length > 0) ++ urb->state = BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST; ++ else ++ urb->state = BCE_VHCI_URB_DATA_TRANSFER_COMPLETE; ++ return 0; ++ } else { ++ return bce_vhci_urb_data_transfer_in(urb, timeout); ++ } ++} ++ ++static int bce_vhci_urb_send_out_data(struct bce_vhci_urb *urb, dma_addr_t addr, size_t size) ++{ ++ struct bce_qe_submission *s; ++ unsigned long timeout = 0; ++ if (bce_reserve_submission(urb->q->sq_out, &timeout)) { ++ pr_err("bce-vhci: Failed to reserve a submission for URB data transfer\n"); ++ return -EPIPE; ++ } ++ ++ pr_debug("bce-vhci: [%02x] DMA to device %llx %lx\n", urb->q->endp_addr, (u64) addr, size); ++ ++ s = bce_next_submission(urb->q->sq_out); ++ bce_set_submission_single(s, addr, size); ++ bce_submit_to_device(urb->q->sq_out); ++ return 0; ++} ++ ++static int bce_vhci_urb_data_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ u32 tr_len; ++ int status; ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST) { ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST) { ++ tr_len = min(urb->urb->transfer_buffer_length - urb->send_offset, (u32) msg->param2); ++ if ((status = bce_vhci_urb_send_out_data(urb, urb->urb->transfer_dma + urb->send_offset, tr_len))) ++ return status; ++ urb->send_offset += tr_len; ++ urb->state = BCE_VHCI_URB_WAITING_FOR_COMPLETION; ++ return 0; ++ } ++ } ++ ++ /* 0x1000 in out queues aren't really unexpected */ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && urb->q->sq_out != NULL) ++ return -EAGAIN; ++ pr_err("bce-vhci: [%02x] %s URB unexpected message (state = %x, msg: %x %x %x %llx)\n", ++ urb->q->endp_addr, (urb->is_control ? "Control (data update)" : "Data"), urb->state, ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ return -EAGAIN; ++} ++ ++static int bce_vhci_urb_data_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ urb->receive_offset += c->data_size; ++ if (urb->dir == DMA_FROM_DEVICE || urb->receive_offset >= urb->urb->transfer_buffer_length) { ++ urb->urb->actual_length = (u32) urb->receive_offset; ++ urb->state = BCE_VHCI_URB_DATA_TRANSFER_COMPLETE; ++ if (!urb->is_control) { ++ bce_vhci_urb_complete(urb, 0); ++ return -ENOENT; ++ } ++ } ++ } else { ++ pr_err("bce-vhci: [%02x] Data URB unexpected completion\n", urb->q->endp_addr); ++ } ++ return 0; ++} ++ ++ ++static int bce_vhci_urb_control_check_status(struct bce_vhci_urb *urb) ++{ ++ struct bce_vhci_transfer_queue *q = urb->q; ++ if (urb->received_status == 0) ++ return 0; ++ if (urb->state == BCE_VHCI_URB_DATA_TRANSFER_COMPLETE || ++ (urb->received_status != BCE_VHCI_SUCCESS && urb->state != BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST && ++ urb->state != BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION)) { ++ urb->state = BCE_VHCI_URB_CONTROL_COMPLETE; ++ if (urb->received_status != BCE_VHCI_SUCCESS) { ++ pr_err("bce-vhci: [%02x] URB failed: %x\n", urb->q->endp_addr, urb->received_status); ++ urb->q->active = false; ++ urb->q->stalled = true; ++ bce_vhci_urb_complete(urb, -EPIPE); ++ if (!list_empty(&q->endp->urb_list)) ++ bce_vhci_transfer_queue_request_reset(q); ++ return -ENOENT; ++ } ++ bce_vhci_urb_complete(urb, 0); ++ return -ENOENT; ++ } ++ return 0; ++} ++ ++static int bce_vhci_urb_control_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ int status; ++ if (msg->cmd == BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS) { ++ urb->received_status = msg->status; ++ return bce_vhci_urb_control_check_status(urb); ++ } ++ ++ if (urb->state == BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST) { ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST) { ++ if (bce_vhci_urb_send_out_data(urb, urb->urb->setup_dma, sizeof(struct usb_ctrlrequest))) { ++ pr_err("bce-vhci: [%02x] Failed to start URB setup transfer\n", urb->q->endp_addr); ++ return 0; /* TODO: fail the URB? */ ++ } ++ urb->state = BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION; ++ pr_debug("bce-vhci: [%02x] Sent setup %llx\n", urb->q->endp_addr, urb->urb->setup_dma); ++ return 0; ++ } ++ } else if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST || ++ urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ if ((status = bce_vhci_urb_data_update(urb, msg))) ++ return status; ++ return bce_vhci_urb_control_check_status(urb); ++ } ++ ++ /* 0x1000 in out queues aren't really unexpected */ ++ if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST && urb->q->sq_out != NULL) ++ return -EAGAIN; ++ pr_err("bce-vhci: [%02x] Control URB unexpected message (state = %x, msg: %x %x %x %llx)\n", urb->q->endp_addr, ++ urb->state, msg->cmd, msg->status, msg->param1, msg->param2); ++ return -EAGAIN; ++} ++ ++static int bce_vhci_urb_control_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ int status; ++ unsigned long timeout; ++ ++ if (urb->state == BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION) { ++ if (c->data_size != sizeof(struct usb_ctrlrequest)) ++ pr_err("bce-vhci: [%02x] transfer complete data size mistmatch for usb_ctrlrequest (%llx instead of %lx)\n", ++ urb->q->endp_addr, c->data_size, sizeof(struct usb_ctrlrequest)); ++ ++ timeout = 1000; ++ status = bce_vhci_urb_data_start(urb, &timeout); ++ if (status) { ++ bce_vhci_urb_complete(urb, status); ++ return -ENOENT; ++ } ++ return 0; ++ } else if (urb->state == BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST || ++ urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ if ((status = bce_vhci_urb_data_transfer_completion(urb, c))) ++ return status; ++ return bce_vhci_urb_control_check_status(urb); ++ } else { ++ pr_err("bce-vhci: [%02x] Control URB unexpected completion (state = %x)\n", urb->q->endp_addr, urb->state); ++ } ++ return 0; ++} ++ ++static int bce_vhci_urb_update(struct bce_vhci_urb *urb, struct bce_vhci_message *msg) ++{ ++ if (urb->state == BCE_VHCI_URB_INIT_PENDING) ++ return -EAGAIN; ++ if (urb->is_control) ++ return bce_vhci_urb_control_update(urb, msg); ++ else ++ return bce_vhci_urb_data_update(urb, msg); ++} ++ ++static int bce_vhci_urb_transfer_completion(struct bce_vhci_urb *urb, struct bce_sq_completion_data *c) ++{ ++ if (urb->is_control) ++ return bce_vhci_urb_control_transfer_completion(urb, c); ++ else ++ return bce_vhci_urb_data_transfer_completion(urb, c); ++} ++ ++static void bce_vhci_urb_resume(struct bce_vhci_urb *urb) ++{ ++ int status = 0; ++ if (urb->state == BCE_VHCI_URB_WAITING_FOR_COMPLETION) { ++ status = bce_vhci_urb_data_transfer_in(urb, NULL); ++ } ++ if (status) ++ bce_vhci_urb_complete(urb, status); ++} +diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/transfer.h +@@ -0,0 +1,73 @@ ++#ifndef BCEDRIVER_TRANSFER_H ++#define BCEDRIVER_TRANSFER_H ++ ++#include ++#include "queue.h" ++#include "command.h" ++#include "../queue.h" ++ ++struct bce_vhci_list_message { ++ struct list_head list; ++ struct bce_vhci_message msg; ++}; ++enum bce_vhci_pause_source { ++ BCE_VHCI_PAUSE_INTERNAL_WQ = 1, ++ BCE_VHCI_PAUSE_FIRMWARE = 2, ++ BCE_VHCI_PAUSE_SUSPEND = 4, ++ BCE_VHCI_PAUSE_SHUTDOWN = 8 ++}; ++struct bce_vhci_transfer_queue { ++ struct bce_vhci *vhci; ++ struct usb_host_endpoint *endp; ++ enum bce_vhci_endpoint_state state; ++ u32 max_active_requests, remaining_active_requests; ++ bool active, stalled; ++ u32 paused_by; ++ bce_vhci_device_t dev_addr; ++ u8 endp_addr; ++ struct bce_queue_cq *cq; ++ struct bce_queue_sq *sq_in; ++ struct bce_queue_sq *sq_out; ++ struct list_head evq; ++ struct spinlock urb_lock; ++ struct mutex pause_lock; ++ struct list_head giveback_urb_list; ++ ++ struct work_struct w_reset; ++}; ++enum bce_vhci_urb_state { ++ BCE_VHCI_URB_INIT_PENDING, ++ ++ BCE_VHCI_URB_WAITING_FOR_TRANSFER_REQUEST, ++ BCE_VHCI_URB_WAITING_FOR_COMPLETION, ++ BCE_VHCI_URB_DATA_TRANSFER_COMPLETE, ++ ++ BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST, ++ BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION, ++ BCE_VHCI_URB_CONTROL_COMPLETE ++}; ++struct bce_vhci_urb { ++ struct urb *urb; ++ struct bce_vhci_transfer_queue *q; ++ enum dma_data_direction dir; ++ bool is_control; ++ enum bce_vhci_urb_state state; ++ int received_status; ++ u32 send_offset; ++ u32 receive_offset; ++}; ++ ++void bce_vhci_create_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q, ++ struct usb_host_endpoint *endp, bce_vhci_device_t dev_addr, enum dma_data_direction dir); ++void bce_vhci_destroy_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q); ++void bce_vhci_transfer_queue_event(struct bce_vhci_transfer_queue *q, struct bce_vhci_message *msg); ++int bce_vhci_transfer_queue_do_pause(struct bce_vhci_transfer_queue *q); ++int bce_vhci_transfer_queue_do_resume(struct bce_vhci_transfer_queue *q); ++int bce_vhci_transfer_queue_pause(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src); ++int bce_vhci_transfer_queue_resume(struct bce_vhci_transfer_queue *q, enum bce_vhci_pause_source src); ++void bce_vhci_transfer_queue_request_reset(struct bce_vhci_transfer_queue *q); ++ ++int bce_vhci_urb_create(struct bce_vhci_transfer_queue *q, struct urb *urb); ++int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *urb, int status); ++ ++#endif //BCEDRIVER_TRANSFER_H +diff --git a/drivers/staging/apple-bce/vhci/vhci.c b/drivers/staging/apple-bce/vhci/vhci.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/vhci.c +@@ -0,0 +1,763 @@ ++#include "vhci.h" ++#include "../apple_bce.h" ++#include "command.h" ++#include ++#include ++#include ++#include ++ ++static dev_t bce_vhci_chrdev; ++static struct class *bce_vhci_class; ++static const struct hc_driver bce_vhci_driver; ++static u16 bce_vhci_port_mask = U16_MAX; ++ ++static int bce_vhci_create_event_queues(struct bce_vhci *vhci); ++static void bce_vhci_destroy_event_queues(struct bce_vhci *vhci); ++static int bce_vhci_create_message_queues(struct bce_vhci *vhci); ++static void bce_vhci_destroy_message_queues(struct bce_vhci *vhci); ++static void bce_vhci_handle_firmware_events_w(struct work_struct *ws); ++static void bce_vhci_firmware_event_completion(struct bce_queue_sq *sq); ++ ++int bce_vhci_create(struct apple_bce_device *dev, struct bce_vhci *vhci) ++{ ++ int status; ++ ++ spin_lock_init(&vhci->hcd_spinlock); ++ ++ vhci->dev = dev; ++ ++ vhci->vdevt = bce_vhci_chrdev; ++ vhci->vdev = device_create(bce_vhci_class, dev->dev, vhci->vdevt, NULL, "bce-vhci"); ++ if (IS_ERR_OR_NULL(vhci->vdev)) { ++ status = PTR_ERR(vhci->vdev); ++ goto fail_dev; ++ } ++ ++ if ((status = bce_vhci_create_message_queues(vhci))) ++ goto fail_mq; ++ if ((status = bce_vhci_create_event_queues(vhci))) ++ goto fail_eq; ++ ++ vhci->tq_state_wq = alloc_ordered_workqueue("bce-vhci-tq-state", 0); ++ INIT_WORK(&vhci->w_fw_events, bce_vhci_handle_firmware_events_w); ++ ++ vhci->hcd = usb_create_hcd(&bce_vhci_driver, vhci->vdev, "bce-vhci"); ++ if (!vhci->hcd) { ++ status = -ENOMEM; ++ goto fail_hcd; ++ } ++ vhci->hcd->self.sysdev = &dev->pci->dev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ++ vhci->hcd->self.uses_dma = 1; ++#endif ++ *((struct bce_vhci **) vhci->hcd->hcd_priv) = vhci; ++ vhci->hcd->speed = HCD_USB2; ++ ++ if ((status = usb_add_hcd(vhci->hcd, 0, 0))) ++ goto fail_hcd; ++ ++ return 0; ++ ++fail_hcd: ++ bce_vhci_destroy_event_queues(vhci); ++fail_eq: ++ bce_vhci_destroy_message_queues(vhci); ++fail_mq: ++ device_destroy(bce_vhci_class, vhci->vdevt); ++fail_dev: ++ if (!status) ++ status = -EINVAL; ++ return status; ++} ++ ++void bce_vhci_destroy(struct bce_vhci *vhci) ++{ ++ usb_remove_hcd(vhci->hcd); ++ bce_vhci_destroy_event_queues(vhci); ++ bce_vhci_destroy_message_queues(vhci); ++ device_destroy(bce_vhci_class, vhci->vdevt); ++} ++ ++struct bce_vhci *bce_vhci_from_hcd(struct usb_hcd *hcd) ++{ ++ return *((struct bce_vhci **) hcd->hcd_priv); ++} ++ ++int bce_vhci_start(struct usb_hcd *hcd) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int status; ++ u16 port_mask = 0; ++ bce_vhci_port_t port_no = 0; ++ if ((status = bce_vhci_cmd_controller_enable(&vhci->cq, 1, &port_mask))) ++ return status; ++ vhci->port_mask = port_mask; ++ vhci->port_power_mask = 0; ++ if ((status = bce_vhci_cmd_controller_start(&vhci->cq))) ++ return status; ++ port_mask = vhci->port_mask; ++ while (port_mask) { ++ port_no += 1; ++ port_mask >>= 1; ++ } ++ vhci->port_count = port_no; ++ return 0; ++} ++ ++void bce_vhci_stop(struct usb_hcd *hcd) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_cmd_controller_disable(&vhci->cq); ++} ++ ++static int bce_vhci_hub_status_data(struct usb_hcd *hcd, char *buf) ++{ ++ return 0; ++} ++ ++static int bce_vhci_reset_device(struct bce_vhci *vhci, int index, u16 timeout); ++ ++static int bce_vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int status; ++ struct usb_hub_descriptor *hd; ++ struct usb_hub_status *hs; ++ struct usb_port_status *ps; ++ u32 port_status; ++ // pr_info("bce-vhci: bce_vhci_hub_control %x %i %i [bufl=%i]\n", typeReq, wValue, wIndex, wLength); ++ if (typeReq == GetHubDescriptor && wLength >= sizeof(struct usb_hub_descriptor)) { ++ hd = (struct usb_hub_descriptor *) buf; ++ memset(hd, 0, sizeof(*hd)); ++ hd->bDescLength = sizeof(struct usb_hub_descriptor); ++ hd->bDescriptorType = USB_DT_HUB; ++ hd->bNbrPorts = (u8) vhci->port_count; ++ hd->wHubCharacteristics = HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_INDV_PORT_OCPM; ++ hd->bPwrOn2PwrGood = 0; ++ hd->bHubContrCurrent = 0; ++ return 0; ++ } else if (typeReq == GetHubStatus && wLength >= sizeof(struct usb_hub_status)) { ++ hs = (struct usb_hub_status *) buf; ++ memset(hs, 0, sizeof(*hs)); ++ hs->wHubStatus = 0; ++ hs->wHubChange = 0; ++ return 0; ++ } else if (typeReq == GetPortStatus && wLength >= 4 /* usb 2.0 */) { ++ ps = (struct usb_port_status *) buf; ++ ps->wPortStatus = 0; ++ ps->wPortChange = 0; ++ ++ if (vhci->port_power_mask & BIT(wIndex)) ++ ps->wPortStatus |= USB_PORT_STAT_POWER; ++ ++ if (!(bce_vhci_port_mask & BIT(wIndex))) ++ return 0; ++ ++ if ((status = bce_vhci_cmd_port_status(&vhci->cq, (u8) wIndex, 0, &port_status))) ++ return status; ++ ++ if (port_status & 16) ++ ps->wPortStatus |= USB_PORT_STAT_ENABLE | USB_PORT_STAT_HIGH_SPEED; ++ if (port_status & 4) ++ ps->wPortStatus |= USB_PORT_STAT_CONNECTION; ++ if (port_status & 2) ++ ps->wPortStatus |= USB_PORT_STAT_OVERCURRENT; ++ if (port_status & 8) ++ ps->wPortStatus |= USB_PORT_STAT_RESET; ++ if (port_status & 0x60) ++ ps->wPortStatus |= USB_PORT_STAT_SUSPEND; ++ ++ if (port_status & 0x40000) ++ ps->wPortChange |= USB_PORT_STAT_C_CONNECTION; ++ ++ pr_debug("bce-vhci: Translated status %x to %x:%x\n", port_status, ps->wPortStatus, ps->wPortChange); ++ return 0; ++ } else if (typeReq == SetPortFeature) { ++ if (wValue == USB_PORT_FEAT_POWER) { ++ status = bce_vhci_cmd_port_power_on(&vhci->cq, (u8) wIndex); ++ /* As far as I am aware, power status is not part of the port status so store it separately */ ++ if (!status) ++ vhci->port_power_mask |= BIT(wIndex); ++ return status; ++ } ++ if (wValue == USB_PORT_FEAT_RESET) { ++ return bce_vhci_reset_device(vhci, wIndex, wValue); ++ } ++ if (wValue == USB_PORT_FEAT_SUSPEND) { ++ /* TODO: Am I supposed to also suspend the endpoints? */ ++ pr_debug("bce-vhci: Suspending port %i\n", wIndex); ++ return bce_vhci_cmd_port_suspend(&vhci->cq, (u8) wIndex); ++ } ++ } else if (typeReq == ClearPortFeature) { ++ if (wValue == USB_PORT_FEAT_ENABLE) ++ return bce_vhci_cmd_port_disable(&vhci->cq, (u8) wIndex); ++ if (wValue == USB_PORT_FEAT_POWER) { ++ status = bce_vhci_cmd_port_power_off(&vhci->cq, (u8) wIndex); ++ if (!status) ++ vhci->port_power_mask &= ~BIT(wIndex); ++ return status; ++ } ++ if (wValue == USB_PORT_FEAT_C_CONNECTION) ++ return bce_vhci_cmd_port_status(&vhci->cq, (u8) wIndex, 0x40000, &port_status); ++ if (wValue == USB_PORT_FEAT_C_RESET) { /* I don't think I can transfer it in any way */ ++ return 0; ++ } ++ if (wValue == USB_PORT_FEAT_SUSPEND) { ++ pr_debug("bce-vhci: Resuming port %i\n", wIndex); ++ return bce_vhci_cmd_port_resume(&vhci->cq, (u8) wIndex); ++ } ++ } ++ pr_err("bce-vhci: bce_vhci_hub_control unhandled request: %x %i %i [bufl=%i]\n", typeReq, wValue, wIndex, wLength); ++ dump_stack(); ++ return -EIO; ++} ++ ++static int bce_vhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ struct bce_vhci_device *vdev; ++ bce_vhci_device_t devid; ++ pr_info("bce_vhci_enable_device\n"); ++ ++ if (vhci->port_to_device[udev->portnum]) ++ return 0; ++ ++ /* We need to early address the device */ ++ if (bce_vhci_cmd_device_create(&vhci->cq, udev->portnum, &devid)) ++ return -EIO; ++ ++ pr_info("bce_vhci_cmd_device_create %i -> %i\n", udev->portnum, devid); ++ ++ vdev = kzalloc(sizeof(struct bce_vhci_device), GFP_KERNEL); ++ vhci->port_to_device[udev->portnum] = devid; ++ vhci->devices[devid] = vdev; ++ ++ bce_vhci_create_transfer_queue(vhci, &vdev->tq[0], &udev->ep0, devid, DMA_BIDIRECTIONAL); ++ udev->ep0.hcpriv = &vdev->tq[0]; ++ vdev->tq_mask |= BIT(0); ++ ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &udev->ep0.desc); ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) ++static int bce_vhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) ++#else ++static int bce_vhci_address_device(struct usb_hcd *hcd, struct usb_device *udev, unsigned int timeout_ms) //TODO: follow timeout ++#endif ++{ ++ /* This is the same as enable_device, but instead in the old scheme */ ++ return bce_vhci_enable_device(hcd, udev); ++} ++ ++static void bce_vhci_free_device(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ int i; ++ bce_vhci_device_t devid; ++ struct bce_vhci_device *dev; ++ pr_info("bce_vhci_free_device %i\n", udev->portnum); ++ if (!vhci->port_to_device[udev->portnum]) ++ return; ++ devid = vhci->port_to_device[udev->portnum]; ++ dev = vhci->devices[devid]; ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ bce_vhci_transfer_queue_pause(&dev->tq[i], BCE_VHCI_PAUSE_SHUTDOWN); ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) i); ++ bce_vhci_destroy_transfer_queue(vhci, &dev->tq[i]); ++ } ++ } ++ vhci->devices[devid] = NULL; ++ vhci->port_to_device[udev->portnum] = 0; ++ bce_vhci_cmd_device_destroy(&vhci->cq, devid); ++ kfree(dev); ++} ++ ++static int bce_vhci_reset_device(struct bce_vhci *vhci, int index, u16 timeout) ++{ ++ struct bce_vhci_device *dev = NULL; ++ bce_vhci_device_t devid; ++ int i; ++ int status; ++ enum dma_data_direction dir; ++ pr_info("bce_vhci_reset_device %i\n", index); ++ ++ devid = vhci->port_to_device[index]; ++ if (devid) { ++ dev = vhci->devices[devid]; ++ ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ bce_vhci_transfer_queue_pause(&dev->tq[i], BCE_VHCI_PAUSE_SHUTDOWN); ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) i); ++ bce_vhci_destroy_transfer_queue(vhci, &dev->tq[i]); ++ } ++ } ++ vhci->devices[devid] = NULL; ++ vhci->port_to_device[index] = 0; ++ bce_vhci_cmd_device_destroy(&vhci->cq, devid); ++ } ++ status = bce_vhci_cmd_port_reset(&vhci->cq, (u8) index, timeout); ++ ++ if (dev) { ++ if ((status = bce_vhci_cmd_device_create(&vhci->cq, index, &devid))) ++ return status; ++ vhci->devices[devid] = dev; ++ vhci->port_to_device[index] = devid; ++ ++ for (i = 0; i < 32; i++) { ++ if (dev->tq_mask & BIT(i)) { ++ dir = usb_endpoint_dir_in(&dev->tq[i].endp->desc) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; ++ if (i == 0) ++ dir = DMA_BIDIRECTIONAL; ++ bce_vhci_create_transfer_queue(vhci, &dev->tq[i], dev->tq[i].endp, devid, dir); ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &dev->tq[i].endp->desc); ++ } ++ } ++ } ++ ++ return status; ++} ++ ++static int bce_vhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ return 0; ++} ++ ++static int bce_vhci_get_frame_number(struct usb_hcd *hcd) ++{ ++ return 0; ++} ++ ++static int bce_vhci_bus_suspend(struct usb_hcd *hcd) ++{ ++ int i, j; ++ int status; ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ pr_info("bce_vhci: suspend started\n"); ++ ++ pr_info("bce_vhci: suspend endpoints\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ for (j = 0; j < 32; j++) { ++ if (!(vhci->devices[vhci->port_to_device[i]]->tq_mask & BIT(j))) ++ continue; ++ bce_vhci_transfer_queue_pause(&vhci->devices[vhci->port_to_device[i]]->tq[j], ++ BCE_VHCI_PAUSE_SUSPEND); ++ } ++ } ++ ++ pr_info("bce_vhci: suspend ports\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ bce_vhci_cmd_port_suspend(&vhci->cq, i); ++ } ++ pr_info("bce_vhci: suspend controller\n"); ++ if ((status = bce_vhci_cmd_controller_pause(&vhci->cq))) ++ return status; ++ ++ bce_vhci_event_queue_pause(&vhci->ev_commands); ++ bce_vhci_event_queue_pause(&vhci->ev_system); ++ bce_vhci_event_queue_pause(&vhci->ev_isochronous); ++ bce_vhci_event_queue_pause(&vhci->ev_interrupt); ++ bce_vhci_event_queue_pause(&vhci->ev_asynchronous); ++ pr_info("bce_vhci: suspend done\n"); ++ return 0; ++} ++ ++static int bce_vhci_bus_resume(struct usb_hcd *hcd) ++{ ++ int i, j; ++ int status; ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ pr_info("bce_vhci: resume started\n"); ++ ++ bce_vhci_event_queue_resume(&vhci->ev_system); ++ bce_vhci_event_queue_resume(&vhci->ev_isochronous); ++ bce_vhci_event_queue_resume(&vhci->ev_interrupt); ++ bce_vhci_event_queue_resume(&vhci->ev_asynchronous); ++ bce_vhci_event_queue_resume(&vhci->ev_commands); ++ ++ pr_info("bce_vhci: resume controller\n"); ++ if ((status = bce_vhci_cmd_controller_start(&vhci->cq))) ++ return status; ++ ++ pr_info("bce_vhci: resume ports\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ bce_vhci_cmd_port_resume(&vhci->cq, i); ++ } ++ pr_info("bce_vhci: resume endpoints\n"); ++ for (i = 0; i < 16; i++) { ++ if (!vhci->port_to_device[i]) ++ continue; ++ for (j = 0; j < 32; j++) { ++ if (!(vhci->devices[vhci->port_to_device[i]]->tq_mask & BIT(j))) ++ continue; ++ bce_vhci_transfer_queue_resume(&vhci->devices[vhci->port_to_device[i]]->tq[j], ++ BCE_VHCI_PAUSE_SUSPEND); ++ } ++ } ++ ++ pr_info("bce_vhci: resume done\n"); ++ return 0; ++} ++ ++static int bce_vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ++{ ++ struct bce_vhci_transfer_queue *q = urb->ep->hcpriv; ++ pr_debug("bce_vhci_urb_enqueue %i:%x\n", q->dev_addr, urb->ep->desc.bEndpointAddress); ++ if (!q) ++ return -ENOENT; ++ return bce_vhci_urb_create(q, urb); ++} ++ ++static int bce_vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ++{ ++ struct bce_vhci_transfer_queue *q = urb->ep->hcpriv; ++ pr_debug("bce_vhci_urb_dequeue %x\n", urb->ep->desc.bEndpointAddress); ++ return bce_vhci_urb_request_cancel(q, urb, status); ++} ++ ++static void bce_vhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) ++{ ++ struct bce_vhci_transfer_queue *q = ep->hcpriv; ++ pr_debug("bce_vhci_endpoint_reset\n"); ++ if (q) ++ bce_vhci_transfer_queue_request_reset(q); ++} ++ ++static u8 bce_vhci_endpoint_index(u8 addr) ++{ ++ if (addr & 0x80) ++ return (u8) (0x10 + (addr & 0xf)); ++ return (u8) (addr & 0xf); ++} ++ ++static int bce_vhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *endp) ++{ ++ u8 endp_index = bce_vhci_endpoint_index(endp->desc.bEndpointAddress); ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_device_t devid = vhci->port_to_device[udev->portnum]; ++ struct bce_vhci_device *vdev = vhci->devices[devid]; ++ pr_debug("bce_vhci_add_endpoint %x/%x:%x\n", udev->portnum, devid, endp_index); ++ ++ if (udev->bus->root_hub == udev) /* The USB hub */ ++ return 0; ++ if (vdev == NULL) ++ return -ENODEV; ++ if (vdev->tq_mask & BIT(endp_index)) { ++ endp->hcpriv = &vdev->tq[endp_index]; ++ return 0; ++ } ++ ++ bce_vhci_create_transfer_queue(vhci, &vdev->tq[endp_index], endp, devid, ++ usb_endpoint_dir_in(&endp->desc) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); ++ endp->hcpriv = &vdev->tq[endp_index]; ++ vdev->tq_mask |= BIT(endp_index); ++ ++ bce_vhci_cmd_endpoint_create(&vhci->cq, devid, &endp->desc); ++ return 0; ++} ++ ++static int bce_vhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *endp) ++{ ++ u8 endp_index = bce_vhci_endpoint_index(endp->desc.bEndpointAddress); ++ struct bce_vhci *vhci = bce_vhci_from_hcd(hcd); ++ bce_vhci_device_t devid = vhci->port_to_device[udev->portnum]; ++ struct bce_vhci_transfer_queue *q = endp->hcpriv; ++ struct bce_vhci_device *vdev = vhci->devices[devid]; ++ pr_info("bce_vhci_drop_endpoint %x:%x\n", udev->portnum, endp_index); ++ if (!q) { ++ if (vdev && vdev->tq_mask & BIT(endp_index)) { ++ pr_err("something deleted the hcpriv?\n"); ++ q = &vdev->tq[endp_index]; ++ } else { ++ return 0; ++ } ++ } ++ ++ bce_vhci_cmd_endpoint_destroy(&vhci->cq, devid, (u8) (endp->desc.bEndpointAddress & 0x8Fu)); ++ vhci->devices[devid]->tq_mask &= ~BIT(endp_index); ++ bce_vhci_destroy_transfer_queue(vhci, q); ++ return 0; ++} ++ ++static int bce_vhci_create_message_queues(struct bce_vhci *vhci) ++{ ++ if (bce_vhci_message_queue_create(vhci, &vhci->msg_commands, "VHC1HostCommands") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_system, "VHC1HostSystemEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_isochronous, "VHC1HostIsochronousEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_interrupt, "VHC1HostInterruptEvents") || ++ bce_vhci_message_queue_create(vhci, &vhci->msg_asynchronous, "VHC1HostAsynchronousEvents")) { ++ bce_vhci_destroy_message_queues(vhci); ++ return -EINVAL; ++ } ++ spin_lock_init(&vhci->msg_asynchronous_lock); ++ bce_vhci_command_queue_create(&vhci->cq, &vhci->msg_commands); ++ return 0; ++} ++ ++static void bce_vhci_destroy_message_queues(struct bce_vhci *vhci) ++{ ++ bce_vhci_command_queue_destroy(&vhci->cq); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_commands); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_system); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_isochronous); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_interrupt); ++ bce_vhci_message_queue_destroy(vhci, &vhci->msg_asynchronous); ++} ++ ++static void bce_vhci_handle_system_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++static void bce_vhci_handle_usb_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg); ++ ++static int bce_vhci_create_event_queues(struct bce_vhci *vhci) ++{ ++ vhci->ev_cq = bce_create_cq(vhci->dev, 0x100); ++ if (!vhci->ev_cq) ++ return -EINVAL; ++#define CREATE_EVENT_QUEUE(field, name, cb) bce_vhci_event_queue_create(vhci, &vhci->field, name, cb) ++ if (__bce_vhci_event_queue_create(vhci, &vhci->ev_commands, "VHC1FirmwareCommands", ++ bce_vhci_firmware_event_completion) || ++ CREATE_EVENT_QUEUE(ev_system, "VHC1FirmwareSystemEvents", bce_vhci_handle_system_event) || ++ CREATE_EVENT_QUEUE(ev_isochronous, "VHC1FirmwareIsochronousEvents", bce_vhci_handle_usb_event) || ++ CREATE_EVENT_QUEUE(ev_interrupt, "VHC1FirmwareInterruptEvents", bce_vhci_handle_usb_event) || ++ CREATE_EVENT_QUEUE(ev_asynchronous, "VHC1FirmwareAsynchronousEvents", bce_vhci_handle_usb_event)) { ++ bce_vhci_destroy_event_queues(vhci); ++ return -EINVAL; ++ } ++#undef CREATE_EVENT_QUEUE ++ return 0; ++} ++ ++static void bce_vhci_destroy_event_queues(struct bce_vhci *vhci) ++{ ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_commands); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_system); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_isochronous); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_interrupt); ++ bce_vhci_event_queue_destroy(vhci, &vhci->ev_asynchronous); ++ if (vhci->ev_cq) ++ bce_destroy_cq(vhci->dev, vhci->ev_cq); ++} ++ ++static void bce_vhci_send_fw_event_response(struct bce_vhci *vhci, struct bce_vhci_message *req, u16 status) ++{ ++ unsigned long timeout = 1000; ++ struct bce_vhci_message r = *req; ++ r.cmd = (u16) (req->cmd | 0x8000u); ++ r.status = status; ++ r.param1 = req->param1; ++ r.param2 = 0; ++ ++ if (bce_reserve_submission(vhci->msg_system.sq, &timeout)) { ++ pr_err("bce-vhci: Cannot reserve submision for FW event reply\n"); ++ return; ++ } ++ bce_vhci_message_queue_write(&vhci->msg_system, &r); ++} ++ ++static int bce_vhci_handle_firmware_event(struct bce_vhci *vhci, struct bce_vhci_message *msg) ++{ ++ unsigned long flags; ++ bce_vhci_device_t devid; ++ u8 endp; ++ struct bce_vhci_device *dev; ++ struct bce_vhci_transfer_queue *tq; ++ if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE || msg->cmd == BCE_VHCI_CMD_ENDPOINT_SET_STATE) { ++ devid = (bce_vhci_device_t) (msg->param1 & 0xff); ++ endp = bce_vhci_endpoint_index((u8) ((msg->param1 >> 8) & 0xff)); ++ dev = vhci->devices[devid]; ++ if (!dev || !(dev->tq_mask & BIT(endp))) ++ return BCE_VHCI_BAD_ARGUMENT; ++ tq = &dev->tq[endp]; ++ } ++ ++ if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_REQUEST_STATE) { ++ if (msg->param2 == BCE_VHCI_ENDPOINT_ACTIVE) { ++ bce_vhci_transfer_queue_resume(tq, BCE_VHCI_PAUSE_FIRMWARE); ++ return BCE_VHCI_SUCCESS; ++ } else if (msg->param2 == BCE_VHCI_ENDPOINT_PAUSED) { ++ bce_vhci_transfer_queue_pause(tq, BCE_VHCI_PAUSE_FIRMWARE); ++ return BCE_VHCI_SUCCESS; ++ } ++ return BCE_VHCI_BAD_ARGUMENT; ++ } else if (msg->cmd == BCE_VHCI_CMD_ENDPOINT_SET_STATE) { ++ if (msg->param2 == BCE_VHCI_ENDPOINT_STALLED) { ++ tq->state = msg->param2; ++ spin_lock_irqsave(&tq->urb_lock, flags); ++ tq->stalled = true; ++ spin_unlock_irqrestore(&tq->urb_lock, flags); ++ return BCE_VHCI_SUCCESS; ++ } ++ return BCE_VHCI_BAD_ARGUMENT; ++ } ++ pr_warn("bce-vhci: Unhandled firmware event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ return BCE_VHCI_BAD_ARGUMENT; ++} ++ ++static void bce_vhci_handle_firmware_events_w(struct work_struct *ws) ++{ ++ size_t cnt = 0; ++ int result; ++ struct bce_vhci *vhci = container_of(ws, struct bce_vhci, w_fw_events); ++ struct bce_queue_sq *sq = vhci->ev_commands.sq; ++ struct bce_sq_completion_data *cq; ++ struct bce_vhci_message *msg, *msg2 = NULL; ++ ++ while (true) { ++ if (msg2) { ++ msg = msg2; ++ msg2 = NULL; ++ } else if ((cq = bce_next_completion(sq))) { ++ if (cq->status == BCE_COMPLETION_ABORTED) { ++ bce_notify_submission_complete(sq); ++ continue; ++ } ++ msg = &vhci->ev_commands.data[sq->head]; ++ } else { ++ break; ++ } ++ ++ pr_debug("bce-vhci: Got fw event: %x s=%x p1=%x p2=%llx\n", msg->cmd, msg->status, msg->param1, msg->param2); ++ if ((cq = bce_next_completion(sq))) { ++ msg2 = &vhci->ev_commands.data[(sq->head + 1) % sq->el_count]; ++ pr_debug("bce-vhci: Got second fw event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ if (cq->status != BCE_COMPLETION_ABORTED && ++ msg2->cmd == (msg->cmd | 0x4000) && msg2->param1 == msg->param1) { ++ /* Take two elements */ ++ pr_debug("bce-vhci: Cancelled\n"); ++ bce_vhci_send_fw_event_response(vhci, msg, BCE_VHCI_ABORT); ++ ++ bce_notify_submission_complete(sq); ++ bce_notify_submission_complete(sq); ++ msg2 = NULL; ++ cnt += 2; ++ continue; ++ } ++ ++ pr_warn("bce-vhci: Handle fw event - unexpected cancellation\n"); ++ } ++ ++ result = bce_vhci_handle_firmware_event(vhci, msg); ++ bce_vhci_send_fw_event_response(vhci, msg, (u16) result); ++ ++ ++ bce_notify_submission_complete(sq); ++ ++cnt; ++ } ++ bce_vhci_event_queue_submit_pending(&vhci->ev_commands, cnt); ++ if (atomic_read(&sq->available_commands) == sq->el_count - 1) { ++ pr_debug("bce-vhci: complete\n"); ++ complete(&vhci->ev_commands.queue_empty_completion); ++ } ++} ++ ++static void bce_vhci_firmware_event_completion(struct bce_queue_sq *sq) ++{ ++ struct bce_vhci_event_queue *q = sq->userdata; ++ queue_work(q->vhci->tq_state_wq, &q->vhci->w_fw_events); ++} ++ ++static void bce_vhci_handle_system_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg) ++{ ++ if (msg->cmd & 0x8000) { ++ bce_vhci_command_queue_deliver_completion(&q->vhci->cq, msg); ++ } else { ++ pr_warn("bce-vhci: Unhandled system event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ } ++} ++ ++static void bce_vhci_handle_usb_event(struct bce_vhci_event_queue *q, struct bce_vhci_message *msg) ++{ ++ bce_vhci_device_t devid; ++ u8 endp; ++ struct bce_vhci_device *dev; ++ if (msg->cmd & 0x8000) { ++ bce_vhci_command_queue_deliver_completion(&q->vhci->cq, msg); ++ } else if (msg->cmd == BCE_VHCI_CMD_TRANSFER_REQUEST || msg->cmd == BCE_VHCI_CMD_CONTROL_TRANSFER_STATUS) { ++ devid = (bce_vhci_device_t) (msg->param1 & 0xff); ++ endp = bce_vhci_endpoint_index((u8) ((msg->param1 >> 8) & 0xff)); ++ dev = q->vhci->devices[devid]; ++ if (!dev || (dev->tq_mask & BIT(endp)) == 0) { ++ pr_err("bce-vhci: Didn't find destination for transfer queue event\n"); ++ return; ++ } ++ bce_vhci_transfer_queue_event(&dev->tq[endp], msg); ++ } else { ++ pr_warn("bce-vhci: Unhandled USB event: %x s=%x p1=%x p2=%llx\n", ++ msg->cmd, msg->status, msg->param1, msg->param2); ++ } ++} ++ ++ ++ ++static const struct hc_driver bce_vhci_driver = { ++ .description = "bce-vhci", ++ .product_desc = "BCE VHCI Host Controller", ++ .hcd_priv_size = sizeof(struct bce_vhci *), ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ++ .flags = HCD_USB2, ++#else ++ .flags = HCD_USB2 | HCD_DMA, ++#endif ++ ++ .start = bce_vhci_start, ++ .stop = bce_vhci_stop, ++ .hub_status_data = bce_vhci_hub_status_data, ++ .hub_control = bce_vhci_hub_control, ++ .urb_enqueue = bce_vhci_urb_enqueue, ++ .urb_dequeue = bce_vhci_urb_dequeue, ++ .enable_device = bce_vhci_enable_device, ++ .free_dev = bce_vhci_free_device, ++ .address_device = bce_vhci_address_device, ++ .add_endpoint = bce_vhci_add_endpoint, ++ .drop_endpoint = bce_vhci_drop_endpoint, ++ .endpoint_reset = bce_vhci_endpoint_reset, ++ .check_bandwidth = bce_vhci_check_bandwidth, ++ .get_frame_number = bce_vhci_get_frame_number, ++ .bus_suspend = bce_vhci_bus_suspend, ++ .bus_resume = bce_vhci_bus_resume ++}; ++ ++ ++int __init bce_vhci_module_init(void) ++{ ++ int result; ++ if ((result = alloc_chrdev_region(&bce_vhci_chrdev, 0, 1, "bce-vhci"))) ++ goto fail_chrdev; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0) ++ bce_vhci_class = class_create(THIS_MODULE, "bce-vhci"); ++#else ++ bce_vhci_class = class_create("bce-vhci"); ++#endif ++ if (IS_ERR(bce_vhci_class)) { ++ result = PTR_ERR(bce_vhci_class); ++ goto fail_class; ++ } ++ return 0; ++ ++fail_class: ++ class_destroy(bce_vhci_class); ++fail_chrdev: ++ unregister_chrdev_region(bce_vhci_chrdev, 1); ++ if (!result) ++ result = -EINVAL; ++ return result; ++} ++void __exit bce_vhci_module_exit(void) ++{ ++ class_destroy(bce_vhci_class); ++ unregister_chrdev_region(bce_vhci_chrdev, 1); ++} ++ ++module_param_named(vhci_port_mask, bce_vhci_port_mask, ushort, 0444); ++MODULE_PARM_DESC(vhci_port_mask, "Specifies which VHCI ports are enabled"); +diff --git a/drivers/staging/apple-bce/vhci/vhci.h b/drivers/staging/apple-bce/vhci/vhci.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/vhci/vhci.h +@@ -0,0 +1,52 @@ ++#ifndef BCE_VHCI_H ++#define BCE_VHCI_H ++ ++#include "queue.h" ++#include "transfer.h" ++ ++struct usb_hcd; ++struct bce_queue_cq; ++ ++struct bce_vhci_device { ++ struct bce_vhci_transfer_queue tq[32]; ++ u32 tq_mask; ++}; ++struct bce_vhci { ++ struct apple_bce_device *dev; ++ dev_t vdevt; ++ struct device *vdev; ++ struct usb_hcd *hcd; ++ struct spinlock hcd_spinlock; ++ struct bce_vhci_message_queue msg_commands; ++ struct bce_vhci_message_queue msg_system; ++ struct bce_vhci_message_queue msg_isochronous; ++ struct bce_vhci_message_queue msg_interrupt; ++ struct bce_vhci_message_queue msg_asynchronous; ++ struct spinlock msg_asynchronous_lock; ++ struct bce_vhci_command_queue cq; ++ struct bce_queue_cq *ev_cq; ++ struct bce_vhci_event_queue ev_commands; ++ struct bce_vhci_event_queue ev_system; ++ struct bce_vhci_event_queue ev_isochronous; ++ struct bce_vhci_event_queue ev_interrupt; ++ struct bce_vhci_event_queue ev_asynchronous; ++ u16 port_mask; ++ u8 port_count; ++ u16 port_power_mask; ++ bce_vhci_device_t port_to_device[16]; ++ struct bce_vhci_device *devices[16]; ++ struct workqueue_struct *tq_state_wq; ++ struct work_struct w_fw_events; ++}; ++ ++int __init bce_vhci_module_init(void); ++void __exit bce_vhci_module_exit(void); ++ ++int bce_vhci_create(struct apple_bce_device *dev, struct bce_vhci *vhci); ++void bce_vhci_destroy(struct bce_vhci *vhci); ++int bce_vhci_start(struct usb_hcd *hcd); ++void bce_vhci_stop(struct usb_hcd *hcd); ++ ++struct bce_vhci *bce_vhci_from_hcd(struct usb_hcd *hcd); ++ ++#endif //BCE_VHCI_H +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/1002-Put-apple-bce-in-drivers-staging.patch b/patch/kernel/archive/uefi-x86-6.18/1002-Put-apple-bce-in-drivers-staging.patch new file mode 100644 index 000000000..76fc17d51 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/1002-Put-apple-bce-in-drivers-staging.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Redecorating <69827514+Redecorating@users.noreply.github.com> +Date: Mon, 7 Nov 2022 14:56:34 +0530 +Subject: Put apple-bce in drivers/staging + +- rpardini: 6.12: in drivers/staging/Makefile do it at the top to avoid + conflicts with Armbian's (wifi?) patching. + +Signed-off-by: Ricardo Pardini +--- + drivers/staging/Kconfig | 2 ++ + drivers/staging/Makefile | 1 + + drivers/staging/apple-bce/Kconfig | 18 ++++++++++ + drivers/staging/apple-bce/Makefile | 2 +- + 4 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -52,4 +52,6 @@ source "drivers/staging/gpib/Kconfig" + + source "drivers/staging/rtl8723cs/Kconfig" + ++source "drivers/staging/apple-bce/Kconfig" ++ + endif # STAGING +diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -2,6 +2,7 @@ + # Makefile for staging directory + + obj-y += media/ ++obj-$(CONFIG_APPLE_BCE) += apple-bce/ + obj-$(CONFIG_RTL8723BS) += rtl8723bs/ + obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ + obj-$(CONFIG_VME_BUS) += vme_user/ +diff --git a/drivers/staging/apple-bce/Kconfig b/drivers/staging/apple-bce/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/staging/apple-bce/Kconfig +@@ -0,0 +1,18 @@ ++config APPLE_BCE ++ tristate "Apple BCE driver (VHCI and Audio support)" ++ default m ++ depends on X86 ++ select SOUND ++ select SND ++ select SND_PCM ++ select SND_JACK ++ help ++ VHCI and audio support on Apple MacBooks with the T2 Chip. ++ This driver is divided in three components: ++ - BCE (Buffer Copy Engine): which establishes a basic communication ++ channel with the T2 chip. This component is required by the other two: ++ - VHCI (Virtual Host Controller Interface): Access to keyboard, mouse ++ and other system devices depend on this virtual USB host controller ++ - Audio: a driver for the T2 audio interface. ++ ++ If "M" is selected, the module will be called apple-bce.' +diff --git a/drivers/staging/apple-bce/Makefile b/drivers/staging/apple-bce/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/Makefile ++++ b/drivers/staging/apple-bce/Makefile +@@ -1,5 +1,5 @@ + modname := apple-bce +-obj-m += $(modname).o ++obj-$(CONFIG_APPLE_BCE) += $(modname).o + + apple-bce-objs := apple_bce.o mailbox.o queue.o queue_dma.o vhci/vhci.o vhci/queue.o vhci/transfer.o audio/audio.o audio/protocol.o audio/protocol_bce.o audio/pcm.o + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/1003-Fix-freezing-on-turning-off-camera.patch b/patch/kernel/archive/uefi-x86-6.18/1003-Fix-freezing-on-turning-off-camera.patch new file mode 100644 index 000000000..f4f746a4d --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/1003-Fix-freezing-on-turning-off-camera.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: mnural +Date: Mon, 14 Apr 2025 14:44:20 +0530 +Subject: Fix freezing on turning off camera + +Detailed logs and reason behind can be seen here: +https://github.com/t2linux/T2-Debian-and-Ubuntu-Kernel/issues/130#issuecomment-2799130835 +--- + drivers/staging/apple-bce/vhci/transfer.c | 16 ++++++++-- + drivers/staging/apple-bce/vhci/transfer.h | 4 ++- + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/vhci/transfer.c ++++ b/drivers/staging/apple-bce/vhci/transfer.c +@@ -400,6 +400,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + struct bce_vhci_urb *vurb; + unsigned long flags; + int ret; ++ enum bce_vhci_urb_state old_state; + + spin_lock_irqsave(&q->urb_lock, flags); + if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) { +@@ -408,8 +409,19 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + } + + vurb = urb->hcpriv; ++ ++ old_state = vurb->state; /* save old state to use later because we'll set state as cancelled */ ++ ++ if (old_state == BCE_VHCI_URB_CANCELLED) { ++ spin_unlock_irqrestore(&q->urb_lock, flags); ++ pr_debug("bce-vhci: URB %p is already cancelled, skipping\n", urb); ++ return 0; ++ } ++ ++ vurb->state = BCE_VHCI_URB_CANCELLED; ++ + /* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */ +- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) { ++ if (old_state != BCE_VHCI_URB_INIT_PENDING) { + pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr); + + spin_unlock_irqrestore(&q->urb_lock, flags); +@@ -425,7 +437,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u + + usb_hcd_giveback_urb(q->vhci->hcd, urb, status); + +- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) ++ if (old_state != BCE_VHCI_URB_INIT_PENDING) + bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ); + + kfree(vurb); +diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h +index 111111111111..222222222222 100644 +--- a/drivers/staging/apple-bce/vhci/transfer.h ++++ b/drivers/staging/apple-bce/vhci/transfer.h +@@ -44,7 +44,9 @@ enum bce_vhci_urb_state { + + BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST, + BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION, +- BCE_VHCI_URB_CONTROL_COMPLETE ++ BCE_VHCI_URB_CONTROL_COMPLETE, ++ ++ BCE_VHCI_URB_CANCELLED + }; + struct bce_vhci_urb { + struct urb *urb; +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/2008-i915-4-lane-quirk-for-mbp15-1.patch b/patch/kernel/archive/uefi-x86-6.18/2008-i915-4-lane-quirk-for-mbp15-1.patch new file mode 100644 index 000000000..4779c1904 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/2008-i915-4-lane-quirk-for-mbp15-1.patch @@ -0,0 +1,76 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Fri, 28 Jun 2024 04:43:50 +0000 +Subject: i915: 4 lane quirk for mbp15,1 + +Needed to use iGPU when dGPU was boot GPU + +Patch written by Kerem Karabay +--- + drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++ + drivers/gpu/drm/i915/display/intel_quirks.c | 15 ++++++++++ + drivers/gpu/drm/i915/display/intel_quirks.h | 1 + + 3 files changed, 19 insertions(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -4868,6 +4868,9 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) + if (dig_port->ddi_a_4_lanes) + return false; + ++ if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES)) ++ return true; ++ + /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only + * supported configuration + */ +diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_quirks.c ++++ b/drivers/gpu/drm/i915/display/intel_quirks.c +@@ -66,6 +66,18 @@ static void quirk_increase_ddi_disabled_time(struct intel_display *display) + drm_info(display->drm, "Applying Increase DDI Disabled quirk\n"); + } + ++/* ++ * In some cases, the firmware might not set the lane count to 4 (for example, ++ * when booting in some dual GPU Macs with the dGPU as the default GPU), this ++ * quirk is used to force it as otherwise it might not be possible to compute a ++ * valid link configuration. ++ */ ++static void quirk_ddi_a_force_4_lanes(struct intel_display *display) ++{ ++ intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES); ++ drm_info(display->drm, "Applying DDI A Forced 4 Lanes quirk\n"); ++} ++ + static void quirk_no_pps_backlight_power_hook(struct intel_display *display) + { + intel_set_quirk(display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK); +@@ -240,6 +252,9 @@ static struct intel_quirk intel_quirks[] = { + + /* Dell XPS 13 7390 2-in-1 */ + { 0x8a12, 0x1028, 0x08b0, quirk_edp_limit_rate_hbr2 }, ++ ++ /* Apple MacBookPro15,1 */ ++ { 0x3e9b, 0x106b, 0x0176, quirk_ddi_a_force_4_lanes }, + }; + + static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { +diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_quirks.h ++++ b/drivers/gpu/drm/i915/display/intel_quirks.h +@@ -21,6 +21,7 @@ enum intel_quirk_id { + QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK, + QUIRK_FW_SYNC_LEN, + QUIRK_EDP_LIMIT_RATE_HBR2, ++ QUIRK_DDI_A_FORCE_4_LANES, + }; + + void intel_init_quirks(struct intel_display *display); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch b/patch/kernel/archive/uefi-x86-6.18/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch new file mode 100644 index 000000000..7c568cdc0 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/2009-apple-gmux-allow-switching-to-igpu-at-probe.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Fri, 10 Feb 2023 22:45:00 +1100 +Subject: apple-gmux: allow switching to igpu at probe + +This means user don't need to set the gpu-power-prefs efivar to use the +igpu while runtime switching isn't working, so macOS will be unaffected. + +This isn't really upstreamable, what we want upstream is the ability to +switch at runtime (so both gpus need to be able to probe the eDP panel). + +Based off of work by Kerem Karabay +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++ + drivers/gpu/vga/vga_switcheroo.c | 7 +--- + drivers/pci/vgaarb.c | 1 + + drivers/platform/x86/apple-gmux.c | 18 ++++++++++ + 4 files changed, 23 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2322,6 +2322,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, + int ret, retry = 0, i; + bool supports_atomic = false; + ++ if (vga_switcheroo_client_probe_defer(pdev)) ++ return -EPROBE_DEFER; ++ + if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA || + (pdev->class >> 8) == PCI_CLASS_DISPLAY_OTHER) { + if (drm_firmware_drivers_only() && amdgpu_modeset == -1) +diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/vga/vga_switcheroo.c ++++ b/drivers/gpu/vga/vga_switcheroo.c +@@ -438,12 +438,7 @@ find_active_client(struct list_head *head) + bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) + { + if (pci_is_display(pdev)) { +- /* +- * apple-gmux is needed on pre-retina MacBook Pro +- * to probe the panel if pdev is the inactive GPU. +- */ +- if (apple_gmux_present() && pdev != vga_default_device() && +- !vgasr_priv.handler_flags) ++ if (apple_gmux_present() && !vgasr_priv.handler_flags) + return true; + } + +diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c +index 111111111111..222222222222 100644 +--- a/drivers/pci/vgaarb.c ++++ b/drivers/pci/vgaarb.c +@@ -143,6 +143,7 @@ void vga_set_default_device(struct pci_dev *pdev) + pci_dev_put(vga_default); + vga_default = pci_dev_get(pdev); + } ++EXPORT_SYMBOL_GPL(vga_set_default_device); + + /** + * vga_remove_vgacon - deactivate VGA console +diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c +index 111111111111..222222222222 100644 +--- a/drivers/platform/x86/apple-gmux.c ++++ b/drivers/platform/x86/apple-gmux.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -107,6 +108,10 @@ struct apple_gmux_config { + + # define MMIO_GMUX_MAX_BRIGHTNESS 0xffff + ++static bool force_igd; ++module_param(force_igd, bool, 0); ++MODULE_PARM_DESC(force_idg, "Switch gpu to igd on module load. Make sure that you have apple-set-os set up and the iGPU is in `lspci -s 00:02.0`. (default: false) (bool)"); ++ + static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) + { + return inb(gmux_data->iostart + port); +@@ -945,6 +950,19 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) + gmux_enable_interrupts(gmux_data); + gmux_read_switch_state(gmux_data); + ++ if (force_igd) { ++ struct pci_dev *pdev; ++ ++ pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(2, 0)); ++ if (pdev) { ++ pr_info("Switching to IGD"); ++ gmux_switchto(VGA_SWITCHEROO_IGD); ++ vga_set_default_device(pdev); ++ } else { ++ pr_err("force_idg is true, but couldn't find iGPU at 00:02.0! Is apple-set-os working?"); ++ } ++ } ++ + /* + * Retina MacBook Pros cannot switch the panel's AUX separately + * and need eDP pre-calibration. They are distinguishable from +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3001-applesmc-convert-static-structures-to-drvdata.patch b/patch/kernel/archive/uefi-x86-6.18/3001-applesmc-convert-static-structures-to-drvdata.patch new file mode 100644 index 000000000..17c687ecb --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3001-applesmc-convert-static-structures-to-drvdata.patch @@ -0,0 +1,1218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:55 +0100 +Subject: applesmc: convert static structures to drvdata + +All static data structures have been moved to an applesmc_device struct, +which is then associated with the platform device. +This change is intended to ease the migration to an acpi_device, where +static data would preferably be avoided. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 540 ++++++---- + 1 file changed, 319 insertions(+), 221 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -6,6 +6,7 @@ + * + * Copyright (C) 2007 Nicolas Boichat + * Copyright (C) 2010 Henrik Rydberg ++ * Copyright (C) 2019 Paul Pawlowski + * + * Based on hdaps.c driver: + * Copyright (C) 2005 Robert Love +@@ -119,7 +120,7 @@ struct applesmc_entry { + }; + + /* Register lookup and registers common to all SMCs */ +-static struct applesmc_registers { ++struct applesmc_registers { + struct mutex mutex; /* register read/write mutex */ + unsigned int key_count; /* number of SMC registers */ + unsigned int fan_count; /* number of fans */ +@@ -133,26 +134,32 @@ static struct applesmc_registers { + bool init_complete; /* true when fully initialized */ + struct applesmc_entry *cache; /* cached key entries */ + const char **index; /* temperature key index */ +-} smcreg = { +- .mutex = __MUTEX_INITIALIZER(smcreg.mutex), + }; + +-static const int debug; +-static struct platform_device *pdev; +-static s16 rest_x; +-static s16 rest_y; +-static u8 backlight_state[2]; ++struct applesmc_device { ++ struct platform_device *dev; ++ struct applesmc_registers reg; + +-static struct device *hwmon_dev; +-static struct input_dev *applesmc_idev; ++ s16 rest_x; ++ s16 rest_y; + +-/* +- * Last index written to key_at_index sysfs file, and value to use for all other +- * key_at_index_* sysfs files. +- */ +-static unsigned int key_at_index; ++ u8 backlight_state[2]; ++ ++ struct device *hwmon_dev; ++ struct input_dev *idev; ++ ++ /* ++ * Last index written to key_at_index sysfs file, and value to use for all other ++ * key_at_index_* sysfs files. ++ */ ++ unsigned int key_at_index; ++ ++ struct workqueue_struct *backlight_wq; ++ struct work_struct backlight_work; ++ struct led_classdev backlight_dev; ++}; + +-static struct workqueue_struct *applesmc_led_wq; ++static const int debug; + + /* + * Wait for specific status bits with a mask on the SMC. +@@ -338,36 +345,37 @@ static int read_register_count(unsigned int *count) + * All functions below are concurrency safe - callers should NOT hold lock. + */ + +-static int applesmc_read_entry(const struct applesmc_entry *entry, +- u8 *buf, u8 len) ++static int applesmc_read_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + + return ret; + } + +-static int applesmc_write_entry(const struct applesmc_entry *entry, +- const u8 *buf, u8 len) ++static int applesmc_write_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, const u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + return ret; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_index(int index) ++static const struct applesmc_entry *applesmc_get_entry_by_index( ++ struct applesmc_device *smc, int index) + { +- struct applesmc_entry *cache = &smcreg.cache[index]; ++ struct applesmc_entry *cache = &smc->reg.cache[index]; + u8 key[4], info[6]; + __be32 be; + int ret = 0; +@@ -375,7 +383,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + if (cache->valid) + return cache; + +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + + if (cache->valid) + goto out; +@@ -394,20 +402,21 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + cache->valid = true; + + out: +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + if (ret) + return ERR_PTR(ret); + return cache; + } + +-static int applesmc_get_lower_bound(unsigned int *lo, const char *key) ++static int applesmc_get_lower_bound(struct applesmc_device *smc, ++ unsigned int *lo, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { + *lo = 0; + return PTR_ERR(entry); +@@ -422,16 +431,17 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) + return 0; + } + +-static int applesmc_get_upper_bound(unsigned int *hi, const char *key) ++static int applesmc_get_upper_bound(struct applesmc_device *smc, ++ unsigned int *hi, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { +- *hi = smcreg.key_count; ++ *hi = smc->reg.key_count; + return PTR_ERR(entry); + } + if (strcmp(key, entry->key) < 0) +@@ -444,50 +454,54 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) + return 0; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key) ++static const struct applesmc_entry *applesmc_get_entry_by_key( ++ struct applesmc_device *smc, const char *key) + { + int begin, end; + int ret; + +- ret = applesmc_get_lower_bound(&begin, key); ++ ret = applesmc_get_lower_bound(smc, &begin, key); + if (ret) + return ERR_PTR(ret); +- ret = applesmc_get_upper_bound(&end, key); ++ ret = applesmc_get_upper_bound(smc, &end, key); + if (ret) + return ERR_PTR(ret); + if (end - begin != 1) + return ERR_PTR(-EINVAL); + +- return applesmc_get_entry_by_index(begin); ++ return applesmc_get_entry_by_index(smc, begin); + } + +-static int applesmc_read_key(const char *key, u8 *buffer, u8 len) ++static int applesmc_read_key(struct applesmc_device *smc, ++ const char *key, u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_read_entry(entry, buffer, len); ++ return applesmc_read_entry(smc, entry, buffer, len); + } + +-static int applesmc_write_key(const char *key, const u8 *buffer, u8 len) ++static int applesmc_write_key(struct applesmc_device *smc, ++ const char *key, const u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_write_entry(entry, buffer, len); ++ return applesmc_write_entry(smc, entry, buffer, len); + } + +-static int applesmc_has_key(const char *key, bool *value) ++static int applesmc_has_key(struct applesmc_device *smc, ++ const char *key, bool *value) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) + return PTR_ERR(entry); + +@@ -498,12 +512,13 @@ static int applesmc_has_key(const char *key, bool *value) + /* + * applesmc_read_s16 - Read 16-bit signed big endian register + */ +-static int applesmc_read_s16(const char *key, s16 *value) ++static int applesmc_read_s16(struct applesmc_device *smc, ++ const char *key, s16 *value) + { + u8 buffer[2]; + int ret; + +- ret = applesmc_read_key(key, buffer, 2); ++ ret = applesmc_read_key(smc, key, buffer, 2); + if (ret) + return ret; + +@@ -514,28 +529,29 @@ static int applesmc_read_s16(const char *key, s16 *value) + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +-static void applesmc_device_init(void) ++static void applesmc_device_init(struct applesmc_device *smc) + { + int total; + u8 buffer[2]; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; + + for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { +- if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && ++ if (!applesmc_read_key(smc, MOTION_SENSOR_KEY, buffer, 2) && + (buffer[0] != 0x00 || buffer[1] != 0x00)) + return; + buffer[0] = 0xe0; + buffer[1] = 0x00; +- applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); ++ applesmc_write_key(smc, MOTION_SENSOR_KEY, buffer, 2); + msleep(INIT_WAIT_MSECS); + } + + pr_warn("failed to init the device\n"); + } + +-static int applesmc_init_index(struct applesmc_registers *s) ++static int applesmc_init_index(struct applesmc_device *smc, ++ struct applesmc_registers *s) + { + const struct applesmc_entry *entry; + unsigned int i; +@@ -548,7 +564,7 @@ static int applesmc_init_index(struct applesmc_registers *s) + return -ENOMEM; + + for (i = s->temp_begin; i < s->temp_end; i++) { +- entry = applesmc_get_entry_by_index(i); ++ entry = applesmc_get_entry_by_index(smc, i); + if (IS_ERR(entry)) + continue; + if (strcmp(entry->type, TEMP_SENSOR_TYPE)) +@@ -562,9 +578,9 @@ static int applesmc_init_index(struct applesmc_registers *s) + /* + * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. + */ +-static int applesmc_init_smcreg_try(void) ++static int applesmc_init_smcreg_try(struct applesmc_device *smc) + { +- struct applesmc_registers *s = &smcreg; ++ struct applesmc_registers *s = &smc->reg; + bool left_light_sensor = false, right_light_sensor = false; + unsigned int count; + u8 tmp[1]; +@@ -590,35 +606,35 @@ static int applesmc_init_smcreg_try(void) + if (!s->cache) + return -ENOMEM; + +- ret = applesmc_read_key(FANS_COUNT, tmp, 1); ++ ret = applesmc_read_key(smc, FANS_COUNT, tmp, 1); + if (ret) + return ret; + s->fan_count = tmp[0]; + if (s->fan_count > 10) + s->fan_count = 10; + +- ret = applesmc_get_lower_bound(&s->temp_begin, "T"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_begin, "T"); + if (ret) + return ret; +- ret = applesmc_get_lower_bound(&s->temp_end, "U"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_end, "U"); + if (ret) + return ret; + s->temp_count = s->temp_end - s->temp_begin; + +- ret = applesmc_init_index(s); ++ ret = applesmc_init_index(smc, s); + if (ret) + return ret; + +- ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); ++ ret = applesmc_has_key(smc, MOTION_SENSOR_KEY, &s->has_accelerometer); + if (ret) + return ret; +- ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); ++ ret = applesmc_has_key(smc, BACKLIGHT_KEY, &s->has_key_backlight); + if (ret) + return ret; + +@@ -634,13 +650,13 @@ static int applesmc_init_smcreg_try(void) + return 0; + } + +-static void applesmc_destroy_smcreg(void) ++static void applesmc_destroy_smcreg(struct applesmc_device *smc) + { +- kfree(smcreg.index); +- smcreg.index = NULL; +- kfree(smcreg.cache); +- smcreg.cache = NULL; +- smcreg.init_complete = false; ++ kfree(smc->reg.index); ++ smc->reg.index = NULL; ++ kfree(smc->reg.cache); ++ smc->reg.cache = NULL; ++ smc->reg.init_complete = false; + } + + /* +@@ -649,12 +665,12 @@ static void applesmc_destroy_smcreg(void) + * Retries until initialization is successful, or the operation times out. + * + */ +-static int applesmc_init_smcreg(void) ++static int applesmc_init_smcreg(struct applesmc_device *smc) + { + int ms, ret; + + for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) { +- ret = applesmc_init_smcreg_try(); ++ ret = applesmc_init_smcreg_try(smc); + if (!ret) { + if (ms) + pr_info("init_smcreg() took %d ms\n", ms); +@@ -663,21 +679,58 @@ static int applesmc_init_smcreg(void) + msleep(INIT_WAIT_MSECS); + } + +- applesmc_destroy_smcreg(); ++ applesmc_destroy_smcreg(smc); + + return ret; + } + + /* Device model stuff */ ++static int applesmc_create_modules(struct applesmc_device *smc); ++static void applesmc_destroy_modules(struct applesmc_device *smc); + static int applesmc_probe(struct platform_device *dev) + { ++ struct applesmc_device *smc; + int ret; + +- ret = applesmc_init_smcreg(); ++ smc = kzalloc(sizeof(struct applesmc_device), GFP_KERNEL); ++ if (!smc) ++ return -ENOMEM; ++ smc->dev = dev; ++ mutex_init(&smc->reg.mutex); ++ ++ platform_set_drvdata(dev, smc); ++ ++ ret = applesmc_init_smcreg(smc); + if (ret) +- return ret; ++ goto out_mem; ++ ++ applesmc_device_init(smc); ++ ++ ret = applesmc_create_modules(smc); ++ if (ret) ++ goto out_reg; ++ ++ return 0; ++ ++out_reg: ++ applesmc_destroy_smcreg(smc); ++out_mem: ++ platform_set_drvdata(dev, NULL); ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + +- applesmc_device_init(); ++ return ret; ++} ++ ++static int applesmc_remove(struct platform_device *dev) ++{ ++ struct applesmc_device *smc = platform_get_drvdata(dev); ++ ++ applesmc_destroy_modules(smc); ++ applesmc_destroy_smcreg(smc); ++ ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + + return 0; + } +@@ -685,15 +738,21 @@ static int applesmc_probe(struct platform_device *dev) + /* Synchronize device with memorized backlight state */ + static int applesmc_pm_resume(struct device *dev) + { +- if (smcreg.has_key_backlight) +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ if (smc->reg.has_key_backlight) ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); ++ + return 0; + } + + /* Reinitialize device on resume from hibernation */ + static int applesmc_pm_restore(struct device *dev) + { +- applesmc_device_init(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_device_init(smc); ++ + return applesmc_pm_resume(dev); + } + +@@ -704,6 +763,7 @@ static const struct dev_pm_ops applesmc_pm_ops = { + + static struct platform_driver applesmc_driver = { + .probe = applesmc_probe, ++ .remove = applesmc_remove, + .driver = { + .name = "applesmc", + .pm = &applesmc_pm_ops, +@@ -714,25 +774,26 @@ static struct platform_driver applesmc_driver = { + * applesmc_calibrate - Set our "resting" values. Callers must + * hold applesmc_lock. + */ +-static void applesmc_calibrate(void) ++static void applesmc_calibrate(struct applesmc_device *smc) + { +- applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x); +- applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y); +- rest_x = -rest_x; ++ applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &smc->rest_x); ++ applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &smc->rest_y); ++ smc->rest_x = -smc->rest_x; + } + + static void applesmc_idev_poll(struct input_dev *idev) + { ++ struct applesmc_device *smc = dev_get_drvdata(&idev->dev); + s16 x, y; + +- if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x)) + return; +- if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y)) + return; + + x = -x; +- input_report_abs(idev, ABS_X, x - rest_x); +- input_report_abs(idev, ABS_Y, y - rest_y); ++ input_report_abs(idev, ABS_X, x - smc->rest_x); ++ input_report_abs(idev, ABS_Y, y - smc->rest_y); + input_sync(idev); + } + +@@ -747,16 +808,17 @@ static ssize_t applesmc_name_show(struct device *dev, + static ssize_t applesmc_position_show(struct device *dev, + struct device_attribute *attr, char *buf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + s16 x, y, z; + +- ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Z_KEY, &z); + if (ret) + goto out; + +@@ -770,6 +832,7 @@ static ssize_t applesmc_position_show(struct device *dev, + static ssize_t applesmc_light_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + static int data_length; + int ret; +@@ -777,7 +840,7 @@ static ssize_t applesmc_light_show(struct device *dev, + u8 buffer[10]; + + if (!data_length) { +- entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY); ++ entry = applesmc_get_entry_by_key(smc, LIGHT_SENSOR_LEFT_KEY); + if (IS_ERR(entry)) + return PTR_ERR(entry); + if (entry->len > 10) +@@ -786,7 +849,7 @@ static ssize_t applesmc_light_show(struct device *dev, + pr_info("light sensor data length set to %d\n", data_length); + } + +- ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + if (ret) + goto out; + /* newer macbooks report a single 10-bit bigendian value */ +@@ -796,7 +859,7 @@ static ssize_t applesmc_light_show(struct device *dev, + } + left = buffer[2]; + +- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); + if (ret) + goto out; + right = buffer[2]; +@@ -812,7 +875,8 @@ static ssize_t applesmc_light_show(struct device *dev, + static ssize_t applesmc_show_sensor_label(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + + return sysfs_emit(sysfsbuf, "%s\n", key); + } +@@ -821,12 +885,13 @@ static ssize_t applesmc_show_sensor_label(struct device *dev, + static ssize_t applesmc_show_temperature(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + int ret; + s16 value; + int temp; + +- ret = applesmc_read_s16(key, &value); ++ ret = applesmc_read_s16(smc, key, &value); + if (ret) + return ret; + +@@ -838,6 +903,7 @@ static ssize_t applesmc_show_temperature(struct device *dev, + static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -846,7 +912,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 2); ++ ret = applesmc_read_key(smc, newkey, buffer, 2); + if (ret) + return ret; + +@@ -858,6 +924,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned long speed; + char newkey[5]; +@@ -871,7 +938,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + + buffer[0] = (speed >> 6) & 0xff; + buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(newkey, buffer, 2); ++ ret = applesmc_write_key(smc, newkey, buffer, 2); + + if (ret) + return ret; +@@ -882,11 +949,12 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + static ssize_t applesmc_show_fan_manual(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u16 manual = 0; + u8 buffer[2]; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +@@ -898,6 +966,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; + unsigned long input; +@@ -906,7 +975,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + goto out; + +@@ -920,7 +989,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + buffer[0] = (val >> 8) & 0xFF; + buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); + + out: + if (ret) +@@ -932,13 +1001,14 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + static ssize_t applesmc_show_fan_position(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + char newkey[5]; + u8 buffer[17]; + + scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 16); ++ ret = applesmc_read_key(smc, newkey, buffer, 16); + buffer[16] = 0; + + if (ret) +@@ -950,30 +1020,36 @@ static ssize_t applesmc_show_fan_position(struct device *dev, + static ssize_t applesmc_calibrate_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return sysfs_emit(sysfsbuf, "(%d,%d)\n", rest_x, rest_y); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return sysfs_emit(sysfsbuf, "(%d,%d)\n", smc->rest_x, smc->rest_y); + } + + static ssize_t applesmc_calibrate_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { +- applesmc_calibrate(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_calibrate(smc); + + return count; + } + + static void applesmc_backlight_set(struct work_struct *work) + { +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = container_of(work, struct applesmc_device, backlight_work); ++ ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); + } +-static DECLARE_WORK(backlight_work, &applesmc_backlight_set); + + static void applesmc_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) + { ++ struct applesmc_device *smc = dev_get_drvdata(led_cdev->dev); + int ret; + +- backlight_state[0] = value; +- ret = queue_work(applesmc_led_wq, &backlight_work); ++ smc->backlight_state[0] = value; ++ ret = queue_work(smc->backlight_wq, &smc->backlight_work); + + if (debug && (!ret)) + dev_dbg(led_cdev->dev, "work was already on the queue.\n"); +@@ -982,11 +1058,12 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, + static ssize_t applesmc_key_count_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[4]; + u32 count; + +- ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); ++ ret = applesmc_read_key(smc, KEY_COUNT_KEY, buffer, 4); + if (ret) + return ret; + +@@ -998,13 +1075,14 @@ static ssize_t applesmc_key_count_show(struct device *dev, + static ssize_t applesmc_key_at_index_read_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + int ret; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); +- ret = applesmc_read_entry(entry, sysfsbuf, entry->len); ++ ret = applesmc_read_entry(smc, entry, sysfsbuf, entry->len); + if (ret) + return ret; + +@@ -1014,9 +1092,10 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev, + static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1026,9 +1105,10 @@ static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + static ssize_t applesmc_key_at_index_type_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1038,9 +1118,10 @@ static ssize_t applesmc_key_at_index_type_show(struct device *dev, + static ssize_t applesmc_key_at_index_name_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1050,28 +1131,25 @@ static ssize_t applesmc_key_at_index_name_show(struct device *dev, + static ssize_t applesmc_key_at_index_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return sysfs_emit(sysfsbuf, "%d\n", key_at_index); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return sysfs_emit(sysfsbuf, "%d\n", smc->key_at_index); + } + + static ssize_t applesmc_key_at_index_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + unsigned long newkey; + + if (kstrtoul(sysfsbuf, 10, &newkey) < 0 +- || newkey >= smcreg.key_count) ++ || newkey >= smc->reg.key_count) + return -EINVAL; + +- key_at_index = newkey; ++ smc->key_at_index = newkey; + return count; + } + +-static struct led_classdev applesmc_backlight = { +- .name = "smc::kbd_backlight", +- .default_trigger = "nand-disk", +- .brightness_set = applesmc_brightness_set, +-}; +- + static struct applesmc_node_group info_group[] = { + { "name", applesmc_name_show }, + { "key_count", applesmc_key_count_show }, +@@ -1116,14 +1194,15 @@ static struct applesmc_node_group temp_group[] = { + /* + * applesmc_destroy_nodes - remove files and free associated memory + */ +-static void applesmc_destroy_nodes(struct applesmc_node_group *groups) ++static void applesmc_destroy_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; + + for (grp = groups; grp->nodes; grp++) { + for (node = grp->nodes; node->sda.dev_attr.attr.name; node++) +- sysfs_remove_file(&pdev->dev.kobj, ++ sysfs_remove_file(&smc->dev->dev.kobj, + &node->sda.dev_attr.attr); + kfree(grp->nodes); + grp->nodes = NULL; +@@ -1133,7 +1212,8 @@ static void applesmc_destroy_nodes(struct applesmc_node_group *groups) + /* + * applesmc_create_nodes - create a two-dimensional group of sysfs files + */ +-static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) ++static int applesmc_create_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups, int num) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; +@@ -1157,7 +1237,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + sysfs_attr_init(attr); + attr->name = node->name; + attr->mode = 0444 | (grp->store ? 0200 : 0); +- ret = sysfs_create_file(&pdev->dev.kobj, attr); ++ ret = sysfs_create_file(&smc->dev->dev.kobj, attr); + if (ret) { + attr->name = NULL; + goto out; +@@ -1167,57 +1247,57 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + + return 0; + out: +- applesmc_destroy_nodes(groups); ++ applesmc_destroy_nodes(smc, groups); + return ret; + } + + /* Create accelerometer resources */ +-static int applesmc_create_accelerometer(void) ++static int applesmc_create_accelerometer(struct applesmc_device *smc) + { + int ret; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return 0; + +- ret = applesmc_create_nodes(accelerometer_group, 1); ++ ret = applesmc_create_nodes(smc, accelerometer_group, 1); + if (ret) + goto out; + +- applesmc_idev = input_allocate_device(); +- if (!applesmc_idev) { ++ smc->idev = input_allocate_device(); ++ if (!smc->idev) { + ret = -ENOMEM; + goto out_sysfs; + } + + /* initial calibrate for the input device */ +- applesmc_calibrate(); ++ applesmc_calibrate(smc); + + /* initialize the input device */ +- applesmc_idev->name = "applesmc"; +- applesmc_idev->id.bustype = BUS_HOST; +- applesmc_idev->dev.parent = &pdev->dev; +- input_set_abs_params(applesmc_idev, ABS_X, ++ smc->idev->name = "applesmc"; ++ smc->idev->id.bustype = BUS_HOST; ++ smc->idev->dev.parent = &smc->dev->dev; ++ input_set_abs_params(smc->idev, ABS_X, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); +- input_set_abs_params(applesmc_idev, ABS_Y, ++ input_set_abs_params(smc->idev, ABS_Y, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); + +- ret = input_setup_polling(applesmc_idev, applesmc_idev_poll); ++ ret = input_setup_polling(smc->idev, applesmc_idev_poll); + if (ret) + goto out_idev; + +- input_set_poll_interval(applesmc_idev, APPLESMC_POLL_INTERVAL); ++ input_set_poll_interval(smc->idev, APPLESMC_POLL_INTERVAL); + +- ret = input_register_device(applesmc_idev); ++ ret = input_register_device(smc->idev); + if (ret) + goto out_idev; + + return 0; + + out_idev: +- input_free_device(applesmc_idev); ++ input_free_device(smc->idev); + + out_sysfs: +- applesmc_destroy_nodes(accelerometer_group); ++ applesmc_destroy_nodes(smc, accelerometer_group); + + out: + pr_warn("driver init failed (ret=%d)!\n", ret); +@@ -1225,44 +1305,55 @@ static int applesmc_create_accelerometer(void) + } + + /* Release all resources used by the accelerometer */ +-static void applesmc_release_accelerometer(void) ++static void applesmc_release_accelerometer(struct applesmc_device *smc) + { +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; +- input_unregister_device(applesmc_idev); +- applesmc_destroy_nodes(accelerometer_group); ++ input_unregister_device(smc->idev); ++ applesmc_destroy_nodes(smc, accelerometer_group); + } + +-static int applesmc_create_light_sensor(void) ++static int applesmc_create_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return 0; +- return applesmc_create_nodes(light_sensor_group, 1); ++ return applesmc_create_nodes(smc, light_sensor_group, 1); + } + +-static void applesmc_release_light_sensor(void) ++static void applesmc_release_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return; +- applesmc_destroy_nodes(light_sensor_group); ++ applesmc_destroy_nodes(smc, light_sensor_group); + } + +-static int applesmc_create_key_backlight(void) ++static int applesmc_create_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ int ret; ++ ++ if (!smc->reg.has_key_backlight) + return 0; +- applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); +- if (!applesmc_led_wq) ++ smc->backlight_wq = create_singlethread_workqueue("applesmc-led"); ++ if (!smc->backlight_wq) + return -ENOMEM; +- return led_classdev_register(&pdev->dev, &applesmc_backlight); ++ ++ INIT_WORK(&smc->backlight_work, applesmc_backlight_set); ++ smc->backlight_dev.name = "smc::kbd_backlight"; ++ smc->backlight_dev.default_trigger = "nand-disk"; ++ smc->backlight_dev.brightness_set = applesmc_brightness_set; ++ ret = led_classdev_register(&smc->dev->dev, &smc->backlight_dev); ++ if (ret) ++ destroy_workqueue(smc->backlight_wq); ++ ++ return ret; + } + +-static void applesmc_release_key_backlight(void) ++static void applesmc_release_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ if (!smc->reg.has_key_backlight) + return; +- led_classdev_unregister(&applesmc_backlight); +- destroy_workqueue(applesmc_led_wq); ++ led_classdev_unregister(&smc->backlight_dev); ++ destroy_workqueue(smc->backlight_wq); + } + + static int applesmc_dmi_match(const struct dmi_system_id *id) +@@ -1306,86 +1397,100 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = { + { .ident = NULL } + }; + +-static int __init applesmc_init(void) ++static int applesmc_create_modules(struct applesmc_device *smc) + { + int ret; + +- if (!dmi_check_system(applesmc_whitelist)) { +- pr_warn("supported laptop not found!\n"); +- ret = -ENODEV; +- goto out; +- } +- +- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, +- "applesmc")) { +- ret = -ENXIO; +- goto out; +- } +- +- ret = platform_driver_register(&applesmc_driver); +- if (ret) +- goto out_region; +- +- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, +- NULL, 0); +- if (IS_ERR(pdev)) { +- ret = PTR_ERR(pdev); +- goto out_driver; +- } +- +- /* create register cache */ +- ret = applesmc_init_smcreg(); +- if (ret) +- goto out_device; +- +- ret = applesmc_create_nodes(info_group, 1); ++ ret = applesmc_create_nodes(smc, info_group, 1); + if (ret) +- goto out_smcreg; ++ goto out; + +- ret = applesmc_create_nodes(fan_group, smcreg.fan_count); ++ ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count); + if (ret) + goto out_info; + +- ret = applesmc_create_nodes(temp_group, smcreg.index_count); ++ ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count); + if (ret) + goto out_fans; + +- ret = applesmc_create_accelerometer(); ++ ret = applesmc_create_accelerometer(smc); + if (ret) + goto out_temperature; + +- ret = applesmc_create_light_sensor(); ++ ret = applesmc_create_light_sensor(smc); + if (ret) + goto out_accelerometer; + +- ret = applesmc_create_key_backlight(); ++ ret = applesmc_create_key_backlight(smc); + if (ret) + goto out_light_sysfs; + +- hwmon_dev = hwmon_device_register(&pdev->dev); +- if (IS_ERR(hwmon_dev)) { +- ret = PTR_ERR(hwmon_dev); ++ smc->hwmon_dev = hwmon_device_register(&smc->dev->dev); ++ if (IS_ERR(smc->hwmon_dev)) { ++ ret = PTR_ERR(smc->hwmon_dev); + goto out_light_ledclass; + } + + return 0; + + out_light_ledclass: +- applesmc_release_key_backlight(); ++ applesmc_release_key_backlight(smc); + out_light_sysfs: +- applesmc_release_light_sensor(); ++ applesmc_release_light_sensor(smc); + out_accelerometer: +- applesmc_release_accelerometer(); ++ applesmc_release_accelerometer(smc); + out_temperature: +- applesmc_destroy_nodes(temp_group); ++ applesmc_destroy_nodes(smc, temp_group); + out_fans: +- applesmc_destroy_nodes(fan_group); ++ applesmc_destroy_nodes(smc, fan_group); + out_info: +- applesmc_destroy_nodes(info_group); +-out_smcreg: +- applesmc_destroy_smcreg(); +-out_device: +- platform_device_unregister(pdev); ++ applesmc_destroy_nodes(smc, info_group); ++out: ++ return ret; ++} ++ ++static void applesmc_destroy_modules(struct applesmc_device *smc) ++{ ++ hwmon_device_unregister(smc->hwmon_dev); ++ applesmc_release_key_backlight(smc); ++ applesmc_release_light_sensor(smc); ++ applesmc_release_accelerometer(smc); ++ applesmc_destroy_nodes(smc, temp_group); ++ applesmc_destroy_nodes(smc, fan_group); ++ applesmc_destroy_nodes(smc, info_group); ++} ++ ++static struct platform_device *pdev; ++ ++static int __init applesmc_init(void) ++{ ++ int ret; ++ ++ if (!dmi_check_system(applesmc_whitelist)) { ++ pr_warn("supported laptop not found!\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, ++ "applesmc")) { ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ ret = platform_driver_register(&applesmc_driver); ++ if (ret) ++ goto out_region; ++ ++ pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, ++ NULL, 0); ++ if (IS_ERR(pdev)) { ++ ret = PTR_ERR(pdev); ++ goto out_driver; ++ } ++ ++ return 0; ++ + out_driver: + platform_driver_unregister(&applesmc_driver); + out_region: +@@ -1397,14 +1502,6 @@ static int __init applesmc_init(void) + + static void __exit applesmc_exit(void) + { +- hwmon_device_unregister(hwmon_dev); +- applesmc_release_key_backlight(); +- applesmc_release_light_sensor(); +- applesmc_release_accelerometer(); +- applesmc_destroy_nodes(temp_group); +- applesmc_destroy_nodes(fan_group); +- applesmc_destroy_nodes(info_group); +- applesmc_destroy_smcreg(); + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); + release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); +@@ -1414,6 +1511,7 @@ module_init(applesmc_init); + module_exit(applesmc_exit); + + MODULE_AUTHOR("Nicolas Boichat"); ++MODULE_AUTHOR("Paul Pawlowski"); + MODULE_DESCRIPTION("Apple SMC"); + MODULE_LICENSE("GPL v2"); + MODULE_DEVICE_TABLE(dmi, applesmc_whitelist); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3002-applesmc-make-io-port-base-addr-dynamic.patch b/patch/kernel/archive/uefi-x86-6.18/3002-applesmc-make-io-port-base-addr-dynamic.patch new file mode 100644 index 000000000..c6640a593 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3002-applesmc-make-io-port-base-addr-dynamic.patch @@ -0,0 +1,312 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:11:56 +0100 +Subject: applesmc: make io port base addr dynamic + +This change makes the port base runtime configurable. +The reason why this change is made is so that when we switch to an +acpi_device we can resolve the port base addr from ACPI. + +This change is not strictly required for T2 support - the base +address is still 0x300 on T2 Macs. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 91 +++++----- + 1 file changed, 49 insertions(+), 42 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -35,10 +35,11 @@ + #include + #include + ++#define APPLESMC_PORT_BASE 0x300 + /* data port used by Apple SMC */ +-#define APPLESMC_DATA_PORT 0x300 ++#define APPLESMC_DATA_PORT 0 + /* command/status port used by Apple SMC */ +-#define APPLESMC_CMD_PORT 0x304 ++#define APPLESMC_CMD_PORT 4 + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + +@@ -140,6 +141,8 @@ struct applesmc_device { + struct platform_device *dev; + struct applesmc_registers reg; + ++ u16 port_base; ++ + s16 rest_x; + s16 rest_y; + +@@ -169,7 +172,7 @@ static const int debug; + * run out past 500ms. + */ + +-static int wait_status(u8 val, u8 mask) ++static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) + { + u8 status; + int us; +@@ -177,7 +180,7 @@ static int wait_status(u8 val, u8 mask) + + us = APPLESMC_MIN_WAIT; + for (i = 0; i < 24 ; i++) { +- status = inb(APPLESMC_CMD_PORT); ++ status = inb(smc->port_base + APPLESMC_CMD_PORT); + if ((status & mask) == val) + return 0; + usleep_range(us, us * 2); +@@ -189,11 +192,11 @@ static int wait_status(u8 val, u8 mask) + + /* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ + +-static int send_byte(u8 cmd, u16 port) ++static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + { + int status; + +- status = wait_status(0, SMC_STATUS_IB_CLOSED); ++ status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (status) + return status; + /* +@@ -202,24 +205,24 @@ static int send_byte(u8 cmd, u16 port) + * this extra read may not happen if status returns both + * simultaneously and this would appear to be required. + */ +- status = wait_status(SMC_STATUS_BUSY, SMC_STATUS_BUSY); ++ status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); + if (status) + return status; + +- outb(cmd, port); ++ outb(cmd, smc->port_base + port); + return 0; + } + + /* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ + +-static int send_command(u8 cmd) ++static int send_command(struct applesmc_device *smc, u8 cmd) + { + int ret; + +- ret = wait_status(0, SMC_STATUS_IB_CLOSED); ++ ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (ret) + return ret; +- outb(cmd, APPLESMC_CMD_PORT); ++ outb(cmd, smc->port_base + APPLESMC_CMD_PORT); + return 0; + } + +@@ -229,108 +232,112 @@ static int send_command(u8 cmd) + * If busy is stuck high after the command then the SMC is jammed. + */ + +-static int smc_sane(void) ++static int smc_sane(struct applesmc_device *smc) + { + int ret; + +- ret = wait_status(0, SMC_STATUS_BUSY); ++ ret = wait_status(smc, 0, SMC_STATUS_BUSY); + if (!ret) + return ret; +- ret = send_command(APPLESMC_READ_CMD); ++ ret = send_command(smc, APPLESMC_READ_CMD); + if (ret) + return ret; +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int send_argument(const char *key) ++static int send_argument(struct applesmc_device *smc, const char *key) + { + int i; + + for (i = 0; i < 4; i++) +- if (send_byte(key[i], APPLESMC_DATA_PORT)) ++ if (send_byte(smc, key[i], APPLESMC_DATA_PORT)) + return -EIO; + return 0; + } + +-static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) ++static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ u8 *buffer, u8 len) + { + u8 status, data = 0; + int i; + int ret; + +- ret = smc_sane(); ++ ret = smc_sane(smc); + if (ret) + return ret; + +- if (send_command(cmd) || send_argument(key)) { ++ if (send_command(smc, cmd) || send_argument(smc, key)) { + pr_warn("%.4s: read arg fail\n", key); + return -EIO; + } + + /* This has no effect on newer (2012) SMCs */ +- if (send_byte(len, APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (wait_status(SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, ++ if (wait_status(smc, ++ SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) { + pr_warn("%.4s: read data[%d] fail\n", key, i); + return -EIO; + } +- buffer[i] = inb(APPLESMC_DATA_PORT); ++ buffer[i] = inb(smc->port_base + APPLESMC_DATA_PORT); + } + + /* Read the data port until bit0 is cleared */ + for (i = 0; i < 16; i++) { + udelay(APPLESMC_MIN_WAIT); +- status = inb(APPLESMC_CMD_PORT); ++ status = inb(smc->port_base + APPLESMC_CMD_PORT); + if (!(status & SMC_STATUS_AWAITING_DATA)) + break; +- data = inb(APPLESMC_DATA_PORT); ++ data = inb(smc->port_base + APPLESMC_DATA_PORT); + } + if (i) + pr_warn("flushed %d bytes, last value is: %d\n", i, data); + +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len) ++static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ const u8 *buffer, u8 len) + { + int i; + int ret; + +- ret = smc_sane(); ++ ret = smc_sane(smc); + if (ret) + return ret; + +- if (send_command(cmd) || send_argument(key)) { ++ if (send_command(smc, cmd) || send_argument(smc, key)) { + pr_warn("%s: write arg fail\n", key); + return -EIO; + } + +- if (send_byte(len, APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: write len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (send_byte(buffer[i], APPLESMC_DATA_PORT)) { ++ if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { + pr_warn("%s: write data fail\n", key); + return -EIO; + } + } + +- return wait_status(0, SMC_STATUS_BUSY); ++ return wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int read_register_count(unsigned int *count) ++static int read_register_count(struct applesmc_device *smc, ++ unsigned int *count) + { + __be32 be; + int ret; + +- ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); ++ ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); + if (ret) + return ret; + +@@ -353,7 +360,7 @@ static int applesmc_read_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); ++ ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + + return ret; +@@ -367,7 +374,7 @@ static int applesmc_write_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); ++ ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + return ret; + } +@@ -388,10 +395,10 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + if (cache->valid) + goto out; + be = cpu_to_be32(index); +- ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); ++ ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); + if (ret) + goto out; +- ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); ++ ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); + if (ret) + goto out; + +@@ -589,7 +596,7 @@ static int applesmc_init_smcreg_try(struct applesmc_device *smc) + if (s->init_complete) + return 0; + +- ret = read_register_count(&count); ++ ret = read_register_count(smc, &count); + if (ret) + return ret; + +@@ -1472,7 +1479,7 @@ static int __init applesmc_init(void) + goto out; + } + +- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, ++ if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS, + "applesmc")) { + ret = -ENXIO; + goto out; +@@ -1494,7 +1501,7 @@ static int __init applesmc_init(void) + out_driver: + platform_driver_unregister(&applesmc_driver); + out_region: +- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); ++ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + out: + pr_warn("driver init failed (ret=%d)!\n", ret); + return ret; +@@ -1504,7 +1511,7 @@ static void __exit applesmc_exit(void) + { + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); +- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); ++ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + } + + module_init(applesmc_init); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3003-applesmc-switch-to-acpi_device-from-platform.patch b/patch/kernel/archive/uefi-x86-6.18/3003-applesmc-switch-to-acpi_device-from-platform.patch new file mode 100644 index 000000000..21b04a5a5 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3003-applesmc-switch-to-acpi_device-from-platform.patch @@ -0,0 +1,265 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sat, 29 Jun 2024 04:49:16 +0000 +Subject: applesmc: switch to acpi_device (from platform) + +This change makes the change from platform_device +to acpi_device. The rationale for this change is +that on T2 Macs, an additional FixedMemory32 +region is needed for device operation, and it can +be easily resolved via ACPI tables (this will be +done in another commit). + +Additionally, on older Macs, the OS X driver also +looks for the specified ACPI device to resolve +its memory regions, and therefore this change +should not result in any incompatibilities. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 124 +++++++--- + 1 file changed, 84 insertions(+), 40 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -19,7 +19,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include +-#include ++#include + #include + #include + #include +@@ -35,7 +35,6 @@ + #include + #include + +-#define APPLESMC_PORT_BASE 0x300 + /* data port used by Apple SMC */ + #define APPLESMC_DATA_PORT 0 + /* command/status port used by Apple SMC */ +@@ -138,9 +137,10 @@ struct applesmc_registers { + }; + + struct applesmc_device { +- struct platform_device *dev; ++ struct acpi_device *dev; + struct applesmc_registers reg; + ++ bool port_base_set; + u16 port_base; + + s16 rest_x; +@@ -692,9 +692,13 @@ static int applesmc_init_smcreg(struct applesmc_device *smc) + } + + /* Device model stuff */ ++ ++static int applesmc_init_resources(struct applesmc_device *smc); ++static void applesmc_free_resources(struct applesmc_device *smc); + static int applesmc_create_modules(struct applesmc_device *smc); + static void applesmc_destroy_modules(struct applesmc_device *smc); +-static int applesmc_probe(struct platform_device *dev) ++ ++static int applesmc_add(struct acpi_device *dev) + { + struct applesmc_device *smc; + int ret; +@@ -705,12 +709,16 @@ static int applesmc_probe(struct platform_device *dev) + smc->dev = dev; + mutex_init(&smc->reg.mutex); + +- platform_set_drvdata(dev, smc); ++ dev_set_drvdata(&dev->dev, smc); + +- ret = applesmc_init_smcreg(smc); ++ ret = applesmc_init_resources(smc); + if (ret) + goto out_mem; + ++ ret = applesmc_init_smcreg(smc); ++ if (ret) ++ goto out_res; ++ + applesmc_device_init(smc); + + ret = applesmc_create_modules(smc); +@@ -721,20 +729,23 @@ static int applesmc_probe(struct platform_device *dev) + + out_reg: + applesmc_destroy_smcreg(smc); ++out_res: ++ applesmc_free_resources(smc); + out_mem: +- platform_set_drvdata(dev, NULL); ++ dev_set_drvdata(&dev->dev, NULL); + mutex_destroy(&smc->reg.mutex); + kfree(smc); + + return ret; + } + +-static int applesmc_remove(struct platform_device *dev) ++static int applesmc_remove(struct acpi_device *dev) + { +- struct applesmc_device *smc = platform_get_drvdata(dev); ++ struct applesmc_device *smc = dev_get_drvdata(&dev->dev); + + applesmc_destroy_modules(smc); + applesmc_destroy_smcreg(smc); ++ applesmc_free_resources(smc); + + mutex_destroy(&smc->reg.mutex); + kfree(smc); +@@ -742,6 +753,52 @@ static int applesmc_remove(struct platform_device *dev) + return 0; + } + ++static acpi_status applesmc_walk_resources(struct acpi_resource *res, ++ void *data) ++{ ++ struct applesmc_device *smc = data; ++ ++ switch (res->type) { ++ case ACPI_RESOURCE_TYPE_IO: ++ if (!smc->port_base_set) { ++ if (res->data.io.address_length < APPLESMC_NR_PORTS) ++ return AE_ERROR; ++ smc->port_base = res->data.io.minimum; ++ smc->port_base_set = true; ++ } ++ return AE_OK; ++ ++ case ACPI_RESOURCE_TYPE_END_TAG: ++ if (smc->port_base_set) ++ return AE_OK; ++ else ++ return AE_NOT_FOUND; ++ ++ default: ++ return AE_OK; ++ } ++} ++ ++static int applesmc_init_resources(struct applesmc_device *smc) ++{ ++ int ret; ++ ++ ret = acpi_walk_resources(smc->dev->handle, METHOD_NAME__CRS, ++ applesmc_walk_resources, smc); ++ if (ACPI_FAILURE(ret)) ++ return -ENXIO; ++ ++ if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc")) ++ return -ENXIO; ++ ++ return 0; ++} ++ ++static void applesmc_free_resources(struct applesmc_device *smc) ++{ ++ release_region(smc->port_base, APPLESMC_NR_PORTS); ++} ++ + /* Synchronize device with memorized backlight state */ + static int applesmc_pm_resume(struct device *dev) + { +@@ -763,17 +820,26 @@ static int applesmc_pm_restore(struct device *dev) + return applesmc_pm_resume(dev); + } + ++static const struct acpi_device_id applesmc_ids[] = { ++ {"APP0001", 0}, ++ {"", 0}, ++}; ++ + static const struct dev_pm_ops applesmc_pm_ops = { + .resume = applesmc_pm_resume, + .restore = applesmc_pm_restore, + }; + +-static struct platform_driver applesmc_driver = { +- .probe = applesmc_probe, +- .remove = applesmc_remove, +- .driver = { +- .name = "applesmc", +- .pm = &applesmc_pm_ops, ++static struct acpi_driver applesmc_driver = { ++ .name = "applesmc", ++ .class = "applesmc", ++ .ids = applesmc_ids, ++ .ops = { ++ .add = applesmc_add, ++ .remove = applesmc_remove ++ }, ++ .drv = { ++ .pm = &applesmc_pm_ops + }, + }; + +@@ -1262,7 +1328,6 @@ static int applesmc_create_nodes(struct applesmc_device *smc, + static int applesmc_create_accelerometer(struct applesmc_device *smc) + { + int ret; +- + if (!smc->reg.has_accelerometer) + return 0; + +@@ -1467,8 +1532,6 @@ static void applesmc_destroy_modules(struct applesmc_device *smc) + applesmc_destroy_nodes(smc, info_group); + } + +-static struct platform_device *pdev; +- + static int __init applesmc_init(void) + { + int ret; +@@ -1479,29 +1542,12 @@ static int __init applesmc_init(void) + goto out; + } + +- if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS, +- "applesmc")) { +- ret = -ENXIO; +- goto out; +- } +- +- ret = platform_driver_register(&applesmc_driver); ++ ret = acpi_bus_register_driver(&applesmc_driver); + if (ret) +- goto out_region; +- +- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT, +- NULL, 0); +- if (IS_ERR(pdev)) { +- ret = PTR_ERR(pdev); +- goto out_driver; +- } ++ goto out; + + return 0; + +-out_driver: +- platform_driver_unregister(&applesmc_driver); +-out_region: +- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); + out: + pr_warn("driver init failed (ret=%d)!\n", ret); + return ret; +@@ -1509,9 +1555,7 @@ static int __init applesmc_init(void) + + static void __exit applesmc_exit(void) + { +- platform_device_unregister(pdev); +- platform_driver_unregister(&applesmc_driver); +- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS); ++ acpi_bus_unregister_driver(&applesmc_driver); + } + + module_init(applesmc_init); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3004-applesmc-key-interface-wrappers.patch b/patch/kernel/archive/uefi-x86-6.18/3004-applesmc-key-interface-wrappers.patch new file mode 100644 index 000000000..ad7e3105f --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3004-applesmc-key-interface-wrappers.patch @@ -0,0 +1,298 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:14 +0100 +Subject: applesmc: key interface wrappers + +This change replaces the read_smc and write_smc +methods with wrappers, additionally removing the +command id parameter from them (and introducing +get_smc_key_by_index and get_smc_key_info). + +This is done as to allow simple implementation +replacement on T2 Macs. The newly introduced +methods mentioned in the previous paragraph need +special handling on T2 and as such had to be +separated. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 119 ++++++---- + 1 file changed, 79 insertions(+), 40 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -172,7 +172,7 @@ static const int debug; + * run out past 500ms. + */ + +-static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) ++static int port_wait_status(struct applesmc_device *smc, u8 val, u8 mask) + { + u8 status; + int us; +@@ -190,13 +190,13 @@ static int wait_status(struct applesmc_device *smc, u8 val, u8 mask) + return -EIO; + } + +-/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ ++/* port_send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ + +-static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) ++static int port_send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + { + int status; + +- status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); ++ status = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (status) + return status; + /* +@@ -205,7 +205,7 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + * this extra read may not happen if status returns both + * simultaneously and this would appear to be required. + */ +- status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); ++ status = port_wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY); + if (status) + return status; + +@@ -213,15 +213,16 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port) + return 0; + } + +-/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ ++/* port_send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ + +-static int send_command(struct applesmc_device *smc, u8 cmd) ++static int port_send_command(struct applesmc_device *smc, u8 cmd) + { + int ret; + +- ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED); ++ ret = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED); + if (ret) + return ret; ++ + outb(cmd, smc->port_base + APPLESMC_CMD_PORT); + return 0; + } +@@ -232,53 +233,53 @@ static int send_command(struct applesmc_device *smc, u8 cmd) + * If busy is stuck high after the command then the SMC is jammed. + */ + +-static int smc_sane(struct applesmc_device *smc) ++static int port_smc_sane(struct applesmc_device *smc) + { + int ret; + +- ret = wait_status(smc, 0, SMC_STATUS_BUSY); ++ ret = port_wait_status(smc, 0, SMC_STATUS_BUSY); + if (!ret) + return ret; +- ret = send_command(smc, APPLESMC_READ_CMD); ++ ret = port_send_command(smc, APPLESMC_READ_CMD); + if (ret) + return ret; +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int send_argument(struct applesmc_device *smc, const char *key) ++static int port_send_argument(struct applesmc_device *smc, const char *key) + { + int i; + + for (i = 0; i < 4; i++) +- if (send_byte(smc, key[i], APPLESMC_DATA_PORT)) ++ if (port_send_byte(smc, key[i], APPLESMC_DATA_PORT)) + return -EIO; + return 0; + } + +-static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++static int port_read_smc(struct applesmc_device *smc, u8 cmd, const char *key, + u8 *buffer, u8 len) + { + u8 status, data = 0; + int i; + int ret; + +- ret = smc_sane(smc); ++ ret = port_smc_sane(smc); + if (ret) + return ret; + +- if (send_command(smc, cmd) || send_argument(smc, key)) { ++ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) { + pr_warn("%.4s: read arg fail\n", key); + return -EIO; + } + + /* This has no effect on newer (2012) SMCs */ +- if (send_byte(smc, len, APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (wait_status(smc, ++ if (port_wait_status(smc, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY, + SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) { + pr_warn("%.4s: read data[%d] fail\n", key, i); +@@ -298,37 +299,80 @@ static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key, + if (i) + pr_warn("flushed %d bytes, last value is: %d\n", i, data); + +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); + } + +-static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++static int port_write_smc(struct applesmc_device *smc, u8 cmd, const char *key, + const u8 *buffer, u8 len) + { + int i; + int ret; + +- ret = smc_sane(smc); ++ ret = port_smc_sane(smc); + if (ret) + return ret; + +- if (send_command(smc, cmd) || send_argument(smc, key)) { ++ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) { + pr_warn("%s: write arg fail\n", key); + return -EIO; + } + +- if (send_byte(smc, len, APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: write len fail\n", key); + return -EIO; + } + + for (i = 0; i < len; i++) { +- if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { ++ if (port_send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) { + pr_warn("%s: write data fail\n", key); + return -EIO; + } + } + +- return wait_status(smc, 0, SMC_STATUS_BUSY); ++ return port_wait_status(smc, 0, SMC_STATUS_BUSY); ++} ++ ++static int port_get_smc_key_info(struct applesmc_device *smc, ++ const char *key, struct applesmc_entry *info) ++{ ++ int ret; ++ u8 raw[6]; ++ ++ ret = port_read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, raw, 6); ++ if (ret) ++ return ret; ++ info->len = raw[0]; ++ memcpy(info->type, &raw[1], 4); ++ info->flags = raw[5]; ++ return 0; ++} ++ ++static int read_smc(struct applesmc_device *smc, const char *key, ++ u8 *buffer, u8 len) ++{ ++ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++} ++ ++static int write_smc(struct applesmc_device *smc, const char *key, ++ const u8 *buffer, u8 len) ++{ ++ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++} ++ ++static int get_smc_key_by_index(struct applesmc_device *smc, ++ unsigned int index, char *key) ++{ ++ __be32 be; ++ ++ be = cpu_to_be32(index); ++ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); ++} ++ ++static int get_smc_key_info(struct applesmc_device *smc, const char *key, ++ struct applesmc_entry *info) ++{ ++ return port_get_smc_key_info(smc, key, info); + } + + static int read_register_count(struct applesmc_device *smc, +@@ -337,8 +381,8 @@ static int read_register_count(struct applesmc_device *smc, + __be32 be; + int ret; + +- ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); +- if (ret) ++ ret = read_smc(smc, KEY_COUNT_KEY, (u8 *)&be, 4); ++ if (ret < 0) + return ret; + + *count = be32_to_cpu(be); +@@ -360,7 +404,7 @@ static int applesmc_read_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len); ++ ret = read_smc(smc, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + + return ret; +@@ -374,7 +418,7 @@ static int applesmc_write_entry(struct applesmc_device *smc, + if (entry->len != len) + return -EINVAL; + mutex_lock(&smc->reg.mutex); +- ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len); ++ ret = write_smc(smc, entry->key, buf, len); + mutex_unlock(&smc->reg.mutex); + return ret; + } +@@ -383,8 +427,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + struct applesmc_device *smc, int index) + { + struct applesmc_entry *cache = &smc->reg.cache[index]; +- u8 key[4], info[6]; +- __be32 be; ++ char key[4]; + int ret = 0; + + if (cache->valid) +@@ -394,18 +437,14 @@ static const struct applesmc_entry *applesmc_get_entry_by_index( + + if (cache->valid) + goto out; +- be = cpu_to_be32(index); +- ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); ++ ret = get_smc_key_by_index(smc, index, key); + if (ret) + goto out; +- ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); ++ memcpy(cache->key, key, 4); ++ ++ ret = get_smc_key_info(smc, key, cache); + if (ret) + goto out; +- +- memcpy(cache->key, key, 4); +- cache->len = info[0]; +- memcpy(cache->type, &info[1], 4); +- cache->flags = info[5]; + cache->valid = true; + + out: +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3005-applesmc-basic-mmio-interface-implementation.patch b/patch/kernel/archive/uefi-x86-6.18/3005-applesmc-basic-mmio-interface-implementation.patch new file mode 100644 index 000000000..230656989 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3005-applesmc-basic-mmio-interface-implementation.patch @@ -0,0 +1,343 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 17 Nov 2019 23:12:16 +0100 +Subject: applesmc: basic mmio interface implementation + +This change introduces a basic MMIO-based +interface implementation required to communicate +with the SMC on T2 Macs. The MMIO interface is +enabled only when it's supported on the running +system. + +The MMIO interface replaces legacy port-based SMC +key reads, writes and metadata requests (getting +key by index and getting key info). + +(Based on patch by @mcmrarm) + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 237 +++++++++- + 1 file changed, 231 insertions(+), 6 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -42,6 +42,18 @@ + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + ++#define APPLESMC_IOMEM_KEY_DATA 0 ++#define APPLESMC_IOMEM_KEY_STATUS 0x4005 ++#define APPLESMC_IOMEM_KEY_NAME 0x78 ++#define APPLESMC_IOMEM_KEY_DATA_LEN 0x7D ++#define APPLESMC_IOMEM_KEY_SMC_ID 0x7E ++#define APPLESMC_IOMEM_KEY_CMD 0x7F ++#define APPLESMC_IOMEM_MIN_SIZE 0x4006 ++ ++#define APPLESMC_IOMEM_KEY_TYPE_CODE 0 ++#define APPLESMC_IOMEM_KEY_TYPE_DATA_LEN 5 ++#define APPLESMC_IOMEM_KEY_TYPE_FLAGS 6 ++ + #define APPLESMC_MAX_DATA_LENGTH 32 + + /* Apple SMC status bits */ +@@ -138,10 +150,13 @@ struct applesmc_registers { + + struct applesmc_device { + struct acpi_device *dev; ++ struct device *ldev; + struct applesmc_registers reg; + +- bool port_base_set; ++ bool port_base_set, iomem_base_set; + u16 port_base; ++ u8 *__iomem iomem_base; ++ u32 iomem_base_addr, iomem_base_size; + + s16 rest_x; + s16 rest_y; +@@ -347,16 +362,156 @@ static int port_get_smc_key_info(struct applesmc_device *smc, + return 0; + } + ++ ++/* ++ * MMIO based communication. ++ * TODO: Use updated mechanism for cmd timeout/retry ++ */ ++ ++static void iomem_clear_status(struct applesmc_device *smc) ++{ ++ if (ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS)) ++ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++} ++ ++static int iomem_wait_read(struct applesmc_device *smc) ++{ ++ u8 status; ++ int us; ++ int i; ++ ++ us = APPLESMC_MIN_WAIT; ++ for (i = 0; i < 24 ; i++) { ++ status = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (status & 0x20) ++ return 0; ++ usleep_range(us, us * 2); ++ if (i > 9) ++ us <<= 1; ++ } ++ ++ dev_warn(smc->ldev, "%s... timeout\n", __func__); ++ return -EIO; ++} ++ ++static int iomem_read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ u8 *buffer, u8 len) ++{ ++ u8 err, remote_len; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "read_smc_mmio(%x %8x/%.4s) failed: %u\n", ++ cmd, key_int, key, err); ++ return -EIO; ++ } ++ ++ if (cmd == APPLESMC_READ_CMD) { ++ remote_len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ if (remote_len != len) { ++ dev_warn(smc->ldev, ++ "read_smc_mmio(%x %8x/%.4s) failed: buffer length mismatch (remote = %u, requested = %u)\n", ++ cmd, key_int, key, remote_len, len); ++ return -EINVAL; ++ } ++ } else { ++ remote_len = len; ++ } ++ ++ memcpy_fromio(buffer, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, ++ remote_len); ++ ++ dev_dbg(smc->ldev, "read_smc_mmio(%x %8x/%.4s): buflen=%u reslen=%u\n", ++ cmd, key_int, key, len, remote_len); ++ print_hex_dump_bytes("read_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, remote_len); ++ return 0; ++} ++ ++static int iomem_get_smc_key_type(struct applesmc_device *smc, const char *key, ++ struct applesmc_entry *e) ++{ ++ u8 err; ++ u8 cmd = APPLESMC_GET_KEY_TYPE_CMD; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "get_smc_key_type_mmio(%.4s) failed: %u\n", key, err); ++ return -EIO; ++ } ++ ++ e->len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_DATA_LEN); ++ *((uint32_t *) e->type) = ioread32( ++ smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_CODE); ++ e->flags = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_FLAGS); ++ ++ dev_dbg(smc->ldev, "get_smc_key_type_mmio(%.4s): len=%u type=%.4s flags=%x\n", ++ key, e->len, e->type, e->flags); ++ return 0; ++} ++ ++static int iomem_write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ const u8 *buffer, u8 len) ++{ ++ u8 err; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ memcpy_toio(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, buffer, len); ++ iowrite32(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "write_smc_mmio(%x %.4s) failed: %u\n", cmd, key, err); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return -EIO; ++ } ++ ++ dev_dbg(smc->ldev, "write_smc_mmio(%x %.4s): buflen=%u\n", cmd, key, len); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return 0; ++} ++ ++ + static int read_smc(struct applesmc_device *smc, const char *key, + u8 *buffer, u8 len) + { +- return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ else ++ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); + } + + static int write_smc(struct applesmc_device *smc, const char *key, + const u8 *buffer, u8 len) + { +- return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ else ++ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); + } + + static int get_smc_key_by_index(struct applesmc_device *smc, +@@ -365,14 +520,21 @@ static int get_smc_key_by_index(struct applesmc_device *smc, + __be32 be; + + be = cpu_to_be32(index); +- return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, +- (const char *) &be, (u8 *) key, 4); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); ++ else ++ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); + } + + static int get_smc_key_info(struct applesmc_device *smc, const char *key, + struct applesmc_entry *info) + { +- return port_get_smc_key_info(smc, key, info); ++ if (smc->iomem_base_set) ++ return iomem_get_smc_key_type(smc, key, info); ++ else ++ return port_get_smc_key_info(smc, key, info); + } + + static int read_register_count(struct applesmc_device *smc, +@@ -746,6 +908,7 @@ static int applesmc_add(struct acpi_device *dev) + if (!smc) + return -ENOMEM; + smc->dev = dev; ++ smc->ldev = &dev->dev; + mutex_init(&smc->reg.mutex); + + dev_set_drvdata(&dev->dev, smc); +@@ -807,6 +970,20 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + return AE_OK; + ++ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: ++ if (!smc->iomem_base_set) { ++ if (res->data.fixed_memory32.address_length < ++ APPLESMC_IOMEM_MIN_SIZE) { ++ dev_warn(smc->ldev, "found iomem but it's too small: %u\n", ++ res->data.fixed_memory32.address_length); ++ return AE_OK; ++ } ++ smc->iomem_base_addr = res->data.fixed_memory32.address; ++ smc->iomem_base_size = res->data.fixed_memory32.address_length; ++ smc->iomem_base_set = true; ++ } ++ return AE_OK; ++ + case ACPI_RESOURCE_TYPE_END_TAG: + if (smc->port_base_set) + return AE_OK; +@@ -818,6 +995,8 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc); ++ + static int applesmc_init_resources(struct applesmc_device *smc) + { + int ret; +@@ -830,11 +1009,57 @@ static int applesmc_init_resources(struct applesmc_device *smc) + if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc")) + return -ENXIO; + ++ if (smc->iomem_base_set) { ++ if (applesmc_try_enable_iomem(smc)) ++ smc->iomem_base_set = false; ++ } ++ + return 0; + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc) ++{ ++ u8 test_val, ldkn_version; ++ ++ dev_dbg(smc->ldev, "Trying to enable iomem based communication\n"); ++ smc->iomem_base = ioremap(smc->iomem_base_addr, smc->iomem_base_size); ++ if (!smc->iomem_base) ++ goto out; ++ ++ /* Apple's driver does this check for some reason */ ++ test_val = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (test_val == 0xff) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: initial status is 0xff (is %x)\n", ++ test_val); ++ goto out_iomem; ++ } ++ ++ if (read_smc(smc, "LDKN", &ldkn_version, 1)) { ++ dev_warn(smc->ldev, "iomem enable failed: ldkn read failed\n"); ++ goto out_iomem; ++ } ++ ++ if (ldkn_version < 2) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: ldkn version %u is less than minimum (2)\n", ++ ldkn_version); ++ goto out_iomem; ++ } ++ ++ return 0; ++ ++out_iomem: ++ iounmap(smc->iomem_base); ++ ++out: ++ return -ENXIO; ++} ++ + static void applesmc_free_resources(struct applesmc_device *smc) + { ++ if (smc->iomem_base_set) ++ iounmap(smc->iomem_base); + release_region(smc->port_base, APPLESMC_NR_PORTS); + } + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3006-applesmc-fan-support-on-T2-Macs.patch b/patch/kernel/archive/uefi-x86-6.18/3006-applesmc-fan-support-on-T2-Macs.patch new file mode 100644 index 000000000..4d2cbb318 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3006-applesmc-fan-support-on-T2-Macs.patch @@ -0,0 +1,227 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:18 +0100 +Subject: applesmc: fan support on T2 Macs + +T2 Macs changed the fan values from shorts to +floats, and changed the fan manual override +setting from a bitmask to a per-fan boolean +named F0Md (thanks to @kleuter for mentioning +it). + +A minimal soft-float implementation has been +written for convert floats to integers (and vice +versa). + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 119 ++++++++-- + 1 file changed, 102 insertions(+), 17 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -87,6 +87,7 @@ + #define FAN_ID_FMT "F%dID" /* r-o char[16] */ + + #define TEMP_SENSOR_TYPE "sp78" ++#define FLOAT_TYPE "flt " + + /* List of keys used to read/write fan speeds */ + static const char *const fan_speed_fmt[] = { +@@ -96,6 +97,7 @@ static const char *const fan_speed_fmt[] = { + "F%dSf", /* safe speed - not all models */ + "F%dTg", /* target speed (manual: rw) */ + }; ++#define FAN_MANUAL_FMT "F%dMd" + + #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ + #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ +@@ -734,6 +736,42 @@ static int applesmc_read_s16(struct applesmc_device *smc, + return 0; + } + ++/** ++ * applesmc_float_to_u32 - Retrieve the integral part of a float. ++ * This is needed because Apple made fans use float values in the T2. ++ * The fractional point is not significantly useful though, and the integral ++ * part can be easily extracted. ++ */ ++static inline u32 applesmc_float_to_u32(u32 d) ++{ ++ u8 sign = (u8) ((d >> 31) & 1); ++ s32 exp = (s32) ((d >> 23) & 0xff) - 0x7f; ++ u32 fr = d & ((1u << 23) - 1); ++ ++ if (sign || exp < 0) ++ return 0; ++ ++ return (u32) ((1u << exp) + (fr >> (23 - exp))); ++} ++ ++/** ++ * applesmc_u32_to_float - Convert an u32 into a float. ++ * See applesmc_float_to_u32 for a rationale. ++ */ ++static inline u32 applesmc_u32_to_float(u32 d) ++{ ++ u32 dc = d, bc = 0, exp; ++ ++ if (!d) ++ return 0; ++ ++ while (dc >>= 1) ++ ++bc; ++ exp = 0x7f + bc; ++ ++ return (u32) ((exp << 23) | ++ ((d << (23 - (exp - 0x7f))) & ((1u << 23) - 1))); ++} + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +@@ -1241,6 +1279,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -1249,11 +1288,21 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ ret = applesmc_read_entry(smc, entry, (u8 *) &speed, 4); ++ speed = applesmc_float_to_u32(speed); ++ } else { ++ ret = applesmc_read_entry(smc, entry, buffer, 2); ++ speed = ((buffer[0] << 8 | buffer[1]) >> 2); ++ } ++ + if (ret) + return ret; + +- speed = ((buffer[0] << 8 | buffer[1]) >> 2); + return sysfs_emit(sysfsbuf, "%u\n", speed); + } + +@@ -1262,6 +1311,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + const char *sysfsbuf, size_t count) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned long speed; + char newkey[5]; +@@ -1273,9 +1323,18 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- buffer[0] = (speed >> 6) & 0xff; +- buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ speed = applesmc_u32_to_float(speed); ++ ret = applesmc_write_entry(smc, entry, (u8 *) &speed, 4); ++ } else { ++ buffer[0] = (speed >> 6) & 0xff; ++ buffer[1] = (speed << 2) & 0xff; ++ ret = applesmc_write_key(smc, newkey, buffer, 2); ++ } + + if (ret) + return ret; +@@ -1290,12 +1349,26 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, + int ret; + u16 manual = 0; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; ++ ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); ++ if (ret) ++ return ret; ++ ++ if (has_newkey) { ++ ret = applesmc_read_key(smc, newkey, buffer, 1); ++ manual = buffer[0]; ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; ++ } + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +- manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + return sysfs_emit(sysfsbuf, "%d\n", manual); + } + +@@ -1306,27 +1379,39 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; + unsigned long input; + u16 val; + + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); + if (ret) +- goto out; ++ return ret; + +- val = (buffer[0] << 8 | buffer[1]); ++ if (has_newkey) { ++ buffer[0] = input & 1; ++ ret = applesmc_write_key(smc, newkey, buffer, 1); ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ val = (buffer[0] << 8 | buffer[1]); ++ if (ret) ++ goto out; + +- if (input) +- val = val | (0x01 << to_index(attr)); +- else +- val = val & ~(0x01 << to_index(attr)); ++ if (input) ++ val = val | (0x01 << to_index(attr)); ++ else ++ val = val & ~(0x01 << to_index(attr)); + +- buffer[0] = (val >> 8) & 0xFF; +- buffer[1] = val & 0xFF; ++ buffer[0] = (val >> 8) & 0xFF; ++ buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ } + + out: + if (ret) +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch b/patch/kernel/archive/uefi-x86-6.18/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch new file mode 100644 index 000000000..ea124754f --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3007-applesmc-Add-iMacPro-to-applesmc_whitelist.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Sun, 9 Oct 2022 15:59:01 +0530 +Subject: applesmc: Add iMacPro to applesmc_whitelist + +The iMacPro1,1 is the only iMacPro released before the line was +discontinued. Add it to the applesmc_whitelist. + +Signed-off-by: Orlando Chamberlain +--- + drivers/hwmon/applesmc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1803,6 +1803,10 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") }, + }, ++ { applesmc_dmi_match, "Apple iMacPro", { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "iMacPro") }, ++ }, + { applesmc_dmi_match, "Apple MacPro", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3008-applesmc-make-applesmc_remove-void.patch b/patch/kernel/archive/uefi-x86-6.18/3008-applesmc-make-applesmc_remove-void.patch new file mode 100644 index 000000000..6ad7f1422 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3008-applesmc-make-applesmc_remove-void.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Tue, 24 Jan 2023 15:46:48 +1100 +Subject: applesmc: make applesmc_remove void + +for linux6.2 compatibility +--- + drivers/hwmon/applesmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -979,7 +979,7 @@ static int applesmc_add(struct acpi_device *dev) + return ret; + } + +-static int applesmc_remove(struct acpi_device *dev) ++static void applesmc_remove(struct acpi_device *dev) + { + struct applesmc_device *smc = dev_get_drvdata(&dev->dev); + +@@ -990,7 +990,7 @@ static int applesmc_remove(struct acpi_device *dev) + mutex_destroy(&smc->reg.mutex); + kfree(smc); + +- return 0; ++ return; + } + + static acpi_status applesmc_walk_resources(struct acpi_resource *res, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/3009-applesmc-battery-charge-limiter.patch b/patch/kernel/archive/uefi-x86-6.18/3009-applesmc-battery-charge-limiter.patch new file mode 100644 index 000000000..d485b1ca2 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/3009-applesmc-battery-charge-limiter.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Mon, 30 Jan 2023 18:42:21 +1100 +Subject: applesmc: battery charge limiter + +--- + drivers/hwmon/applesmc.c | 42 +++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 111111111111..222222222222 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1477,6 +1477,35 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, + dev_dbg(led_cdev->dev, "work was already on the queue.\n"); + } + ++static ssize_t applesmc_BCLM_store(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf, size_t count) ++{ ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ u8 val; ++ ++ if (kstrtou8(sysfsbuf, 10, &val) < 0) ++ return -EINVAL; ++ ++ if (val < 0 || val > 100) ++ return -EINVAL; ++ ++ if (applesmc_write_key(smc, "BCLM", &val, 1)) ++ return -ENODEV; ++ return count; ++} ++ ++static ssize_t applesmc_BCLM_show(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ u8 val; ++ ++ if (applesmc_read_key(smc, "BCLM", &val, 1)) ++ return -ENODEV; ++ ++ return sysfs_emit(sysfsbuf, "%d\n", val); ++} ++ + static ssize_t applesmc_key_count_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +@@ -1611,6 +1640,11 @@ static struct applesmc_node_group temp_group[] = { + { } + }; + ++static struct applesmc_node_group BCLM_group[] = { ++ { "battery_charge_limit", applesmc_BCLM_show, applesmc_BCLM_store }, ++ { } ++}; ++ + /* Module stuff */ + + /* +@@ -1829,10 +1863,13 @@ static int applesmc_create_modules(struct applesmc_device *smc) + ret = applesmc_create_nodes(smc, info_group, 1); + if (ret) + goto out; ++ ret = applesmc_create_nodes(smc, BCLM_group, 1); ++ if (ret) ++ goto out_info; + + ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count); + if (ret) +- goto out_info; ++ goto out_bclm; + + ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count); + if (ret) +@@ -1868,6 +1905,8 @@ static int applesmc_create_modules(struct applesmc_device *smc) + applesmc_destroy_nodes(smc, temp_group); + out_fans: + applesmc_destroy_nodes(smc, fan_group); ++out_bclm: ++ applesmc_destroy_nodes(smc, BCLM_group); + out_info: + applesmc_destroy_nodes(smc, info_group); + out: +@@ -1882,6 +1921,7 @@ static void applesmc_destroy_modules(struct applesmc_device *smc) + applesmc_release_accelerometer(smc); + applesmc_destroy_nodes(smc, temp_group); + applesmc_destroy_nodes(smc, fan_group); ++ applesmc_destroy_nodes(smc, BCLM_group); + applesmc_destroy_nodes(smc, info_group); + } + +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/4001-asahi-trackpad.patch b/patch/kernel/archive/uefi-x86-6.18/4001-asahi-trackpad.patch new file mode 100644 index 000000000..89784a1e6 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/4001-asahi-trackpad.patch @@ -0,0 +1,5052 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 12 Dec 2021 20:40:04 +0100 +Subject: HID: add device IDs for Apple SPI HID devices + +Apple Silicon based laptop use SPI as transport for HID. Add support for +SPI-based HID devices and and Apple keyboard and trackpad devices. +Intel based laptops using the keyboard input driver applespi use the +same HID over SPI protocol and can be supported later. + +This requires SPI keyboard/mouse HID types since Apple's intenal +keyboards/trackpads use the same product id. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-core.c | 3 +++ + drivers/hid/hid-ids.h | 5 +++++ + include/linux/hid.h | 6 +++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2316,6 +2316,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) + case BUS_I2C: + bus = "I2C"; + break; ++ case BUS_SPI: ++ bus = "SPI"; ++ break; + case BUS_SDW: + bus = "SOUNDWIRE"; + break; +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -93,6 +93,7 @@ + + #define USB_VENDOR_ID_APPLE 0x05ac + #define BT_VENDOR_ID_APPLE 0x004c ++#define SPI_VENDOR_ID_APPLE 0x05ac + #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 + #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d + #define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269 +@@ -197,6 +198,10 @@ + #define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 + #define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102 + #define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_AIR_2020 0x0281 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020 0x0341 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021 0x0342 ++#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021 0x0343 + + #define USB_VENDOR_ID_ASETEK 0x2433 + #define USB_DEVICE_ID_ASETEK_INVICTA 0xf300 +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 111111111111..222222222222 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -625,7 +625,9 @@ struct hid_input { + enum hid_type { + HID_TYPE_OTHER = 0, + HID_TYPE_USBMOUSE, +- HID_TYPE_USBNONE ++ HID_TYPE_USBNONE, ++ HID_TYPE_SPI_KEYBOARD, ++ HID_TYPE_SPI_MOUSE, + }; + + enum hid_battery_status { +@@ -786,6 +788,8 @@ struct hid_descriptor { + .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod) + #define HID_I2C_DEVICE(ven, prod) \ + .bus = BUS_I2C, .vendor = (ven), .product = (prod) ++#define HID_SPI_DEVICE(ven, prod) \ ++ .bus = BUS_SPI, .vendor = (ven), .product = (prod) + + #define HID_REPORT_ID(rep) \ + .report_type = (rep) +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 00:29:43 +0900 +Subject: HID: add HOST vendor/device IDs for Apple MTP devices + +Apple M2* chips have an embedded MTP processor that handles all HID +functions, and does not go over a traditional bus like SPI. The devices +still have real IDs, so add them here. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-ids.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -94,6 +94,7 @@ + #define USB_VENDOR_ID_APPLE 0x05ac + #define BT_VENDOR_ID_APPLE 0x004c + #define SPI_VENDOR_ID_APPLE 0x05ac ++#define HOST_VENDOR_ID_APPLE 0x05ac + #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 + #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d + #define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269 +@@ -202,6 +203,10 @@ + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020 0x0341 + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021 0x0342 + #define SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021 0x0343 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_AIR13_2022 0x0351 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO14_2023 0x0352 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO16_2023 0x0353 ++#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022 0x0354 + + #define USB_VENDOR_ID_ASETEK 0x2433 + #define USB_DEVICE_ID_ASETEK_INVICTA 0xf300 +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:06:15 +0900 +Subject: HID: core: Handle HOST bus type when announcing devices + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2319,6 +2319,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) + case BUS_SPI: + bus = "SPI"; + break; ++ case BUS_HOST: ++ bus = "HOST"; ++ break; + case BUS_SDW: + bus = "SOUNDWIRE"; + break; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Mon, 10 Apr 2023 22:44:44 +0900 +Subject: HID: Bump maximum report size to 16384 + +This maximum is arbitrary. Recent Apple devices have some vendor-defined +reports with 16384 here which fail to parse without this, so let's bump +it to that. + +This value is used as follows: + +report->size += parser->global.report_size * parser->global.report_count; + +[...] + +/* Total size check: Allow for possible report index byte */ +if (report->size > (max_buffer_size - 1) << 3) { + hid_err(parser->device, "report is too long\n"); + return -1; +} + +All of these fields are unsigned integers, and report_count is bounded +by HID_MAX_USAGES (12288). Therefore, as long as the respective maximums +do not overflow an unsigned integer (let's say a signed integer just in +case), we're safe. This holds for 16384. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -468,7 +468,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) + + case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: + parser->global.report_size = item_udata(item); +- if (parser->global.report_size > 256) { ++ /* Arbitrary maximum. Some Apple devices have 16384 here. ++ * This * HID_MAX_USAGES must fit in a signed integer. ++ */ ++ if (parser->global.report_size > 16384) { + hid_err(parser->device, "invalid report_size %d\n", + parser->global.report_size); + return -1; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 21:15:31 +0100 +Subject: HID: apple: Bind Apple silicon SPI devices + +Apple MacBook keyboards started using HID over SPI in 2015. With the +addition of the SPI HID transport they can be supported by this driver. +Support all product ids over with the Apple SPI vendor id for now. + +The Macbook Pro (M1, 13-inch, 2020) uses the same function key mapping +as other Macbook Pros with touchbar and dedicated ESC key. +Apple silicon Macbooks use the same function key mapping as the 2021 and +later Magic Keyboards. + +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 2 +- + drivers/hid/hid-apple.c | 15 ++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -140,7 +140,7 @@ config HID_APPLE + tristate "Apple {i,Power,Mac}Books" + depends on LEDS_CLASS + depends on NEW_LEDS +- default !EXPERT ++ default !EXPERT || SPI_HID_APPLE + help + Support for some Apple devices which less or more break + HID specification. +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -517,6 +517,15 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + table = macbookair_fn_keys; + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; ++ else if (hid->bus == BUS_SPI) ++ switch (hid->product) { ++ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020: ++ table = macbookpro_dedicated_esc_fn_keys; ++ break; ++ default: ++ table = magic_keyboard_2021_and_2024_fn_keys; ++ break; ++ } + else + table = apple_fn_keys; + } +@@ -937,6 +946,10 @@ static int apple_probe(struct hid_device *hdev, + struct apple_sc *asc; + int ret; + ++ if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ hdev->type != HID_TYPE_SPI_KEYBOARD) ++ return -ENODEV; ++ + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); + if (asc == NULL) { + hid_err(hdev, "can't alloc apple descriptor\n"); +@@ -1215,6 +1228,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), + .driver_data = APPLE_MAGIC_BACKLIGHT }, + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:12:24 +0900 +Subject: HID: apple: Bind to HOST devices for MTP + +We use BUS_HOST for MTP HID subdevices + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-apple.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -517,9 +517,10 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + table = macbookair_fn_keys; + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; +- else if (hid->bus == BUS_SPI) ++ else if (hid->bus == BUS_HOST || hid->bus == BUS_SPI) + switch (hid->product) { + case SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020: ++ case HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022: + table = macbookpro_dedicated_esc_fn_keys; + break; + default: +@@ -946,7 +947,7 @@ static int apple_probe(struct hid_device *hdev, + struct apple_sc *asc; + int ret; + +- if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && + hdev->type != HID_TYPE_SPI_KEYBOARD) + return -ENODEV; + +@@ -1230,6 +1231,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), + .driver_data = APPLE_MAGIC_BACKLIGHT }, + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:10:51 +0100 +Subject: HID: magicmouse: use a define of the max number of touch contacts + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -62,6 +62,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define DOUBLE_REPORT_ID 0xf7 + #define USB_BATTERY_TIMEOUT_SEC 60 + ++#define MAX_CONTACTS 16 ++ + /* These definitions are not precise, but they're close enough. (Bits + * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem + * to be some kind of bit mask -- 0x20 may be a near-field reading, +@@ -143,8 +145,8 @@ struct magicmouse_sc { + u8 size; + bool scroll_x_active; + bool scroll_y_active; +- } touches[16]; +- int tracking_ids[16]; ++ } touches[MAX_CONTACTS]; ++ int tracking_ids[MAX_CONTACTS]; + + struct hid_device *hdev; + struct delayed_work work; +@@ -615,7 +617,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd + + __set_bit(EV_ABS, input->evbit); + +- error = input_mt_init_slots(input, 16, mt_flags); ++ error = input_mt_init_slots(input, MAX_CONTACTS, mt_flags); + if (error) + return error; + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:12:35 +0100 +Subject: HID: magicmouse: use struct input_mt_pos for X/Y + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -121,6 +121,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + * @ntouches: Number of touches in most recent touch report. + * @scroll_accel: Number of consecutive scroll motions. + * @scroll_jiffies: Time of last scroll motion. ++ * @pos: multi touch position data of the last report. + * @touches: Most recent data for a touch, indexed by tracking ID. + * @tracking_ids: Mapping of current touch input data to @touches. + * @hdev: Pointer to the underlying HID device. +@@ -135,9 +136,8 @@ struct magicmouse_sc { + int scroll_accel; + unsigned long scroll_jiffies; + ++ struct input_mt_pos pos[MAX_CONTACTS]; + struct { +- short x; +- short y; + short scroll_x; + short scroll_y; + short scroll_x_hr; +@@ -194,7 +194,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) + } else if (last_state != 0) { + state = last_state; + } else if ((id = magicmouse_firm_touch(msc)) >= 0) { +- int x = msc->touches[id].x; ++ int x = msc->pos[id].x; + if (x < middle_button_start) + state = 1; + else if (x > middle_button_stop) +@@ -258,8 +258,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda + + /* Store tracking ID and other fields. */ + msc->tracking_ids[raw_id] = id; +- msc->touches[id].x = x; +- msc->touches[id].y = y; ++ msc->pos[id].x = x; ++ msc->pos[id].y = y; + msc->touches[id].size = size; + + /* If requested, emulate a scroll wheel by detecting small +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 00:15:30 +0100 +Subject: HID: magicmouse: use ops function pointers for input functionality + +Will be used for supporting MacBook trackpads connected via SPI. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 32 +++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -114,6 +114,13 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++ ++struct magicmouse_input_ops { ++ int (*raw_event)(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size); ++ int (*setup_input)(struct input_dev *input, struct hid_device *hdev); ++}; ++ + /** + * struct magicmouse_sc - Tracks Magic Mouse-specific data. + * @input: Input device through which we report events. +@@ -127,6 +134,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + * @hdev: Pointer to the underlying HID device. + * @work: Workqueue to handle initialization retry for quirky devices. + * @battery_timer: Timer for obtaining battery level information. ++ * @input_ops: Input ops based on device type. + */ + struct magicmouse_sc { + struct input_dev *input; +@@ -151,6 +159,7 @@ struct magicmouse_sc { + struct hid_device *hdev; + struct delayed_work work; + struct timer_list battery_timer; ++ struct magicmouse_input_ops input_ops; + }; + + static int magicmouse_firm_touch(struct magicmouse_sc *msc) +@@ -389,6 +398,14 @@ static int magicmouse_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { + struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ ++ return msc->input_ops.raw_event(hdev, report, data, size); ++} ++ ++static int magicmouse_raw_event_usb(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + struct input_dev *input = msc->input; + int x = 0, y = 0, ii, clicks = 0, npoints; + +@@ -538,7 +555,17 @@ static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + return 0; + } + +-static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) ++ ++static int magicmouse_setup_input(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ ++ return msc->input_ops.setup_input(input, hdev); ++} ++ ++static int magicmouse_setup_input_usb(struct input_dev *input, ++ struct hid_device *hdev) + { + int error; + int mt_flags = 0; +@@ -860,6 +887,9 @@ static int magicmouse_probe(struct hid_device *hdev, + return -ENOMEM; + } + ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; + msc->hdev = hdev; + INIT_DEFERRABLE_WORK(&msc->work, magicmouse_enable_mt_work); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Thu, 16 Dec 2021 01:17:48 +0100 +Subject: HID: magicmouse: add support for Macbook trackpads + +The trackpads in Macbooks beginning in 2015 are HID devices connected +over SPI. On Intel Macbooks they are currently supported by applespi.c. +This chang adds support for the trackpads on Apple Silicon Macbooks +starting in late 2020. They use a new HID over SPI transport driver. +The touch report format differs from USB/BT Magic Trackpads. It is the +same format as the type 4 format supported by bcm5974.c. + +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 4 +- + drivers/hid/hid-magicmouse.c | 266 +++++++++- + 2 files changed, 266 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -726,11 +726,13 @@ config LOGIWHEELS_FF + + config HID_MAGICMOUSE + tristate "Apple Magic Mouse/Trackpad multi-touch support" ++ default SPI_HID_APPLE + help + Support for the Apple Magic Mouse/Trackpad multi-touch. + + Say Y here if you want support for the multi-touch features of the +- Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. ++ Apple Wireless "Magic" Mouse, the Apple Wireless "Magic" Trackpad and ++ force touch Trackpads in Macbooks starting from 2015. + + config HID_MALTRON + tristate "Maltron L90 keyboard" +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -60,6 +60,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define MOUSE_REPORT_ID 0x29 + #define MOUSE2_REPORT_ID 0x12 + #define DOUBLE_REPORT_ID 0xf7 ++#define SPI_REPORT_ID 0x02 + #define USB_BATTERY_TIMEOUT_SEC 60 + + #define MAX_CONTACTS 16 +@@ -114,6 +115,18 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++#define J314_TP_DIMENSION_X (float)13000 ++#define J314_TP_MIN_X -5900 ++#define J314_TP_MAX_X 6500 ++#define J314_TP_RES_X \ ++ ((J314_TP_MAX_X - J314_TP_MIN_X) / (J314_TP_DIMENSION_X / 100)) ++#define J314_TP_DIMENSION_Y (float)8100 ++#define J314_TP_MIN_Y -200 ++#define J314_TP_MAX_Y 7400 ++#define J314_TP_RES_Y \ ++ ((J314_TP_MAX_Y - J314_TP_MIN_Y) / (J314_TP_DIMENSION_Y / 100)) ++ ++#define J314_TP_MAX_FINGER_ORIENTATION 16384 + + struct magicmouse_input_ops { + int (*raw_event)(struct hid_device *hdev, +@@ -537,6 +550,154 @@ static int magicmouse_raw_event_usb(struct hid_device *hdev, + return 1; + } + ++/** ++ * struct tp_finger - single trackpad finger structure, le16-aligned ++ * ++ * @unknown1: unknown ++ * @unknown2: unknown ++ * @abs_x: absolute x coordinate ++ * @abs_y: absolute y coordinate ++ * @rel_x: relative x coordinate ++ * @rel_y: relative y coordinate ++ * @tool_major: tool area, major axis ++ * @tool_minor: tool area, minor axis ++ * @orientation: 16384 when point, else 15 bit angle ++ * @touch_major: touch area, major axis ++ * @touch_minor: touch area, minor axis ++ * @unused: zeros ++ * @pressure: pressure on forcetouch touchpad ++ * @multi: one finger: varies, more fingers: constant ++ */ ++struct tp_finger { ++ __le16 unknown1; ++ __le16 unknown2; ++ __le16 abs_x; ++ __le16 abs_y; ++ __le16 rel_x; ++ __le16 rel_y; ++ __le16 tool_major; ++ __le16 tool_minor; ++ __le16 orientation; ++ __le16 touch_major; ++ __le16 touch_minor; ++ __le16 unused[2]; ++ __le16 pressure; ++ __le16 multi; ++} __attribute__((packed, aligned(2))); ++ ++/** ++ * struct trackpad report ++ * ++ * @report_id: reportid ++ * @buttons: HID Usage Buttons 3 1-bit reports ++ * @num_fingers: the number of fingers being reported in @fingers ++ * @clicked: same as @buttons ++ */ ++struct tp_header { ++ // HID mouse report ++ u8 report_id; ++ u8 buttons; ++ u8 rel_x; ++ u8 rel_y; ++ u8 padding[4]; ++ // HID vendor part, up to 1751 bytes ++ u8 unknown[22]; ++ u8 num_fingers; ++ u8 clicked; ++ u8 unknown3[14]; ++}; ++ ++static inline int le16_to_int(__le16 x) ++{ ++ return (signed short)le16_to_cpu(x); ++} ++ ++static void report_finger_data(struct input_dev *input, int slot, ++ const struct input_mt_pos *pos, ++ const struct tp_finger *f) ++{ ++ input_mt_slot(input, slot); ++ input_mt_report_slot_state(input, MT_TOOL_FINGER, true); ++ ++ input_report_abs(input, ABS_MT_TOUCH_MAJOR, ++ le16_to_int(f->touch_major) << 1); ++ input_report_abs(input, ABS_MT_TOUCH_MINOR, ++ le16_to_int(f->touch_minor) << 1); ++ input_report_abs(input, ABS_MT_WIDTH_MAJOR, ++ le16_to_int(f->tool_major) << 1); ++ input_report_abs(input, ABS_MT_WIDTH_MINOR, ++ le16_to_int(f->tool_minor) << 1); ++ input_report_abs(input, ABS_MT_ORIENTATION, ++ J314_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); ++ input_report_abs(input, ABS_MT_PRESSURE, le16_to_int(f->pressure)); ++ input_report_abs(input, ABS_MT_POSITION_X, pos->x); ++ input_report_abs(input, ABS_MT_POSITION_Y, pos->y); ++} ++ ++static int magicmouse_raw_event_spi(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ struct input_dev *input = msc->input; ++ struct tp_header *tp_hdr; ++ struct tp_finger *f; ++ int i, n; ++ u32 npoints; ++ const size_t hdr_sz = sizeof(struct tp_header); ++ const size_t touch_sz = sizeof(struct tp_finger); ++ u8 map_contacs[MAX_CONTACTS]; ++ ++ // hid_warn(hdev, "%s\n", __func__); ++ // print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data, ++ // size, false); ++ ++ if (data[0] != SPI_REPORT_ID) ++ return 0; ++ ++ /* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */ ++ if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0) ++ return 0; ++ ++ tp_hdr = (struct tp_header *)data; ++ ++ npoints = (size - hdr_sz) / touch_sz; ++ if (npoints < tp_hdr->num_fingers || npoints > MAX_CONTACTS) { ++ hid_warn(hdev, ++ "unexpected number of touches (%u) for " ++ "report\n", ++ npoints); ++ return 0; ++ } ++ ++ n = 0; ++ for (i = 0; i < tp_hdr->num_fingers; i++) { ++ f = (struct tp_finger *)(data + hdr_sz + i * touch_sz); ++ if (le16_to_int(f->touch_major) == 0) ++ continue; ++ ++ hid_dbg(hdev, "ev x:%04x y:%04x\n", le16_to_int(f->abs_x), ++ le16_to_int(f->abs_y)); ++ msc->pos[n].x = le16_to_int(f->abs_x); ++ msc->pos[n].y = -le16_to_int(f->abs_y); ++ map_contacs[n] = i; ++ n++; ++ } ++ ++ input_mt_assign_slots(input, msc->tracking_ids, msc->pos, n, 0); ++ ++ for (i = 0; i < n; i++) { ++ int idx = map_contacs[i]; ++ f = (struct tp_finger *)(data + hdr_sz + idx * touch_sz); ++ report_finger_data(input, msc->tracking_ids[i], &msc->pos[i], f); ++ } ++ ++ input_mt_sync_frame(input); ++ input_report_key(input, BTN_MOUSE, data[1] & 1); ++ ++ input_sync(input); ++ return 1; ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -727,6 +888,79 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + return 0; + } + ++static int magicmouse_setup_input_spi(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int error; ++ int mt_flags = 0; ++ ++ __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); ++ __clear_bit(BTN_0, input->keybit); ++ __clear_bit(BTN_RIGHT, input->keybit); ++ __clear_bit(BTN_MIDDLE, input->keybit); ++ __clear_bit(EV_REL, input->evbit); ++ __clear_bit(REL_X, input->relbit); ++ __clear_bit(REL_Y, input->relbit); ++ ++ mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK; ++ ++ /* finger touch area */ ++ input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 5000, 0, 0); ++ input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 5000, 0, 0); ++ ++ /* finger approach area */ ++ input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 5000, 0, 0); ++ input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 5000, 0, 0); ++ ++ /* Note: Touch Y position from the device is inverted relative ++ * to how pointer motion is reported (and relative to how USB ++ * HID recommends the coordinates work). This driver keeps ++ * the origin at the same position, and just uses the additive ++ * inverse of the reported Y. ++ */ ++ ++ input_set_abs_params(input, ABS_MT_PRESSURE, 0, 6000, 0, 0); ++ ++ /* ++ * This makes libinput recognize this as a PressurePad and ++ * stop trying to use pressure for touch size. Pressure unit ++ * seems to be ~grams on these touchpads. ++ */ ++ input_abs_set_res(input, ABS_MT_PRESSURE, 1); ++ ++ /* finger orientation */ ++ input_set_abs_params(input, ABS_MT_ORIENTATION, -J314_TP_MAX_FINGER_ORIENTATION, ++ J314_TP_MAX_FINGER_ORIENTATION, 0, 0); ++ ++ /* finger position */ ++ input_set_abs_params(input, ABS_MT_POSITION_X, J314_TP_MIN_X, J314_TP_MAX_X, ++ 0, 0); ++ /* Y axis is inverted */ ++ input_set_abs_params(input, ABS_MT_POSITION_Y, -J314_TP_MAX_Y, -J314_TP_MIN_Y, ++ 0, 0); ++ ++ /* X/Y resolution */ ++ input_abs_set_res(input, ABS_MT_POSITION_X, J314_TP_RES_X); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, J314_TP_RES_Y); ++ ++ input_set_events_per_packet(input, 60); ++ ++ /* touchpad button */ ++ input_set_capability(input, EV_KEY, BTN_MOUSE); ++ ++ /* ++ * hid-input may mark device as using autorepeat, but the trackpad does ++ * not actually want it. ++ */ ++ __clear_bit(EV_REP, input->evbit); ++ ++ error = input_mt_init_slots(input, MAX_CONTACTS, mt_flags); ++ if (error) ++ return error; ++ ++ return 0; ++} ++ + static int magicmouse_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +@@ -777,6 +1011,10 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + int feature_size; + + switch (hdev->product) { ++ case SPI_DEVICE_ID_APPLE_MACBOOK_AIR_2020: ++ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020: ++ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021: ++ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021: + case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2: + case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC: + switch (hdev->vendor) { +@@ -784,7 +1022,7 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + feature_size = sizeof(feature_mt_trackpad2_bt); + feature = feature_mt_trackpad2_bt; + break; +- default: /* USB_VENDOR_ID_APPLE */ ++ default: /* USB_VENDOR_ID_APPLE || SPI_VENDOR_ID_APPLE */ + feature_size = sizeof(feature_mt_trackpad2_usb); + feature = feature_mt_trackpad2_usb; + } +@@ -881,14 +1119,25 @@ static int magicmouse_probe(struct hid_device *hdev, + struct hid_report *report; + int ret; + ++ if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ hdev->type != HID_TYPE_SPI_MOUSE) ++ return -ENODEV; ++ + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { + hid_err(hdev, "can't alloc magicmouse descriptor\n"); + return -ENOMEM; + } + +- msc->input_ops.raw_event = magicmouse_raw_event_usb; +- msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ // internal trackpad use a data format use input ops to avoid ++ // conflicts with the report ID. ++ if (id->vendor == SPI_VENDOR_ID_APPLE) { ++ msc->input_ops.raw_event = magicmouse_raw_event_spi; ++ msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ } else { ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ } + + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; + msc->hdev = hdev; +@@ -948,6 +1197,15 @@ static int magicmouse_probe(struct hid_device *hdev, + TRACKPAD2_USB_REPORT_ID, 0); + } + break; ++ case HID_ANY_ID: ++ switch (id->bus) { ++ case BUS_SPI: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0); ++ break; ++ default: ++ break; ++ } ++ break; + default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD_REPORT_ID, 0); +@@ -1055,6 +1313,8 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, ++ { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), ++ .driver_data = 0 }, + { } + }; + MODULE_DEVICE_TABLE(hid, magic_mice); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:12:57 +0900 +Subject: HID: magicmouse: Add MTP multi-touch device support + +Apple M2 devices expose the multi-touch device over the HID over +DockChannel transport, which we represent as the HOST bus type. The +report format is the same, except the legacy mouse header is gone and +there is no enable request needed. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 63 +++++++--- + 1 file changed, 47 insertions(+), 16 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -61,6 +61,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define MOUSE2_REPORT_ID 0x12 + #define DOUBLE_REPORT_ID 0xf7 + #define SPI_REPORT_ID 0x02 ++#define MTP_REPORT_ID 0x75 + #define USB_BATTERY_TIMEOUT_SEC 60 + + #define MAX_CONTACTS 16 +@@ -586,25 +587,32 @@ struct tp_finger { + } __attribute__((packed, aligned(2))); + + /** +- * struct trackpad report ++ * vendor trackpad report + * +- * @report_id: reportid +- * @buttons: HID Usage Buttons 3 1-bit reports + * @num_fingers: the number of fingers being reported in @fingers +- * @clicked: same as @buttons ++ * @buttons: same as HID buttons + */ + struct tp_header { ++ // HID vendor part, up to 1751 bytes ++ u8 unknown[22]; ++ u8 num_fingers; ++ u8 buttons; ++ u8 unknown3[14]; ++}; ++ ++/** ++ * standard HID mouse report ++ * ++ * @report_id: reportid ++ * @buttons: HID Usage Buttons 3 1-bit reports ++ */ ++struct tp_mouse_report { + // HID mouse report + u8 report_id; + u8 buttons; + u8 rel_x; + u8 rel_y; + u8 padding[4]; +- // HID vendor part, up to 1751 bytes +- u8 unknown[22]; +- u8 num_fingers; +- u8 clicked; +- u8 unknown3[14]; + }; + + static inline int le16_to_int(__le16 x) +@@ -634,7 +642,7 @@ static void report_finger_data(struct input_dev *input, int slot, + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); + } + +-static int magicmouse_raw_event_spi(struct hid_device *hdev, ++static int magicmouse_raw_event_mtp(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { + struct magicmouse_sc *msc = hid_get_drvdata(hdev); +@@ -651,9 +659,6 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + // print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data, + // size, false); + +- if (data[0] != SPI_REPORT_ID) +- return 0; +- + /* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */ + if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0) + return 0; +@@ -692,12 +697,26 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + } + + input_mt_sync_frame(input); +- input_report_key(input, BTN_MOUSE, data[1] & 1); ++ input_report_key(input, BTN_MOUSE, tp_hdr->buttons & 1); + + input_sync(input); + return 1; + } + ++static int magicmouse_raw_event_spi(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ const size_t hdr_sz = sizeof(struct tp_mouse_report); ++ ++ if (size < hdr_sz) ++ return 0; ++ ++ if (data[0] != SPI_REPORT_ID) ++ return 0; ++ ++ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -1119,7 +1138,7 @@ static int magicmouse_probe(struct hid_device *hdev, + struct hid_report *report; + int ret; + +- if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE && ++ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && + hdev->type != HID_TYPE_SPI_MOUSE) + return -ENODEV; + +@@ -1131,7 +1150,10 @@ static int magicmouse_probe(struct hid_device *hdev, + + // internal trackpad use a data format use input ops to avoid + // conflicts with the report ID. +- if (id->vendor == SPI_VENDOR_ID_APPLE) { ++ if (id->bus == BUS_HOST) { ++ msc->input_ops.raw_event = magicmouse_raw_event_mtp; ++ msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ } else if (id->bus == BUS_SPI) { + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; + } else { +@@ -1199,6 +1221,9 @@ static int magicmouse_probe(struct hid_device *hdev, + break; + case HID_ANY_ID: + switch (id->bus) { ++ case BUS_HOST: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0); ++ break; + case BUS_SPI: + report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0); + break; +@@ -1220,6 +1245,10 @@ static int magicmouse_probe(struct hid_device *hdev, + } + report->size = 6; + ++ /* MTP devices do not need the MT enable, this is handled by the MTP driver */ ++ if (id->bus == BUS_HOST) ++ return 0; ++ + /* + * Some devices repond with 'invalid report id' when feature + * report switching it into multitouch mode is sent to it. +@@ -1315,6 +1344,8 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = 0 }, ++ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, ++ HID_ANY_ID), .driver_data = 0 }, + { } + }; + MODULE_DEVICE_TABLE(hid, magic_mice); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Sun, 11 Dec 2022 22:56:16 +0100 +Subject: HID: magicmouse: Add .reset_resume for SPI trackpads + +The trackpad has to request multi touch reports during resume. + +Signed-off-by: Janne Grunau +--- + drivers/hid/hid-magicmouse.c | 14 ++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -1350,6 +1350,16 @@ static const struct hid_device_id magic_mice[] = { + }; + MODULE_DEVICE_TABLE(hid, magic_mice); + ++#ifdef CONFIG_PM ++static int magicmouse_reset_resume(struct hid_device *hdev) ++{ ++ if (hdev->bus == BUS_SPI) ++ return magicmouse_enable_multitouch(hdev); ++ ++ return 0; ++} ++#endif ++ + static struct hid_driver magicmouse_driver = { + .name = "magicmouse", + .id_table = magic_mice, +@@ -1360,6 +1370,10 @@ static struct hid_driver magicmouse_driver = { + .event = magicmouse_event, + .input_mapping = magicmouse_input_mapping, + .input_configured = magicmouse_input_configured, ++#ifdef CONFIG_PM ++ .reset_resume = magicmouse_reset_resume, ++#endif ++ + }; + module_hid_driver(magicmouse_driver); + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 30 Apr 2023 23:48:45 +0900 +Subject: HID: magicmouse: Handle touch controller resets on SPI devices + +On at least some SPI devices (e.g. recent Apple Silicon machines), the +Broadcom touch controller is prone to crashing. When this happens, the +STM eventually notices and resets it. It then notifies the driver via +HID report 0x60, and the driver needs to re-enable MT mode to make +things work again. + +This poses an additional issue: the hidinput core will close the +low-level transport while the device is closed, which can cause us to +miss a reset notification. To fix this, override the input open/close +callbacks and send the MT enable every time the HID device is opened, +instead of only once on probe. This should increase general robustness, +even if the reset mechanism doesn't work for some reason, so it's worth +doing it for USB devices too. MTP devices are exempt since they do not +require the MT enable at all. + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 108 ++++++++-- + 1 file changed, 87 insertions(+), 21 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -61,6 +61,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define MOUSE2_REPORT_ID 0x12 + #define DOUBLE_REPORT_ID 0xf7 + #define SPI_REPORT_ID 0x02 ++#define SPI_RESET_REPORT_ID 0x60 + #define MTP_REPORT_ID 0x75 + #define USB_BATTERY_TIMEOUT_SEC 60 + +@@ -176,6 +177,50 @@ struct magicmouse_sc { + struct magicmouse_input_ops input_ops; + }; + ++static int magicmouse_enable_multitouch(struct hid_device *hdev); ++ ++static int magicmouse_open(struct input_dev *dev) ++{ ++ struct hid_device *hdev = input_get_drvdata(dev); ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); ++ int ret; ++ ++ ret = hid_hw_open(hdev); ++ if (ret) ++ return ret; ++ ++ /* ++ * Some devices repond with 'invalid report id' when feature ++ * report switching it into multitouch mode is sent to it. ++ * ++ * This results in -EIO from the _raw low-level transport callback, ++ * but there seems to be no other way of switching the mode. ++ * Thus the super-ugly hacky success check below. ++ */ ++ ret = magicmouse_enable_multitouch(hdev); ++ if (ret != -EIO && ret < 0) { ++ hid_err(hdev, "unable to request touch data (%d)\n", ret); ++ return ret; ++ } ++ if (ret == -EIO && (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || ++ hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) { ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ } ++ ++ /* ++ * MT enable is usually not required after the first time, so don't ++ * consider it fatal. ++ */ ++ return 0; ++} ++ ++static void magicmouse_close(struct input_dev *dev) ++{ ++ struct hid_device *hdev = input_get_drvdata(dev); ++ ++ hid_hw_close(hdev); ++} ++ + static int magicmouse_firm_touch(struct magicmouse_sc *msc) + { + int touch = -1; +@@ -706,12 +751,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev, + static int magicmouse_raw_event_spi(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) + { ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + const size_t hdr_sz = sizeof(struct tp_mouse_report); + +- if (size < hdr_sz) ++ if (!size) + return 0; + +- if (data[0] != SPI_REPORT_ID) ++ if (data[0] == SPI_RESET_REPORT_ID) { ++ hid_info(hdev, "Touch controller was reset, re-enabling touch mode\n"); ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(10)); ++ return 1; ++ } ++ ++ if (data[0] != SPI_REPORT_ID || size < hdr_sz) + return 0; + + return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); +@@ -904,10 +956,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + */ + __clear_bit(EV_REP, input->evbit); + ++ /* ++ * This isn't strictly speaking needed for USB, but enabling MT on ++ * device open is probably more robust than only doing it once on probe ++ * even if USB devices are not known to suffer from the SPI reset issue. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; + return 0; + } + +-static int magicmouse_setup_input_spi(struct input_dev *input, ++static int magicmouse_setup_input_mtp(struct input_dev *input, + struct hid_device *hdev) + { + int error; +@@ -980,6 +1039,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input, + return 0; + } + ++static int magicmouse_setup_input_spi(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int ret = magicmouse_setup_input_mtp(input, hdev); ++ if (ret) ++ return ret; ++ ++ /* ++ * Override the default input->open function to send the MT ++ * enable every time the device is opened. This ensures it works ++ * even if we missed a reset event due to the device being closed. ++ * input->close is overridden for symmetry. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; ++ ++ return 0; ++} ++ + static int magicmouse_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +@@ -1041,7 +1119,7 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + feature_size = sizeof(feature_mt_trackpad2_bt); + feature = feature_mt_trackpad2_bt; + break; +- default: /* USB_VENDOR_ID_APPLE || SPI_VENDOR_ID_APPLE */ ++ default: /* USB_VENDOR_ID_APPLE || SPI_VENDOR_ID_APPLE */ + feature_size = sizeof(feature_mt_trackpad2_usb); + feature = feature_mt_trackpad2_usb; + } +@@ -1152,7 +1230,7 @@ static int magicmouse_probe(struct hid_device *hdev, + // conflicts with the report ID. + if (id->bus == BUS_HOST) { + msc->input_ops.raw_event = magicmouse_raw_event_mtp; +- msc->input_ops.setup_input = magicmouse_setup_input_spi; ++ msc->input_ops.setup_input = magicmouse_setup_input_mtp; + } else if (id->bus == BUS_SPI) { + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; +@@ -1249,22 +1327,10 @@ static int magicmouse_probe(struct hid_device *hdev, + if (id->bus == BUS_HOST) + return 0; + +- /* +- * Some devices repond with 'invalid report id' when feature +- * report switching it into multitouch mode is sent to it. +- * +- * This results in -EIO from the _raw low-level transport callback, +- * but there seems to be no other way of switching the mode. +- * Thus the super-ugly hacky success check below. +- */ +- ret = magicmouse_enable_multitouch(hdev); +- if (ret != -EIO && ret < 0) { +- hid_err(hdev, "unable to request touch data (%d)\n", ret); +- goto err_stop_hw; +- } +- if (ret == -EIO && (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || +- id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) { +- schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ /* SPI devices need to watch for reset events to re-send the MT enable */ ++ if (id->bus == BUS_SPI) { ++ report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_RESET_REPORT_ID, 0); ++ report->size = 2; + } + + return 0; +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 3 Dec 2023 21:08:17 +0900 +Subject: HID: magicmouse: Query device dimensions via HID report + +For SPI/MTP trackpads, query the dimensions via HID report instead of +hardcoding values. + +TODO: Does this work for the USB/BT devices? Maybe we can get rid of the +hardcoded sizes everywhere? + +Signed-off-by: Hector Martin +--- + drivers/hid/hid-magicmouse.c | 104 +++++++--- + 1 file changed, 80 insertions(+), 24 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -63,6 +63,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define SPI_REPORT_ID 0x02 + #define SPI_RESET_REPORT_ID 0x60 + #define MTP_REPORT_ID 0x75 ++#define SENSOR_DIMENSIONS_REPORT_ID 0xd9 + #define USB_BATTERY_TIMEOUT_SEC 60 + + #define MAX_CONTACTS 16 +@@ -117,6 +118,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++/* These are fallback values, since the real values will be queried from the device. */ + #define J314_TP_DIMENSION_X (float)13000 + #define J314_TP_MIN_X -5900 + #define J314_TP_MAX_X 6500 +@@ -140,6 +142,7 @@ struct magicmouse_input_ops { + * struct magicmouse_sc - Tracks Magic Mouse-specific data. + * @input: Input device through which we report events. + * @quirks: Currently unused. ++ * @query_dimensions: Whether to query and update dimensions on first open + * @ntouches: Number of touches in most recent touch report. + * @scroll_accel: Number of consecutive scroll motions. + * @scroll_jiffies: Time of last scroll motion. +@@ -154,6 +157,7 @@ struct magicmouse_input_ops { + struct magicmouse_sc { + struct input_dev *input; + unsigned long quirks; ++ bool query_dimensions; + + int ntouches; + int scroll_accel; +@@ -179,6 +183,11 @@ struct magicmouse_sc { + + static int magicmouse_enable_multitouch(struct hid_device *hdev); + ++static inline int le16_to_int(__le16 x) ++{ ++ return (signed short)le16_to_cpu(x); ++} ++ + static int magicmouse_open(struct input_dev *dev) + { + struct hid_device *hdev = input_get_drvdata(dev); +@@ -196,21 +205,69 @@ static int magicmouse_open(struct input_dev *dev) + * This results in -EIO from the _raw low-level transport callback, + * but there seems to be no other way of switching the mode. + * Thus the super-ugly hacky success check below. ++ * ++ * MTP devices do not need this. + */ +- ret = magicmouse_enable_multitouch(hdev); +- if (ret != -EIO && ret < 0) { +- hid_err(hdev, "unable to request touch data (%d)\n", ret); +- return ret; +- } +- if (ret == -EIO && (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || +- hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) { +- schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ if (hdev->bus != BUS_HOST) { ++ ret = magicmouse_enable_multitouch(hdev); ++ if (ret != -EIO && ret < 0) { ++ hid_err(hdev, "unable to request touch data (%d)\n", ret); ++ return ret; ++ } ++ if (ret == -EIO && (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || ++ hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) { ++ schedule_delayed_work(&msc->work, msecs_to_jiffies(500)); ++ } + } + + /* +- * MT enable is usually not required after the first time, so don't +- * consider it fatal. ++ * For Apple Silicon trackpads, we want to query the dimensions on ++ * device open. This is because doing so requires the firmware, but ++ * we don't want to force a firmware load until the device is opened ++ * for the first time. So do that here and update the input properties ++ * just in time before userspace queries them. + */ ++ if (msc->query_dimensions) { ++ struct input_dev *input = msc->input; ++ u8 buf[32]; ++ struct { ++ __le32 width; ++ __le32 height; ++ __le16 min_x; ++ __le16 min_y; ++ __le16 max_x; ++ __le16 max_y; ++ } dim; ++ uint32_t x_span, y_span; ++ ++ ret = hid_hw_raw_request(hdev, SENSOR_DIMENSIONS_REPORT_ID, buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_GET_REPORT); ++ if (ret < (int)(1 + sizeof(dim))) { ++ hid_err(hdev, "unable to request dimensions (%d)\n", ret); ++ return ret; ++ } ++ ++ memcpy(&dim, buf + 1, sizeof(dim)); ++ ++ /* finger position */ ++ input_set_abs_params(input, ABS_MT_POSITION_X, ++ le16_to_int(dim.min_x), le16_to_int(dim.max_x), 0, 0); ++ /* Y axis is inverted */ ++ input_set_abs_params(input, ABS_MT_POSITION_Y, ++ -le16_to_int(dim.max_y), -le16_to_int(dim.min_y), 0, 0); ++ x_span = le16_to_int(dim.max_x) - le16_to_int(dim.min_x); ++ y_span = le16_to_int(dim.max_y) - le16_to_int(dim.min_y); ++ ++ /* X/Y resolution */ ++ input_abs_set_res(input, ABS_MT_POSITION_X, 100 * x_span / le32_to_cpu(dim.width) ); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, 100 * y_span / le32_to_cpu(dim.height) ); ++ ++ /* copy info, as input_mt_init_slots() does */ ++ dev->absinfo[ABS_X] = dev->absinfo[ABS_MT_POSITION_X]; ++ dev->absinfo[ABS_Y] = dev->absinfo[ABS_MT_POSITION_Y]; ++ ++ msc->query_dimensions = false; ++ } ++ + return 0; + } + +@@ -660,11 +717,6 @@ struct tp_mouse_report { + u8 padding[4]; + }; + +-static inline int le16_to_int(__le16 x) +-{ +- return (signed short)le16_to_cpu(x); +-} +- + static void report_finger_data(struct input_dev *input, int slot, + const struct input_mt_pos *pos, + const struct tp_finger *f) +@@ -971,6 +1023,7 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + { + int error; + int mt_flags = 0; ++ struct magicmouse_sc *msc = hid_get_drvdata(hdev); + + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + __clear_bit(BTN_0, input->keybit); +@@ -1036,6 +1089,18 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + if (error) + return error; + ++ /* ++ * Override the default input->open function to send the MT ++ * enable every time the device is opened. This ensures it works ++ * even if we missed a reset event due to the device being closed. ++ * input->close is overridden for symmetry. ++ * ++ * This also takes care of the dimensions query. ++ */ ++ input->open = magicmouse_open; ++ input->close = magicmouse_close; ++ msc->query_dimensions = true; ++ + return 0; + } + +@@ -1046,15 +1111,6 @@ static int magicmouse_setup_input_spi(struct input_dev *input, + if (ret) + return ret; + +- /* +- * Override the default input->open function to send the MT +- * enable every time the device is opened. This ensures it works +- * even if we missed a reset event due to the device being closed. +- * input->close is overridden for symmetry. +- */ +- input->open = magicmouse_open; +- input->close = magicmouse_close; +- + return 0; + } + +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janne Grunau +Date: Fri, 10 Dec 2021 19:38:43 +0100 +Subject: WIP: HID: transport: spi: add Apple SPI transport + +Keyboard and trackpad of Apple Sillicon SoCs (M1, M1 Pro/Max) laptops +are are HID devices connected via SPI. + +This is the same protocol as implemented by applespi.c. It was not +noticed that protocol is a transport for HID. Adding support for ACPI +based Intel MacBooks will be done in a separate commit. + +How HID is mapped in this protocol is not yet fully understood. + +Microsoft has a specification for HID over SPI [1] incompatible with the +transport protocol used by Apple. + +[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/hid-over-spi + +Contains "HID: transport: spi: apple: Increase receive buffer size" + +The SPI receive buffer is passed directly to hid_input_report() if it +contains a complete report. It is then passed to hid_report_raw_event() +which computes the expected report size and memsets the "missing +trailing data up to HID_MAX_BUFFER_SIZE (16K) or +hid_ll_driver.max_buffer_size (if set) to zero. + +Co-developed-by: Hector Martin +Signed-off-by: Hector Martin +Signed-off-by: Janne Grunau +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 2 + + drivers/hid/spi-hid/Kconfig | 26 + + drivers/hid/spi-hid/Makefile | 10 + + drivers/hid/spi-hid/spi-hid-apple-core.c | 1194 ++++++++++ + drivers/hid/spi-hid/spi-hid-apple-of.c | 153 ++ + drivers/hid/spi-hid/spi-hid-apple.h | 35 + + 7 files changed, 1422 insertions(+) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1447,4 +1447,6 @@ endif # HID + + source "drivers/hid/usbhid/Kconfig" + ++source "drivers/hid/spi-hid/Kconfig" ++ + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -173,6 +173,8 @@ obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-hid/ + + obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + ++obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ ++ + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + + obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/ +diff --git a/drivers/hid/spi-hid/Kconfig b/drivers/hid/spi-hid/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/Kconfig +@@ -0,0 +1,26 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++menu "SPI HID support" ++ depends on SPI ++ ++config SPI_HID_APPLE_OF ++ tristate "HID over SPI transport layer for Apple Silicon SoCs" ++ default ARCH_APPLE ++ depends on SPI && INPUT && OF ++ help ++ Say Y here if you use Apple Silicon based laptop. The keyboard and ++ touchpad are HID based devices connected via SPI. ++ ++ If unsure, say N. ++ ++ This support is also available as a module. If so, the module ++ will be called spi-hid-apple-of. It will also build/depend on the ++ module spi-hid-apple. ++ ++endmenu ++ ++config SPI_HID_APPLE_CORE ++ tristate ++ default y if SPI_HID_APPLE_OF=y ++ default m if SPI_HID_APPLE_OF=m ++ select HID ++ select CRC16 +diff --git a/drivers/hid/spi-hid/Makefile b/drivers/hid/spi-hid/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/Makefile +@@ -0,0 +1,10 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Makefile for SPI HID tarnsport drivers ++# ++ ++obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid-apple.o ++ ++spi-hid-apple-objs = spi-hid-apple-core.o ++ ++obj-$(CONFIG_SPI_HID_APPLE_OF) += spi-hid-apple-of.o +diff --git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c +@@ -0,0 +1,1194 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 ++ * ++ * Apple SPI HID transport driver ++ * ++ * Copyright (C) The Asahi Linux Contributors ++ * ++ * Based on: drivers/input/applespi.c ++ * ++ * MacBook (Pro) SPI keyboard and touchpad driver ++ * ++ * Copyright (c) 2015-2018 Federico Lorenzi ++ * Copyright (c) 2017-2018 Ronald Tschalär ++ * ++ */ ++ ++//#define DEBUG 2 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "spi-hid-apple.h" ++ ++#define SPIHID_DEF_WAIT msecs_to_jiffies(1000) ++ ++#define SPIHID_MAX_INPUT_REPORT_SIZE 0x800 ++ ++/* support only keyboard, trackpad and management dev for now */ ++#define SPIHID_MAX_DEVICES 3 ++ ++#define SPIHID_DEVICE_ID_MNGT 0x0 ++#define SPIHID_DEVICE_ID_KBD 0x1 ++#define SPIHID_DEVICE_ID_TP 0x2 ++#define SPIHID_DEVICE_ID_INFO 0xd0 ++ ++#define SPIHID_READ_PACKET 0x20 ++#define SPIHID_WRITE_PACKET 0x40 ++ ++#define SPIHID_DESC_MAX 512 ++ ++#define SPIHID_SET_LEDS 0x0151 /* caps lock */ ++ ++#define SPI_RW_CHG_DELAY_US 200 /* 'Inter Stage Us'? */ ++ ++static const u8 spi_hid_apple_booted[4] = { 0xa0, 0x80, 0x00, 0x00 }; ++static const u8 spi_hid_apple_status_ok[4] = { 0xac, 0x27, 0x68, 0xd5 }; ++ ++struct spihid_interface { ++ struct hid_device *hid; ++ u8 *hid_desc; ++ u32 hid_desc_len; ++ u32 id; ++ unsigned country; ++ u32 max_control_report_len; ++ u32 max_input_report_len; ++ u32 max_output_report_len; ++ u8 name[32]; ++ u8 reply_buf[SPIHID_DESC_MAX]; ++ u32 reply_len; ++ bool ready; ++}; ++ ++struct spihid_input_report { ++ u8 *buf; ++ u32 length; ++ u32 offset; ++ u8 device; ++ u8 flags; ++}; ++ ++struct spihid_apple { ++ struct spi_device *spidev; ++ ++ struct spihid_apple_ops *ops; ++ ++ struct spihid_interface mngt; ++ struct spihid_interface kbd; ++ struct spihid_interface tp; ++ ++ wait_queue_head_t wait; ++ struct mutex tx_lock; //< protects against concurrent SPI writes ++ ++ struct spi_message rx_msg; ++ struct spi_message tx_msg; ++ struct spi_transfer rx_transfer; ++ struct spi_transfer tx_transfer; ++ struct spi_transfer status_transfer; ++ ++ u8 *rx_buf; ++ u8 *tx_buf; ++ u8 *status_buf; ++ ++ u8 vendor[32]; ++ u8 product[64]; ++ u8 serial[32]; ++ ++ u32 num_devices; ++ ++ u32 vendor_id; ++ u32 product_id; ++ u32 version_number; ++ ++ u8 msg_id; ++ ++ /* fragmented HID report */ ++ struct spihid_input_report report; ++ ++ /* state tracking flags */ ++ bool status_booted; ++ ++#ifdef IRQ_WAKE_SUPPORT ++ bool irq_wake_enabled; ++#endif ++}; ++ ++/** ++ * struct spihid_msg_hdr - common header of protocol messages. ++ * ++ * Each message begins with fixed header, followed by a message-type specific ++ * payload, and ends with a 16-bit crc. Because of the varying lengths of the ++ * payload, the crc is defined at the end of each payload struct, rather than ++ * in this struct. ++ * ++ * @unknown0: request type? output, input (0x10), feature, protocol ++ * @unknown1: maybe report id? ++ * @unknown2: mostly zero, in info request maybe device num ++ * @id: incremented on each message, rolls over after 255; there is a ++ * separate counter for each message type. ++ * @rsplen: response length (the exact nature of this field is quite ++ * speculative). On a request/write this is often the same as ++ * @length, though in some cases it has been seen to be much larger ++ * (e.g. 0x400); on a response/read this the same as on the ++ * request; for reads that are not responses it is 0. ++ * @length: length of the remainder of the data in the whole message ++ * structure (after re-assembly in case of being split over ++ * multiple spi-packets), minus the trailing crc. The total size ++ * of a message is therefore @length + 10. ++ */ ++ ++struct spihid_msg_hdr { ++ u8 unknown0; ++ u8 unknown1; ++ u8 unknown2; ++ u8 id; ++ __le16 rsplen; ++ __le16 length; ++}; ++ ++/** ++ * struct spihid_transfer_packet - a complete spi packet; always 256 bytes. This carries ++ * the (parts of the) message in the data. But note that this does not ++ * necessarily contain a complete message, as in some cases (e.g. many ++ * fingers pressed) the message is split over multiple packets (see the ++ * @offset, @remain, and @length fields). In general the data parts in ++ * spihid_transfer_packet's are concatenated until @remaining is 0, and the ++ * result is an message. ++ * ++ * @flags: 0x40 = write (to device), 0x20 = read (from device); note that ++ * the response to a write still has 0x40. ++ * @device: 1 = keyboard, 2 = touchpad ++ * @offset: specifies the offset of this packet's data in the complete ++ * message; i.e. > 0 indicates this is a continuation packet (in ++ * the second packet for a message split over multiple packets ++ * this would then be the same as the @length in the first packet) ++ * @remain: number of message bytes remaining in subsequents packets (in ++ * the first packet of a message split over two packets this would ++ * then be the same as the @length in the second packet) ++ * @length: length of the valid data in the @data in this packet ++ * @data: all or part of a message ++ * @crc16: crc over this whole structure minus this @crc16 field. This ++ * covers just this packet, even on multi-packet messages (in ++ * contrast to the crc in the message). ++ */ ++struct spihid_transfer_packet { ++ u8 flags; ++ u8 device; ++ __le16 offset; ++ __le16 remain; ++ __le16 length; ++ u8 data[246]; ++ __le16 crc16; ++}; ++ ++/* ++ * how HID is mapped onto the protocol is not fully clear. This are the known ++ * reports/request: ++ * ++ * pkt.flags pkt.dev? msg.u0 msg.u1 msg.u2 ++ * info 0x40 0xd0 0x20 0x01 0xd0 ++ * ++ * info mngt: 0x40 0xd0 0x20 0x10 0x00 ++ * info kbd: 0x40 0xd0 0x20 0x10 0x01 ++ * info tp: 0x40 0xd0 0x20 0x10 0x02 ++ * ++ * desc kbd: 0x40 0xd0 0x20 0x10 0x01 ++ * desc trackpad: 0x40 0xd0 0x20 0x10 0x02 ++ * ++ * mt mode: 0x40 0x02 0x52 0x02 0x00 set protocol? ++ * capslock led 0x40 0x01 0x51 0x01 0x00 output report ++ * ++ * report kbd: 0x20 0x01 0x10 0x01 0x00 input report ++ * report tp: 0x20 0x02 0x10 0x02 0x00 input report ++ * ++ */ ++ ++ ++static int spihid_apple_request(struct spihid_apple *spihid, u8 target, u8 unk0, ++ u8 unk1, u8 unk2, u16 resp_len, u8 *buf, ++ size_t len) ++{ ++ struct spihid_transfer_packet *pkt; ++ struct spihid_msg_hdr *hdr; ++ u16 crc; ++ int err; ++ ++ /* know reports are small enoug to fit in a single packet */ ++ if (len > sizeof(pkt->data) - sizeof(*hdr) - sizeof(__le16)) ++ return -EINVAL; ++ ++ err = mutex_lock_interruptible(&spihid->tx_lock); ++ if (err < 0) ++ return err; ++ ++ pkt = (struct spihid_transfer_packet *)spihid->tx_buf; ++ ++ memset(pkt, 0, sizeof(*pkt)); ++ pkt->flags = SPIHID_WRITE_PACKET; ++ pkt->device = target; ++ pkt->length = cpu_to_le16(sizeof(*hdr) + len + sizeof(__le16)); ++ ++ hdr = (struct spihid_msg_hdr *)&pkt->data[0]; ++ hdr->unknown0 = unk0; ++ hdr->unknown1 = unk1; ++ hdr->unknown2 = unk2; ++ hdr->id = spihid->msg_id++; ++ hdr->rsplen = cpu_to_le16(resp_len); ++ hdr->length = cpu_to_le16(len); ++ ++ if (len) ++ memcpy(pkt->data + sizeof(*hdr), buf, len); ++ crc = crc16(0, &pkt->data[0], sizeof(*hdr) + len); ++ put_unaligned_le16(crc, pkt->data + sizeof(*hdr) + len); ++ ++ pkt->crc16 = cpu_to_le16(crc16(0, spihid->tx_buf, ++ offsetof(struct spihid_transfer_packet, crc16))); ++ ++ memset(spihid->status_buf, 0, sizeof(spi_hid_apple_status_ok)); ++ ++ err = spi_sync(spihid->spidev, &spihid->tx_msg); ++ ++ if (memcmp(spihid->status_buf, spi_hid_apple_status_ok, ++ sizeof(spi_hid_apple_status_ok))) { ++ u8 *b = spihid->status_buf; ++ dev_warn_ratelimited(&spihid->spidev->dev, "status message " ++ "mismatch: %02x %02x %02x %02x\n", ++ b[0], b[1], b[2], b[3]); ++ } ++ mutex_unlock(&spihid->tx_lock); ++ if (err < 0) ++ return err; ++ ++ return (int)len; ++} ++ ++static struct spihid_apple *spihid_get_data(struct spihid_interface *idev) ++{ ++ switch (idev->id) { ++ case SPIHID_DEVICE_ID_KBD: ++ return container_of(idev, struct spihid_apple, kbd); ++ case SPIHID_DEVICE_ID_TP: ++ return container_of(idev, struct spihid_apple, tp); ++ default: ++ return NULL; ++ } ++} ++ ++static int apple_ll_start(struct hid_device *hdev) ++{ ++ /* no-op SPI transport is already setup */ ++ return 0; ++}; ++ ++static void apple_ll_stop(struct hid_device *hdev) ++{ ++ /* no-op, devices will be desstroyed on driver destruction */ ++} ++ ++static int apple_ll_open(struct hid_device *hdev) ++{ ++ struct spihid_apple *spihid; ++ struct spihid_interface *idev = hdev->driver_data; ++ ++ if (idev->hid_desc_len == 0) { ++ spihid = spihid_get_data(idev); ++ dev_warn(&spihid->spidev->dev, ++ "HID descriptor missing for dev %u", idev->id); ++ } else ++ idev->ready = true; ++ ++ return 0; ++} ++ ++static void apple_ll_close(struct hid_device *hdev) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ idev->ready = false; ++} ++ ++static int apple_ll_parse(struct hid_device *hdev) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ ++ return hid_parse_report(hdev, idev->hid_desc, idev->hid_desc_len); ++} ++ ++static int apple_ll_raw_request(struct hid_device *hdev, ++ unsigned char reportnum, __u8 *buf, size_t len, ++ unsigned char rtype, int reqtype) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ struct spihid_apple *spihid = spihid_get_data(idev); ++ int ret; ++ ++ dev_dbg(&spihid->spidev->dev, ++ "apple_ll_raw_request: device:%u reportnum:%hhu rtype:%hhu", ++ idev->id, reportnum, rtype); ++ ++ switch (reqtype) { ++ case HID_REQ_GET_REPORT: ++ if (rtype != HID_FEATURE_REPORT) ++ return -EINVAL; ++ ++ idev->reply_len = 0; ++ ret = spihid_apple_request(spihid, idev->id, 0x32, reportnum, 0x00, len, NULL, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = wait_event_interruptible_timeout(spihid->wait, idev->reply_len, ++ SPIHID_DEF_WAIT); ++ if (ret == 0) ++ ret = -ETIMEDOUT; ++ if (ret < 0) { ++ dev_err(&spihid->spidev->dev, "waiting for get report failed: %d", ret); ++ return ret; ++ } ++ memcpy(buf, idev->reply_buf, max_t(size_t, len, idev->reply_len)); ++ return idev->reply_len; ++ ++ case HID_REQ_SET_REPORT: ++ if (buf[0] != reportnum) ++ return -EINVAL; ++ if (reportnum != idev->id) { ++ dev_warn(&spihid->spidev->dev, ++ "device:%u reportnum:" ++ "%hhu mismatch", ++ idev->id, reportnum); ++ return -EINVAL; ++ } ++ return spihid_apple_request(spihid, idev->id, 0x52, reportnum, 0x00, 2, buf, len); ++ default: ++ return -EIO; ++ } ++} ++ ++static int apple_ll_output_report(struct hid_device *hdev, __u8 *buf, ++ size_t len) ++{ ++ struct spihid_interface *idev = hdev->driver_data; ++ struct spihid_apple *spihid = spihid_get_data(idev); ++ if (!spihid) ++ return -1; ++ ++ dev_dbg(&spihid->spidev->dev, ++ "apple_ll_output_report: device:%u len:%zu:", ++ idev->id, len); ++ // second idev->id should maybe be buf[0]? ++ return spihid_apple_request(spihid, idev->id, 0x51, idev->id, 0x00, 0, buf, len); ++} ++ ++static struct hid_ll_driver apple_hid_ll = { ++ .start = &apple_ll_start, ++ .stop = &apple_ll_stop, ++ .open = &apple_ll_open, ++ .close = &apple_ll_close, ++ .parse = &apple_ll_parse, ++ .raw_request = &apple_ll_raw_request, ++ .output_report = &apple_ll_output_report, ++ .max_buffer_size = SPIHID_MAX_INPUT_REPORT_SIZE, ++}; ++ ++static struct spihid_interface *spihid_get_iface(struct spihid_apple *spihid, ++ u32 iface) ++{ ++ switch (iface) { ++ case SPIHID_DEVICE_ID_MNGT: ++ return &spihid->mngt; ++ case SPIHID_DEVICE_ID_KBD: ++ return &spihid->kbd; ++ case SPIHID_DEVICE_ID_TP: ++ return &spihid->tp; ++ default: ++ return NULL; ++ } ++} ++ ++static int spihid_verify_msg(struct spihid_apple *spihid, u8 *buf, size_t len) ++{ ++ u16 msg_crc, crc; ++ struct device *dev = &spihid->spidev->dev; ++ ++ crc = crc16(0, buf, len - sizeof(__le16)); ++ msg_crc = get_unaligned_le16(buf + len - sizeof(__le16)); ++ if (crc != msg_crc) { ++ dev_warn_ratelimited(dev, "Read message crc mismatch\n"); ++ return 0; ++ } ++ return 1; ++} ++ ++static bool spihid_status_report(struct spihid_apple *spihid, u8 *pl, ++ size_t len) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ dev_dbg(dev, "%s: len: %zu", __func__, len); ++ if (len == 5 && pl[0] == 0xe0) ++ return true; ++ ++ return false; ++} ++ ++static bool spihid_process_input_report(struct spihid_apple *spihid, u32 device, ++ struct spihid_msg_hdr *hdr, u8 *payload, ++ size_t len) ++{ ++ //dev_dbg(&spihid>spidev->dev, "input report: req:%hx iface:%u ", hdr->unknown0, device); ++ if (hdr->unknown0 != 0x10) ++ return false; ++ ++ /* HID device as well but Vendor usage only, handle it internally for now */ ++ if (device == 0) { ++ if (hdr->unknown1 == 0xe0) { ++ return spihid_status_report(spihid, payload, len); ++ } ++ } else if (device < SPIHID_MAX_DEVICES) { ++ struct spihid_interface *iface = ++ spihid_get_iface(spihid, device); ++ if (iface && iface->hid && iface->ready) { ++ hid_input_report(iface->hid, HID_INPUT_REPORT, payload, ++ len, 1); ++ return true; ++ } ++ } else ++ dev_dbg(&spihid->spidev->dev, ++ "unexpected iface:%u for input report", device); ++ ++ return false; ++} ++ ++struct spihid_device_info { ++ __le16 u0[2]; ++ __le16 num_devices; ++ __le16 vendor_id; ++ __le16 product_id; ++ __le16 version_number; ++ __le16 vendor_str[2]; //< offset and string length ++ __le16 product_str[2]; //< offset and string length ++ __le16 serial_str[2]; //< offset and string length ++}; ++ ++static bool spihid_process_device_info(struct spihid_apple *spihid, u32 iface, ++ u8 *payload, size_t len) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ ++ if (iface != SPIHID_DEVICE_ID_INFO) ++ return false; ++ ++ if (spihid->vendor_id == 0 && ++ len >= sizeof(struct spihid_device_info)) { ++ struct spihid_device_info *info = ++ (struct spihid_device_info *)payload; ++ u16 voff, vlen, poff, plen, soff, slen; ++ u32 num_devices; ++ ++ num_devices = __le16_to_cpu(info->num_devices); ++ ++ if (num_devices < SPIHID_MAX_DEVICES) { ++ dev_err(dev, ++ "Device info reports %u devices, expecting at least 3", ++ num_devices); ++ return false; ++ } ++ spihid->num_devices = num_devices; ++ ++ if (spihid->num_devices > SPIHID_MAX_DEVICES) { ++ dev_info( ++ dev, ++ "limiting the number of devices to mngt, kbd and mouse"); ++ spihid->num_devices = SPIHID_MAX_DEVICES; ++ } ++ ++ spihid->vendor_id = __le16_to_cpu(info->vendor_id); ++ spihid->product_id = __le16_to_cpu(info->product_id); ++ spihid->version_number = __le16_to_cpu(info->version_number); ++ ++ voff = __le16_to_cpu(info->vendor_str[0]); ++ vlen = __le16_to_cpu(info->vendor_str[1]); ++ ++ if (voff < len && vlen <= len - voff && ++ vlen < sizeof(spihid->vendor)) { ++ memcpy(spihid->vendor, payload + voff, vlen); ++ spihid->vendor[vlen] = '\0'; ++ } ++ ++ poff = __le16_to_cpu(info->product_str[0]); ++ plen = __le16_to_cpu(info->product_str[1]); ++ ++ if (poff < len && plen <= len - poff && ++ plen < sizeof(spihid->product)) { ++ memcpy(spihid->product, payload + poff, plen); ++ spihid->product[plen] = '\0'; ++ } ++ ++ soff = __le16_to_cpu(info->serial_str[0]); ++ slen = __le16_to_cpu(info->serial_str[1]); ++ ++ if (soff < len && slen <= len - soff && ++ slen < sizeof(spihid->serial)) { ++ memcpy(spihid->vendor, payload + soff, slen); ++ spihid->serial[slen] = '\0'; ++ } ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ return true; ++} ++ ++struct spihid_iface_info { ++ u8 u_0; ++ u8 interface_num; ++ u8 u_2; ++ u8 u_3; ++ u8 u_4; ++ u8 country_code; ++ __le16 max_input_report_len; ++ __le16 max_output_report_len; ++ __le16 max_control_report_len; ++ __le16 name_offset; ++ __le16 name_length; ++}; ++ ++static bool spihid_process_iface_info(struct spihid_apple *spihid, u32 num, ++ u8 *payload, size_t len) ++{ ++ struct spihid_iface_info *info; ++ struct spihid_interface *iface = spihid_get_iface(spihid, num); ++ u32 name_off, name_len; ++ ++ if (!iface) ++ return false; ++ ++ if (!iface->max_input_report_len) { ++ if (len < sizeof(*info)) ++ return false; ++ ++ info = (struct spihid_iface_info *)payload; ++ ++ iface->max_input_report_len = ++ le16_to_cpu(info->max_input_report_len); ++ iface->max_output_report_len = ++ le16_to_cpu(info->max_output_report_len); ++ iface->max_control_report_len = ++ le16_to_cpu(info->max_control_report_len); ++ iface->country = info->country_code; ++ ++ name_off = le16_to_cpu(info->name_offset); ++ name_len = le16_to_cpu(info->name_length); ++ ++ if (name_off < len && name_len <= len - name_off && ++ name_len < sizeof(iface->name)) { ++ memcpy(iface->name, payload + name_off, name_len); ++ iface->name[name_len] = '\0'; ++ } ++ ++ dev_dbg(&spihid->spidev->dev, "Info for %s, country code: 0x%x", ++ iface->name, iface->country); ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ ++ return true; ++} ++ ++static int spihid_register_hid_device(struct spihid_apple *spihid, ++ struct spihid_interface *idev, u8 device); ++ ++static bool spihid_process_iface_hid_report_desc(struct spihid_apple *spihid, ++ u32 num, u8 *payload, ++ size_t len) ++{ ++ struct spihid_interface *iface = spihid_get_iface(spihid, num); ++ ++ if (!iface) ++ return false; ++ ++ if (iface->hid_desc_len == 0) { ++ if (len > SPIHID_DESC_MAX) ++ return false; ++ memcpy(iface->hid_desc, payload, len); ++ iface->hid_desc_len = len; ++ ++ /* do not register the mngt iface as HID device */ ++ if (num > 0) ++ spihid_register_hid_device(spihid, iface, num); ++ ++ wake_up_interruptible(&spihid->wait); ++ } ++ return true; ++} ++ ++static bool spihid_process_iface_get_report(struct spihid_apple *spihid, ++ u32 device, u8 report, ++ u8 *payload, size_t len) ++{ ++ struct spihid_interface *iface = spihid_get_iface(spihid, device); ++ ++ if (!iface) ++ return false; ++ ++ if (len > sizeof(iface->reply_buf) || len < 1) ++ return false; ++ ++ memcpy(iface->reply_buf, payload, len); ++ iface->reply_len = len; ++ ++ wake_up_interruptible(&spihid->wait); ++ ++ return true; ++} ++ ++static bool spihid_process_response(struct spihid_apple *spihid, u32 device, ++ struct spihid_msg_hdr *hdr, u8 *payload, ++ size_t len) ++{ ++ if (hdr->unknown0 == 0x20) { ++ switch (hdr->unknown1) { ++ case 0x01: ++ return spihid_process_device_info(spihid, hdr->unknown2, ++ payload, len); ++ case 0x02: ++ return spihid_process_iface_info(spihid, hdr->unknown2, ++ payload, len); ++ case 0x10: ++ return spihid_process_iface_hid_report_desc( ++ spihid, hdr->unknown2, payload, len); ++ default: ++ break; ++ } ++ } ++ ++ if (hdr->unknown0 == 0x32) { ++ return spihid_process_iface_get_report(spihid, device, hdr->unknown1, payload, len); ++ } ++ ++ return false; ++} ++ ++static void spihid_process_message(struct spihid_apple *spihid, u8 *data, ++ size_t length, u8 device, u8 flags) ++{ ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_msg_hdr *hdr; ++ bool handled = false; ++ size_t payload_len; ++ u8 *payload; ++ ++ if (!spihid_verify_msg(spihid, data, length)) ++ return; ++ ++ hdr = (struct spihid_msg_hdr *)data; ++ payload_len = le16_to_cpu(hdr->length); ++ ++ if (payload_len == 0 || ++ (payload_len + sizeof(struct spihid_msg_hdr) + 2) > length) ++ return; ++ ++ payload = data + sizeof(struct spihid_msg_hdr); ++ ++ switch (flags) { ++ case SPIHID_READ_PACKET: ++ handled = spihid_process_input_report(spihid, device, hdr, ++ payload, payload_len); ++ break; ++ case SPIHID_WRITE_PACKET: ++ handled = spihid_process_response(spihid, device, hdr, payload, ++ payload_len); ++ break; ++ default: ++ break; ++ } ++ ++#if defined(DEBUG) && DEBUG > 1 ++ { ++ dev_dbg(dev, ++ "R msg: req:%02hhx rep:%02hhx dev:%02hhx id:%hu len:%hu\n", ++ hdr->unknown0, hdr->unknown1, hdr->unknown2, hdr->id, ++ hdr->length); ++ print_hex_dump_debug("spihid msg: ", DUMP_PREFIX_OFFSET, 16, 1, ++ payload, le16_to_cpu(hdr->length), true); ++ } ++#else ++ if (!handled) { ++ dev_dbg(dev, ++ "R unhandled msg: req:%02hhx rep:%02hhx dev:%02hhx id:%hu len:%hu\n", ++ hdr->unknown0, hdr->unknown1, hdr->unknown2, hdr->id, ++ hdr->length); ++ print_hex_dump_debug("spihid msg: ", DUMP_PREFIX_OFFSET, 16, 1, ++ payload, le16_to_cpu(hdr->length), true); ++ } ++#endif ++} ++ ++static void spihid_assemble_message(struct spihid_apple *spihid, ++ struct spihid_transfer_packet *pkt) ++{ ++ size_t length, offset, remain; ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_input_report *rep = &spihid->report; ++ ++ length = le16_to_cpu(pkt->length); ++ remain = le16_to_cpu(pkt->remain); ++ offset = le16_to_cpu(pkt->offset); ++ ++ if (offset + length + remain > U16_MAX) { ++ return; ++ } ++ ++ if (pkt->device != rep->device || pkt->flags != rep->flags || ++ offset != rep->offset) { ++ rep->device = 0; ++ rep->flags = 0; ++ rep->offset = 0; ++ rep->length = 0; ++ } ++ ++ if (offset == 0) { ++ if (rep->offset != 0) { ++ dev_warn(dev, "incomplete report off:%u len:%u", ++ rep->offset, rep->length); ++ } ++ memcpy(rep->buf, pkt->data, length); ++ rep->offset = length; ++ rep->length = length + remain; ++ rep->device = pkt->device; ++ rep->flags = pkt->flags; ++ } else if (offset == rep->offset) { ++ if (offset + length + remain != rep->length) { ++ dev_warn(dev, "incomplete report off:%u len:%u", ++ rep->offset, rep->length); ++ return; ++ } ++ memcpy(rep->buf + offset, pkt->data, length); ++ rep->offset += length; ++ ++ if (rep->offset == rep->length) { ++ spihid_process_message(spihid, rep->buf, rep->length, ++ rep->device, rep->flags); ++ rep->device = 0; ++ rep->flags = 0; ++ rep->offset = 0; ++ rep->length = 0; ++ } ++ } ++} ++ ++static void spihid_process_read(struct spihid_apple *spihid) ++{ ++ u16 crc; ++ size_t length; ++ struct device *dev = &spihid->spidev->dev; ++ struct spihid_transfer_packet *pkt; ++ ++ pkt = (struct spihid_transfer_packet *)spihid->rx_buf; ++ ++ /* check transfer packet crc */ ++ crc = crc16(0, spihid->rx_buf, ++ offsetof(struct spihid_transfer_packet, crc16)); ++ if (crc != le16_to_cpu(pkt->crc16)) { ++ dev_warn_ratelimited(dev, "Read package crc mismatch\n"); ++ return; ++ } ++ ++ length = le16_to_cpu(pkt->length); ++ ++ if (length < sizeof(struct spihid_msg_hdr) + 2) { ++ if (length == sizeof(spi_hid_apple_booted) && ++ !memcmp(pkt->data, spi_hid_apple_booted, length)) { ++ if (!spihid->status_booted) { ++ spihid->status_booted = true; ++ wake_up_interruptible(&spihid->wait); ++ } ++ } else { ++ dev_info(dev, "R short packet: len:%zu\n", length); ++ print_hex_dump(KERN_INFO, "spihid pkt:", ++ DUMP_PREFIX_OFFSET, 16, 1, pkt->data, ++ length, false); ++ } ++ return; ++ } ++ ++#if defined(DEBUG) && DEBUG > 1 ++ dev_dbg(dev, ++ "R pkt: flags:%02hhx dev:%02hhx off:%hu remain:%hu, len:%zu\n", ++ pkt->flags, pkt->device, pkt->offset, pkt->remain, length); ++#if defined(DEBUG) && DEBUG > 2 ++ print_hex_dump_debug("spihid pkt: ", DUMP_PREFIX_OFFSET, 16, 1, ++ spihid->rx_buf, ++ sizeof(struct spihid_transfer_packet), true); ++#endif ++#endif ++ ++ if (length > sizeof(pkt->data)) { ++ dev_warn_ratelimited(dev, "Invalid pkt len:%zu", length); ++ return; ++ } ++ ++ /* short message */ ++ if (pkt->offset == 0 && pkt->remain == 0) { ++ spihid_process_message(spihid, pkt->data, length, pkt->device, ++ pkt->flags); ++ } else { ++ spihid_assemble_message(spihid, pkt); ++ } ++} ++ ++static void spihid_read_packet_sync(struct spihid_apple *spihid) ++{ ++ int err; ++ ++ err = spi_sync(spihid->spidev, &spihid->rx_msg); ++ if (!err) { ++ spihid_process_read(spihid); ++ } else { ++ dev_warn(&spihid->spidev->dev, "RX failed: %d\n", err); ++ } ++} ++ ++irqreturn_t spihid_apple_core_irq(int irq, void *data) ++{ ++ struct spi_device *spi = data; ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ spihid_read_packet_sync(spihid); ++ ++ return IRQ_HANDLED; ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_irq); ++ ++static void spihid_apple_setup_spi_msgs(struct spihid_apple *spihid) ++{ ++ memset(&spihid->rx_transfer, 0, sizeof(spihid->rx_transfer)); ++ ++ spihid->rx_transfer.rx_buf = spihid->rx_buf; ++ spihid->rx_transfer.len = sizeof(struct spihid_transfer_packet); ++ ++ spi_message_init(&spihid->rx_msg); ++ spi_message_add_tail(&spihid->rx_transfer, &spihid->rx_msg); ++ ++ memset(&spihid->tx_transfer, 0, sizeof(spihid->rx_transfer)); ++ memset(&spihid->status_transfer, 0, sizeof(spihid->status_transfer)); ++ ++ spihid->tx_transfer.tx_buf = spihid->tx_buf; ++ spihid->tx_transfer.len = sizeof(struct spihid_transfer_packet); ++ spihid->tx_transfer.delay.unit = SPI_DELAY_UNIT_USECS; ++ spihid->tx_transfer.delay.value = SPI_RW_CHG_DELAY_US; ++ ++ spihid->status_transfer.rx_buf = spihid->status_buf; ++ spihid->status_transfer.len = sizeof(spi_hid_apple_status_ok); ++ ++ spi_message_init(&spihid->tx_msg); ++ spi_message_add_tail(&spihid->tx_transfer, &spihid->tx_msg); ++ spi_message_add_tail(&spihid->status_transfer, &spihid->tx_msg); ++} ++ ++static int spihid_apple_setup_spi(struct spihid_apple *spihid) ++{ ++ spihid_apple_setup_spi_msgs(spihid); ++ ++ return spihid->ops->power_on(spihid->ops); ++} ++ ++static int spihid_register_hid_device(struct spihid_apple *spihid, ++ struct spihid_interface *iface, u8 device) ++{ ++ int ret; ++ char *suffix; ++ struct hid_device *hid; ++ ++ iface->id = device; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return PTR_ERR(hid); ++ ++ /* ++ * Use 'Apple SPI Keyboard' and 'Apple SPI Trackpad' as input device ++ * names. The device names need to be distinct since at least Kwin uses ++ * the tripple Vendor ID, Product ID, Name to identify devices. ++ */ ++ snprintf(hid->name, sizeof(hid->name), "Apple SPI %s", iface->name); ++ // strip ' / Boot' suffix from the name ++ suffix = strstr(hid->name, " / Boot"); ++ if (suffix) ++ suffix[0] = '\0'; ++ snprintf(hid->phys, sizeof(hid->phys), "%s (%hhx)", ++ dev_name(&spihid->spidev->dev), device); ++ strscpy(hid->uniq, spihid->serial, sizeof(hid->uniq)); ++ ++ hid->ll_driver = &apple_hid_ll; ++ hid->bus = BUS_SPI; ++ hid->vendor = spihid->vendor_id; ++ hid->product = spihid->product_id; ++ hid->version = spihid->version_number; ++ ++ if (device == SPIHID_DEVICE_ID_KBD) ++ hid->type = HID_TYPE_SPI_KEYBOARD; ++ else if (device == SPIHID_DEVICE_ID_TP) ++ hid->type = HID_TYPE_SPI_MOUSE; ++ ++ hid->country = iface->country; ++ hid->dev.parent = &spihid->spidev->dev; ++ hid->driver_data = iface; ++ ++ ret = hid_add_device(hid); ++ if (ret < 0) { ++ hid_destroy_device(hid); ++ dev_warn(&spihid->spidev->dev, ++ "Failed to register hid device %hhu", device); ++ return ret; ++ } ++ ++ iface->hid = hid; ++ ++ return 0; ++} ++ ++static void spihid_destroy_hid_device(struct spihid_interface *iface) ++{ ++ if (iface->hid) { ++ hid_destroy_device(iface->hid); ++ iface->hid = NULL; ++ } ++ iface->ready = false; ++} ++ ++int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops) ++{ ++ struct device *dev = &spi->dev; ++ struct spihid_apple *spihid; ++ int err, i; ++ ++ if (!ops || !ops->power_on || !ops->power_off || !ops->enable_irq || !ops->disable_irq) ++ return -EINVAL; ++ ++ spihid = devm_kzalloc(dev, sizeof(*spihid), GFP_KERNEL); ++ if (!spihid) ++ return -ENOMEM; ++ ++ spihid->ops = ops; ++ spihid->spidev = spi; ++ ++ // init spi ++ spi_set_drvdata(spi, spihid); ++ ++ /* ++ * allocate SPI buffers ++ * Overallocate the receice buffer since it passed directly into ++ * hid_input_report / hid_report_raw_event. The later expects the buffer ++ * to be HID_MAX_BUFFER_SIZE (16k) or hid_ll_driver.max_buffer_size if ++ * set. ++ */ ++ spihid->rx_buf = devm_kmalloc( ++ &spi->dev, SPIHID_MAX_INPUT_REPORT_SIZE, GFP_KERNEL); ++ spihid->tx_buf = devm_kmalloc( ++ &spi->dev, sizeof(struct spihid_transfer_packet), GFP_KERNEL); ++ spihid->status_buf = devm_kmalloc( ++ &spi->dev, sizeof(spi_hid_apple_status_ok), GFP_KERNEL); ++ ++ if (!spihid->rx_buf || !spihid->tx_buf || !spihid->status_buf) ++ return -ENOMEM; ++ ++ spihid->report.buf = ++ devm_kmalloc(dev, SPIHID_MAX_INPUT_REPORT_SIZE, GFP_KERNEL); ++ ++ spihid->kbd.hid_desc = devm_kmalloc(dev, SPIHID_DESC_MAX, GFP_KERNEL); ++ spihid->tp.hid_desc = devm_kmalloc(dev, SPIHID_DESC_MAX, GFP_KERNEL); ++ ++ if (!spihid->report.buf || !spihid->kbd.hid_desc || ++ !spihid->tp.hid_desc) ++ return -ENOMEM; ++ ++ init_waitqueue_head(&spihid->wait); ++ ++ mutex_init(&spihid->tx_lock); ++ ++ /* Init spi transfer buffers and power device on */ ++ err = spihid_apple_setup_spi(spihid); ++ if (err < 0) ++ goto error; ++ ++ /* enable HID irq */ ++ spihid->ops->enable_irq(spihid->ops); ++ ++ // wait for boot message ++ err = wait_event_interruptible_timeout(spihid->wait, ++ spihid->status_booted, ++ msecs_to_jiffies(1000)); ++ if (err == 0) ++ err = -ENODEV; ++ if (err < 0) { ++ dev_err(dev, "waiting for device boot failed: %d", err); ++ goto error; ++ } ++ ++ /* request device information */ ++ dev_dbg(dev, "request device info"); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x01, 0xd0, 0, NULL, 0); ++ err = wait_event_interruptible_timeout(spihid->wait, spihid->vendor_id, ++ SPIHID_DEF_WAIT); ++ if (err == 0) ++ err = -ENODEV; ++ if (err < 0) { ++ dev_err(dev, "waiting for device info failed: %d", err); ++ goto error; ++ } ++ ++ /* request interface information */ ++ for (i = 0; i < spihid->num_devices; i++) { ++ struct spihid_interface *iface = spihid_get_iface(spihid, i); ++ if (!iface) ++ continue; ++ dev_dbg(dev, "request interface info 0x%02x", i); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x02, i, ++ SPIHID_DESC_MAX, NULL, 0); ++ err = wait_event_interruptible_timeout( ++ spihid->wait, iface->max_input_report_len, ++ SPIHID_DEF_WAIT); ++ } ++ ++ /* request HID report descriptors */ ++ for (i = 1; i < spihid->num_devices; i++) { ++ struct spihid_interface *iface = spihid_get_iface(spihid, i); ++ if (!iface) ++ continue; ++ dev_dbg(dev, "request hid report desc 0x%02x", i); ++ spihid_apple_request(spihid, 0xd0, 0x20, 0x10, i, ++ SPIHID_DESC_MAX, NULL, 0); ++ wait_event_interruptible_timeout( ++ spihid->wait, iface->hid_desc_len, SPIHID_DEF_WAIT); ++ } ++ ++ return 0; ++error: ++ return err; ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_probe); ++ ++void spihid_apple_core_remove(struct spi_device *spi) ++{ ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ /* destroy input devices */ ++ ++ spihid_destroy_hid_device(&spihid->tp); ++ spihid_destroy_hid_device(&spihid->kbd); ++ ++ /* disable irq */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++ /* power SPI device down */ ++ spihid->ops->power_off(spihid->ops); ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_remove); ++ ++void spihid_apple_core_shutdown(struct spi_device *spi) ++{ ++ struct spihid_apple *spihid = spi_get_drvdata(spi); ++ ++ /* disable irq */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++ /* power SPI device down */ ++ spihid->ops->power_off(spihid->ops); ++} ++EXPORT_SYMBOL_GPL(spihid_apple_core_shutdown); ++ ++#ifdef CONFIG_PM_SLEEP ++static int spihid_apple_core_suspend(struct device *dev) ++{ ++ int ret; ++#ifdef IRQ_WAKE_SUPPORT ++ int wake_status; ++#endif ++ struct spihid_apple *spihid = spi_get_drvdata(to_spi_device(dev)); ++ ++ if (spihid->tp.hid) { ++ ret = hid_driver_suspend(spihid->tp.hid, PMSG_SUSPEND); ++ if (ret < 0) ++ return ret; ++ } ++ ++ if (spihid->kbd.hid) { ++ ret = hid_driver_suspend(spihid->kbd.hid, PMSG_SUSPEND); ++ if (ret < 0) { ++ if (spihid->tp.hid) ++ hid_driver_resume(spihid->tp.hid); ++ return ret; ++ } ++ } ++ ++ /* Save some power */ ++ spihid->ops->disable_irq(spihid->ops); ++ ++#ifdef IRQ_WAKE_SUPPORT ++ if (device_may_wakeup(dev)) { ++ wake_status = spihid->ops->enable_irq_wake(spihid->ops); ++ if (!wake_status) ++ spihid->irq_wake_enabled = true; ++ else ++ dev_warn(dev, "Failed to enable irq wake: %d\n", ++ wake_status); ++ } else { ++ spihid->ops->power_off(spihid->ops); ++ } ++#else ++ spihid->ops->power_off(spihid->ops); ++#endif ++ ++ return 0; ++} ++ ++static int spihid_apple_core_resume(struct device *dev) ++{ ++ int ret_tp = 0, ret_kbd = 0; ++ struct spihid_apple *spihid = spi_get_drvdata(to_spi_device(dev)); ++#ifdef IRQ_WAKE_SUPPORT ++ int wake_status; ++ ++ if (!device_may_wakeup(dev)) { ++ spihid->ops->power_on(spihid->ops); ++ } else if (spihid->irq_wake_enabled) { ++ wake_status = spihid->ops->disable_irq_wake(spihid->ops); ++ if (!wake_status) ++ spihid->irq_wake_enabled = false; ++ else ++ dev_warn(dev, "Failed to disable irq wake: %d\n", ++ wake_status); ++ } ++#endif ++ ++ spihid->ops->enable_irq(spihid->ops); ++ spihid->ops->power_on(spihid->ops); ++ ++ if (spihid->tp.hid) ++ ret_tp = hid_driver_reset_resume(spihid->tp.hid); ++ if (spihid->kbd.hid) ++ ret_kbd = hid_driver_reset_resume(spihid->kbd.hid); ++ ++ if (ret_tp < 0) ++ return ret_tp; ++ ++ return ret_kbd; ++} ++#endif ++ ++const struct dev_pm_ops spihid_apple_core_pm = { ++ SET_SYSTEM_SLEEP_PM_OPS(spihid_apple_core_suspend, ++ spihid_apple_core_resume) ++}; ++EXPORT_SYMBOL_GPL(spihid_apple_core_pm); ++ ++MODULE_DESCRIPTION("Apple SPI HID transport driver"); ++MODULE_AUTHOR("Janne Grunau "); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/spi-hid/spi-hid-apple-of.c b/drivers/hid/spi-hid/spi-hid-apple-of.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple-of.c +@@ -0,0 +1,153 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 ++ * ++ * Apple SPI HID transport driver - Open Firmware ++ * ++ * Copyright (C) The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "spi-hid-apple.h" ++ ++ ++struct spihid_apple_of { ++ struct spihid_apple_ops ops; ++ ++ struct gpio_desc *enable_gpio; ++ int irq; ++}; ++ ++static int spihid_apple_of_power_on(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ /* reset the controller on boot */ ++ gpiod_direction_output(sh_of->enable_gpio, 1); ++ msleep(5); ++ gpiod_direction_output(sh_of->enable_gpio, 0); ++ msleep(5); ++ /* turn SPI device on */ ++ gpiod_direction_output(sh_of->enable_gpio, 1); ++ msleep(50); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_power_off(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ /* turn SPI device off */ ++ gpiod_direction_output(sh_of->enable_gpio, 0); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_enable_irq(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ enable_irq(sh_of->irq); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_disable_irq(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ disable_irq(sh_of->irq); ++ ++ return 0; ++} ++ ++static int spihid_apple_of_enable_irq_wake(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ return enable_irq_wake(sh_of->irq); ++} ++ ++static int spihid_apple_of_disable_irq_wake(struct spihid_apple_ops *ops) ++{ ++ struct spihid_apple_of *sh_of = container_of(ops, struct spihid_apple_of, ops); ++ ++ return disable_irq_wake(sh_of->irq); ++} ++ ++static int spihid_apple_of_probe(struct spi_device *spi) ++{ ++ struct device *dev = &spi->dev; ++ struct spihid_apple_of *spihid_of; ++ int err; ++ ++ spihid_of = devm_kzalloc(dev, sizeof(*spihid_of), GFP_KERNEL); ++ if (!spihid_of) ++ return -ENOMEM; ++ ++ spihid_of->ops.power_on = spihid_apple_of_power_on; ++ spihid_of->ops.power_off = spihid_apple_of_power_off; ++ spihid_of->ops.enable_irq = spihid_apple_of_enable_irq; ++ spihid_of->ops.disable_irq = spihid_apple_of_disable_irq; ++ spihid_of->ops.enable_irq_wake = spihid_apple_of_enable_irq_wake; ++ spihid_of->ops.disable_irq_wake = spihid_apple_of_disable_irq_wake; ++ ++ spihid_of->enable_gpio = devm_gpiod_get_index(dev, "spien", 0, 0); ++ if (IS_ERR(spihid_of->enable_gpio)) { ++ err = PTR_ERR(spihid_of->enable_gpio); ++ dev_err(dev, "failed to get 'spien' gpio pin: %d", err); ++ return err; ++ } ++ ++ spihid_of->irq = of_irq_get(dev->of_node, 0); ++ if (spihid_of->irq < 0) { ++ err = spihid_of->irq; ++ dev_err(dev, "failed to get 'extended-irq': %d", err); ++ return err; ++ } ++ err = devm_request_threaded_irq(dev, spihid_of->irq, NULL, ++ spihid_apple_core_irq, IRQF_ONESHOT | IRQF_NO_AUTOEN, ++ "spi-hid-apple-irq", spi); ++ if (err < 0) { ++ dev_err(dev, "failed to request extended-irq %d: %d", ++ spihid_of->irq, err); ++ return err; ++ } ++ ++ return spihid_apple_core_probe(spi, &spihid_of->ops); ++} ++ ++static const struct of_device_id spihid_apple_of_match[] = { ++ { .compatible = "apple,spi-hid-transport" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, spihid_apple_of_match); ++ ++static struct spi_device_id spihid_apple_of_id[] = { ++ { "spi-hid-transport", 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(spi, spihid_apple_of_id); ++ ++static struct spi_driver spihid_apple_of_driver = { ++ .driver = { ++ .name = "spi-hid-apple-of", ++ .pm = &spihid_apple_core_pm, ++ .of_match_table = of_match_ptr(spihid_apple_of_match), ++ }, ++ ++ .id_table = spihid_apple_of_id, ++ .probe = spihid_apple_of_probe, ++ .remove = spihid_apple_core_remove, ++ .shutdown = spihid_apple_core_shutdown, ++}; ++ ++module_spi_driver(spihid_apple_of_driver); ++ ++MODULE_DESCRIPTION("Apple SPI HID transport driver for OpenFirmware systems"); ++MODULE_AUTHOR("Janne Grunau "); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/spi-hid/spi-hid-apple.h b/drivers/hid/spi-hid/spi-hid-apple.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/spi-hid/spi-hid-apple.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ ++ ++#ifndef SPI_HID_APPLE_H ++#define SPI_HID_APPLE_H ++ ++#include ++#include ++ ++/** ++ * struct spihid_apple_ops - Ops to control the device from the core driver. ++ * ++ * @power_on: reset and power the device on. ++ * @power_off: power the device off. ++ * @enable_irq: enable irq or ACPI gpe. ++ * @disable_irq: disable irq or ACPI gpe. ++ */ ++ ++struct spihid_apple_ops { ++ int (*power_on)(struct spihid_apple_ops *ops); ++ int (*power_off)(struct spihid_apple_ops *ops); ++ int (*enable_irq)(struct spihid_apple_ops *ops); ++ int (*disable_irq)(struct spihid_apple_ops *ops); ++ int (*enable_irq_wake)(struct spihid_apple_ops *ops); ++ int (*disable_irq_wake)(struct spihid_apple_ops *ops); ++}; ++ ++irqreturn_t spihid_apple_core_irq(int irq, void *data); ++ ++int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops); ++void spihid_apple_core_remove(struct spi_device *spi); ++void spihid_apple_core_shutdown(struct spi_device *spi); ++ ++extern const struct dev_pm_ops spihid_apple_core_pm; ++ ++#endif /* SPI_HID_APPLE_H */ +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:09:24 +0900 +Subject: soc: apple: Add DockChannel driver + +DockChannel is a simple FIFO interface used to communicate between SoC +blocks. Add a driver that represents the shared interrupt controller for +the DockChannel block, and then exposes probe and data transfer +functions that child device drivers can use to instantiate individual +FIFOs. + +Signed-off-by: Hector Martin +--- + drivers/soc/apple/Kconfig | 10 + + drivers/soc/apple/Makefile | 3 + + drivers/soc/apple/dockchannel.c | 406 ++++++++++ + include/linux/soc/apple/dockchannel.h | 26 + + 4 files changed, 445 insertions(+) + +diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Kconfig ++++ b/drivers/soc/apple/Kconfig +@@ -4,6 +4,16 @@ if ARCH_APPLE || COMPILE_TEST + + menu "Apple SoC drivers" + ++config APPLE_DOCKCHANNEL ++ tristate "Apple DockChannel FIFO" ++ depends on ARCH_APPLE || COMPILE_TEST ++ default ARCH_APPLE ++ help ++ DockChannel is a simple FIFO used on Apple SoCs for debug and inter-processor ++ communications. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_MAILBOX + tristate "Apple SoC mailboxes" + depends on PM +diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Makefile ++++ b/drivers/soc/apple/Makefile +@@ -1,5 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++obj-$(CONFIG_APPLE_DOCKCHANNEL) += apple-dockchannel.o ++apple-dockchannel-y = dockchannel.o ++ + obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o + apple-mailbox-y = mailbox.o + +diff --git a/drivers/soc/apple/dockchannel.c b/drivers/soc/apple/dockchannel.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/soc/apple/dockchannel.c +@@ -0,0 +1,406 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Apple DockChannel FIFO driver ++ * Copyright The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DOCKCHANNEL_MAX_IRQ 32 ++ ++#define DOCKCHANNEL_TX_TIMEOUT_MS 1000 ++#define DOCKCHANNEL_RX_TIMEOUT_MS 1000 ++ ++#define IRQ_MASK 0x0 ++#define IRQ_FLAG 0x4 ++ ++#define IRQ_TX BIT(0) ++#define IRQ_RX BIT(1) ++ ++#define CONFIG_TX_THRESH 0x0 ++#define CONFIG_RX_THRESH 0x4 ++ ++#define DATA_TX8 0x4 ++#define DATA_TX16 0x8 ++#define DATA_TX24 0xc ++#define DATA_TX32 0x10 ++#define DATA_TX_FREE 0x14 ++#define DATA_RX8 0x1c ++#define DATA_RX16 0x20 ++#define DATA_RX24 0x24 ++#define DATA_RX32 0x28 ++#define DATA_RX_COUNT 0x2c ++ ++struct dockchannel { ++ struct device *dev; ++ int tx_irq; ++ int rx_irq; ++ ++ void __iomem *config_base; ++ void __iomem *data_base; ++ ++ u32 fifo_size; ++ bool awaiting; ++ struct completion tx_comp; ++ struct completion rx_comp; ++ ++ void *cookie; ++ void (*data_available)(void *cookie, size_t avail); ++}; ++ ++struct dockchannel_common { ++ struct device *dev; ++ struct irq_domain *domain; ++ int irq; ++ ++ void __iomem *irq_base; ++}; ++ ++/* Dockchannel FIFO functions */ ++ ++static irqreturn_t dockchannel_tx_irq(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ ++ disable_irq_nosync(irq); ++ complete(&dockchannel->tx_comp); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t dockchannel_rx_irq(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ ++ disable_irq_nosync(irq); ++ ++ if (dockchannel->awaiting) { ++ return IRQ_WAKE_THREAD; ++ } else { ++ complete(&dockchannel->rx_comp); ++ return IRQ_HANDLED; ++ } ++} ++ ++static irqreturn_t dockchannel_rx_irq_thread(int irq, void *data) ++{ ++ struct dockchannel *dockchannel = data; ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_RX_COUNT); ++ ++ dockchannel->awaiting = false; ++ dockchannel->data_available(dockchannel->cookie, avail); ++ ++ return IRQ_HANDLED; ++} ++ ++int dockchannel_send(struct dockchannel *dockchannel, const void *buf, size_t count) ++{ ++ size_t left = count; ++ const u8 *p = buf; ++ ++ while (left > 0) { ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_TX_FREE); ++ size_t block = min(left, avail); ++ ++ if (avail == 0) { ++ size_t threshold = min((size_t)(dockchannel->fifo_size / 2), left); ++ ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_TX_THRESH); ++ reinit_completion(&dockchannel->tx_comp); ++ enable_irq(dockchannel->tx_irq); ++ ++ if (!wait_for_completion_timeout(&dockchannel->tx_comp, ++ msecs_to_jiffies(DOCKCHANNEL_TX_TIMEOUT_MS))) { ++ disable_irq(dockchannel->tx_irq); ++ return -ETIMEDOUT; ++ } ++ ++ continue; ++ } ++ ++ while (block >= 4) { ++ writel_relaxed(get_unaligned_le32(p), dockchannel->data_base + DATA_TX32); ++ p += 4; ++ left -= 4; ++ block -= 4; ++ } ++ while (block > 0) { ++ writeb_relaxed(*p++, dockchannel->data_base + DATA_TX8); ++ left--; ++ block--; ++ } ++ } ++ ++ return count; ++} ++EXPORT_SYMBOL(dockchannel_send); ++ ++int dockchannel_recv(struct dockchannel *dockchannel, void *buf, size_t count) ++{ ++ size_t left = count; ++ u8 *p = buf; ++ ++ while (left > 0) { ++ size_t avail = readl_relaxed(dockchannel->data_base + DATA_RX_COUNT); ++ size_t block = min(left, avail); ++ ++ if (avail == 0) { ++ size_t threshold = min((size_t)(dockchannel->fifo_size / 2), left); ++ ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_RX_THRESH); ++ reinit_completion(&dockchannel->rx_comp); ++ enable_irq(dockchannel->rx_irq); ++ ++ if (!wait_for_completion_timeout(&dockchannel->rx_comp, ++ msecs_to_jiffies(DOCKCHANNEL_RX_TIMEOUT_MS))) { ++ disable_irq(dockchannel->rx_irq); ++ return -ETIMEDOUT; ++ } ++ ++ continue; ++ } ++ ++ while (block >= 4) { ++ put_unaligned_le32(readl_relaxed(dockchannel->data_base + DATA_RX32), p); ++ p += 4; ++ left -= 4; ++ block -= 4; ++ } ++ while (block > 0) { ++ *p++ = readl_relaxed(dockchannel->data_base + DATA_RX8) >> 8; ++ left--; ++ block--; ++ } ++ } ++ ++ return count; ++} ++EXPORT_SYMBOL(dockchannel_recv); ++ ++int dockchannel_await(struct dockchannel *dockchannel, ++ void (*callback)(void *cookie, size_t avail), ++ void *cookie, size_t count) ++{ ++ size_t threshold = min((size_t)dockchannel->fifo_size, count); ++ ++ if (!count) { ++ dockchannel->awaiting = false; ++ disable_irq(dockchannel->rx_irq); ++ return 0; ++ } ++ ++ dockchannel->data_available = callback; ++ dockchannel->cookie = cookie; ++ dockchannel->awaiting = true; ++ writel_relaxed(threshold, dockchannel->config_base + CONFIG_RX_THRESH); ++ enable_irq(dockchannel->rx_irq); ++ ++ return threshold; ++} ++EXPORT_SYMBOL(dockchannel_await); ++ ++struct dockchannel *dockchannel_init(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel *dockchannel; ++ int ret; ++ ++ dockchannel = devm_kzalloc(dev, sizeof(*dockchannel), GFP_KERNEL); ++ if (!dockchannel) ++ return ERR_PTR(-ENOMEM); ++ ++ dockchannel->dev = dev; ++ dockchannel->config_base = devm_platform_ioremap_resource_byname(pdev, "config"); ++ if (IS_ERR(dockchannel->config_base)) ++ return (__force void *)dockchannel->config_base; ++ ++ dockchannel->data_base = devm_platform_ioremap_resource_byname(pdev, "data"); ++ if (IS_ERR(dockchannel->data_base)) ++ return (__force void *)dockchannel->data_base; ++ ++ ret = of_property_read_u32(dev->of_node, "apple,fifo-size", &dockchannel->fifo_size); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Missing apple,fifo-size property")); ++ ++ init_completion(&dockchannel->tx_comp); ++ init_completion(&dockchannel->rx_comp); ++ ++ dockchannel->tx_irq = platform_get_irq_byname(pdev, "tx"); ++ if (dockchannel->tx_irq <= 0) { ++ return ERR_PTR(dev_err_probe(dev, dockchannel->tx_irq, ++ "Failed to get TX IRQ")); ++ } ++ ++ dockchannel->rx_irq = platform_get_irq_byname(pdev, "rx"); ++ if (dockchannel->rx_irq <= 0) { ++ return ERR_PTR(dev_err_probe(dev, dockchannel->rx_irq, ++ "Failed to get RX IRQ")); ++ } ++ ++ ret = devm_request_irq(dev, dockchannel->tx_irq, dockchannel_tx_irq, IRQF_NO_AUTOEN, ++ "apple-dockchannel-tx", dockchannel); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Failed to request TX IRQ")); ++ ++ ret = devm_request_threaded_irq(dev, dockchannel->rx_irq, dockchannel_rx_irq, ++ dockchannel_rx_irq_thread, IRQF_NO_AUTOEN, ++ "apple-dockchannel-rx", dockchannel); ++ if (ret) ++ return ERR_PTR(dev_err_probe(dev, ret, "Failed to request RX IRQ")); ++ ++ return dockchannel; ++} ++EXPORT_SYMBOL(dockchannel_init); ++ ++ ++/* Dockchannel IRQchip */ ++ ++static void dockchannel_irq(struct irq_desc *desc) ++{ ++ unsigned int irq = irq_desc_get_irq(desc); ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ struct dockchannel_common *dcc = irq_get_handler_data(irq); ++ unsigned long flags = readl_relaxed(dcc->irq_base + IRQ_FLAG); ++ int bit; ++ ++ chained_irq_enter(chip, desc); ++ ++ for_each_set_bit(bit, &flags, DOCKCHANNEL_MAX_IRQ) ++ generic_handle_domain_irq(dcc->domain, bit); ++ ++ chained_irq_exit(chip, desc); ++} ++ ++static void dockchannel_irq_ack(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ ++ writel_relaxed(BIT(hwirq), dcc->irq_base + IRQ_FLAG); ++} ++ ++static void dockchannel_irq_mask(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ u32 val = readl_relaxed(dcc->irq_base + IRQ_MASK); ++ ++ writel_relaxed(val & ~BIT(hwirq), dcc->irq_base + IRQ_MASK); ++} ++ ++static void dockchannel_irq_unmask(struct irq_data *data) ++{ ++ struct dockchannel_common *dcc = irq_data_get_irq_chip_data(data); ++ unsigned int hwirq = data->hwirq; ++ u32 val = readl_relaxed(dcc->irq_base + IRQ_MASK); ++ ++ writel_relaxed(val | BIT(hwirq), dcc->irq_base + IRQ_MASK); ++} ++ ++static const struct irq_chip dockchannel_irqchip = { ++ .name = "dockchannel-irqc", ++ .irq_ack = dockchannel_irq_ack, ++ .irq_mask = dockchannel_irq_mask, ++ .irq_unmask = dockchannel_irq_unmask, ++}; ++ ++static int dockchannel_irq_domain_map(struct irq_domain *d, unsigned int virq, ++ irq_hw_number_t hw) ++{ ++ irq_set_chip_data(virq, d->host_data); ++ irq_set_chip_and_handler(virq, &dockchannel_irqchip, handle_level_irq); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops dockchannel_irq_domain_ops = { ++ .xlate = irq_domain_xlate_twocell, ++ .map = dockchannel_irq_domain_map, ++}; ++ ++static int dockchannel_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel_common *dcc; ++ struct device_node *child; ++ ++ dcc = devm_kzalloc(dev, sizeof(*dcc), GFP_KERNEL); ++ if (!dcc) ++ return -ENOMEM; ++ ++ dcc->dev = dev; ++ platform_set_drvdata(pdev, dcc); ++ ++ dcc->irq_base = devm_platform_ioremap_resource_byname(pdev, "irq"); ++ if (IS_ERR(dcc->irq_base)) ++ return PTR_ERR(dcc->irq_base); ++ ++ writel_relaxed(0, dcc->irq_base + IRQ_MASK); ++ writel_relaxed(~0, dcc->irq_base + IRQ_FLAG); ++ ++ dcc->domain = irq_domain_add_linear(dev->of_node, DOCKCHANNEL_MAX_IRQ, ++ &dockchannel_irq_domain_ops, dcc); ++ if (!dcc->domain) ++ return -ENOMEM; ++ ++ dcc->irq = platform_get_irq(pdev, 0); ++ if (dcc->irq <= 0) ++ return dev_err_probe(dev, dcc->irq, "Failed to get IRQ"); ++ ++ irq_set_handler_data(dcc->irq, dcc); ++ irq_set_chained_handler(dcc->irq, dockchannel_irq); ++ ++ for_each_child_of_node(dev->of_node, child) ++ of_platform_device_create(child, NULL, dev); ++ ++ return 0; ++} ++ ++static void dockchannel_remove(struct platform_device *pdev) ++{ ++ struct dockchannel_common *dcc = platform_get_drvdata(pdev); ++ int hwirq; ++ ++ device_for_each_child(&pdev->dev, NULL, of_platform_device_destroy); ++ ++ irq_set_chained_handler_and_data(dcc->irq, NULL, NULL); ++ ++ for (hwirq = 0; hwirq < DOCKCHANNEL_MAX_IRQ; hwirq++) ++ irq_dispose_mapping(irq_find_mapping(dcc->domain, hwirq)); ++ ++ irq_domain_remove(dcc->domain); ++ ++ writel_relaxed(0, dcc->irq_base + IRQ_MASK); ++ writel_relaxed(~0, dcc->irq_base + IRQ_FLAG); ++} ++ ++static const struct of_device_id dockchannel_of_match[] = { ++ { .compatible = "apple,dockchannel" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dockchannel_of_match); ++ ++static struct platform_driver dockchannel_driver = { ++ .driver = { ++ .name = "dockchannel", ++ .of_match_table = dockchannel_of_match, ++ }, ++ .probe = dockchannel_probe, ++ .remove = dockchannel_remove, ++}; ++module_platform_driver(dockchannel_driver); ++ ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_DESCRIPTION("Apple DockChannel driver"); +diff --git a/include/linux/soc/apple/dockchannel.h b/include/linux/soc/apple/dockchannel.h +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/include/linux/soc/apple/dockchannel.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ ++/* ++ * Apple Dockchannel devices ++ * Copyright (C) The Asahi Linux Contributors ++ */ ++#ifndef _LINUX_APPLE_DOCKCHANNEL_H_ ++#define _LINUX_APPLE_DOCKCHANNEL_H_ ++ ++#include ++#include ++#include ++ ++#if IS_ENABLED(CONFIG_APPLE_DOCKCHANNEL) ++ ++struct dockchannel; ++ ++struct dockchannel *dockchannel_init(struct platform_device *pdev); ++ ++int dockchannel_send(struct dockchannel *dockchannel, const void *buf, size_t count); ++int dockchannel_recv(struct dockchannel *dockchannel, void *buf, size_t count); ++int dockchannel_await(struct dockchannel *dockchannel, ++ void (*callback)(void *cookie, size_t avail), ++ void *cookie, size_t count); ++ ++#endif ++#endif +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Fri, 8 Jul 2022 02:11:21 +0900 +Subject: HID: Add Apple DockChannel HID transport driver + +Apple M2 devices have an MTP coprocessor embedded in the SoC that +handles HID for the integrated touchpad/keyboard, and communicates +over the DockChannel interface. This driver implements this new +interface. + +Signed-off-by: Hector Martin +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 4 + + drivers/hid/dockchannel-hid/Kconfig | 14 + + drivers/hid/dockchannel-hid/Makefile | 6 + + drivers/hid/dockchannel-hid/dockchannel-hid.c | 1213 ++++++++++ + 5 files changed, 1239 insertions(+) + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1449,4 +1449,6 @@ source "drivers/hid/usbhid/Kconfig" + + source "drivers/hid/spi-hid/Kconfig" + ++source "drivers/hid/dockchannel-hid/Kconfig" ++ + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -173,8 +173,12 @@ obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-hid/ + + obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ ++ + obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ + ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ ++ + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + + obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/ +diff --git a/drivers/hid/dockchannel-hid/Kconfig b/drivers/hid/dockchannel-hid/Kconfig +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/Kconfig +@@ -0,0 +1,14 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++menu "DockChannel HID support" ++ depends on APPLE_DOCKCHANNEL ++ ++config HID_DOCKCHANNEL ++ tristate "HID over DockChannel transport layer for Apple Silicon SoCs" ++ default ARCH_APPLE ++ depends on APPLE_DOCKCHANNEL && INPUT && OF && HID ++ help ++ Say Y here if you use an M2 or later Apple Silicon based laptop. ++ The keyboard and touchpad are HID based devices connected via the ++ proprietary DockChannel interface. ++ ++endmenu +diff --git a/drivers/hid/dockchannel-hid/Makefile b/drivers/hid/dockchannel-hid/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/Makefile +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++# ++# Makefile for DockChannel HID transport drivers ++# ++ ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid.o +diff --git a/drivers/hid/dockchannel-hid/dockchannel-hid.c b/drivers/hid/dockchannel-hid/dockchannel-hid.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/hid/dockchannel-hid/dockchannel-hid.c +@@ -0,0 +1,1213 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0 OR MIT ++ * ++ * Apple DockChannel HID transport driver ++ * ++ * Copyright The Asahi Linux Contributors ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../hid-ids.h" ++ ++#define COMMAND_TIMEOUT_MS 1000 ++#define START_TIMEOUT_MS 2000 ++ ++#define MAX_INTERFACES 16 ++ ++/* Data + checksum */ ++#define MAX_PKT_SIZE (0xffff + 4) ++ ++#define DCHID_CHANNEL_CMD 0x11 ++#define DCHID_CHANNEL_REPORT 0x12 ++ ++struct dchid_hdr { ++ u8 hdr_len; ++ u8 channel; ++ u16 length; ++ u8 seq; ++ u8 iface; ++ u16 pad; ++} __packed; ++ ++#define IFACE_COMM 0 ++ ++#define FLAGS_GROUP GENMASK(7, 6) ++#define FLAGS_REQ GENMASK(5, 0) ++ ++#define REQ_SET_REPORT 0 ++#define REQ_GET_REPORT 1 ++ ++struct dchid_subhdr { ++ u8 flags; ++ u8 unk; ++ u16 length; ++ u32 retcode; ++} __packed; ++ ++#define EVENT_GPIO_CMD 0xa0 ++#define EVENT_INIT 0xf0 ++#define EVENT_READY 0xf1 ++ ++struct dchid_init_hdr { ++ u8 type; ++ u8 unk1; ++ u8 unk2; ++ u8 iface; ++ char name[16]; ++ u8 more_packets; ++ u8 unkpad; ++} __packed; ++ ++#define INIT_HID_DESCRIPTOR 0 ++#define INIT_GPIO_REQUEST 1 ++#define INIT_TERMINATOR 2 ++#define INIT_PRODUCT_NAME 7 ++ ++#define CMD_RESET_INTERFACE 0x40 ++#define CMD_SEND_FIRMWARE 0x95 ++#define CMD_ENABLE_INTERFACE 0xb4 ++#define CMD_ACK_GPIO_CMD 0xa1 ++ ++struct dchid_init_block_hdr { ++ u16 type; ++ u16 length; ++} __packed; ++ ++#define MAX_GPIO_NAME 32 ++ ++struct dchid_gpio_request { ++ u16 unk; ++ u16 id; ++ char name[MAX_GPIO_NAME]; ++} __packed; ++ ++struct dchid_gpio_cmd { ++ u8 type; ++ u8 iface; ++ u8 gpio; ++ u8 unk; ++ u8 cmd; ++} __packed; ++ ++struct dchid_gpio_ack { ++ u8 type; ++ u32 retcode; ++ u8 cmd[]; ++} __packed; ++ ++#define STM_REPORT_ID 0x10 ++#define STM_REPORT_SERIAL 0x11 ++#define STM_REPORT_KEYBTYPE 0x14 ++ ++struct dchid_stm_id { ++ u8 unk; ++ u16 vendor_id; ++ u16 product_id; ++ u16 version_number; ++ u8 unk2; ++ u8 unk3; ++ u8 keyboard_type; ++ u8 serial_length; ++ /* Serial follows, but we grab it with a different report. */ ++} __packed; ++ ++#define FW_MAGIC 0x46444948 ++#define FW_VER 1 ++ ++struct fw_header { ++ u32 magic; ++ u32 version; ++ u32 hdr_length; ++ u32 data_length; ++ u32 iface_offset; ++} __packed; ++ ++struct dchid_work { ++ struct work_struct work; ++ struct dchid_iface *iface; ++ ++ struct dchid_hdr hdr; ++ u8 data[]; ++}; ++ ++struct dchid_iface { ++ struct dockchannel_hid *dchid; ++ struct hid_device *hid; ++ struct workqueue_struct *wq; ++ ++ bool creating; ++ struct work_struct create_work; ++ ++ int index; ++ const char *name; ++ const struct device_node *of_node; ++ ++ uint8_t tx_seq; ++ bool deferred; ++ bool starting; ++ bool open; ++ struct completion ready; ++ ++ void *hid_desc; ++ size_t hid_desc_len; ++ ++ struct gpio_desc *gpio; ++ char gpio_name[MAX_GPIO_NAME]; ++ int gpio_id; ++ ++ struct mutex out_mutex; ++ u32 out_flags; ++ int out_report; ++ u32 retcode; ++ void *resp_buf; ++ size_t resp_size; ++ struct completion out_complete; ++ ++ u32 keyboard_layout_id; ++}; ++ ++struct dockchannel_hid { ++ struct device *dev; ++ struct dockchannel *dc; ++ struct device_link *helper_link; ++ ++ bool id_ready; ++ struct dchid_stm_id device_id; ++ char serial[64]; ++ ++ struct dchid_iface *comm; ++ struct dchid_iface *ifaces[MAX_INTERFACES]; ++ ++ u8 pkt_buf[MAX_PKT_SIZE]; ++ ++ /* Workqueue to asynchronously create HID devices */ ++ struct workqueue_struct *new_iface_wq; ++}; ++ ++static ssize_t apple_layout_id_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct hid_device *hdev = to_hid_device(dev); ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ return scnprintf(buf, PAGE_SIZE, "%d\n", iface->keyboard_layout_id); ++} ++ ++static DEVICE_ATTR_RO(apple_layout_id); ++ ++static struct dchid_iface * ++dchid_get_interface(struct dockchannel_hid *dchid, int index, const char *name) ++{ ++ struct dchid_iface *iface; ++ ++ if (index >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Interface index %d out of range\n", index); ++ return NULL; ++ } ++ ++ if (dchid->ifaces[index]) ++ return dchid->ifaces[index]; ++ ++ iface = devm_kzalloc(dchid->dev, sizeof(struct dchid_iface), GFP_KERNEL); ++ if (!iface) ++ return NULL; ++ ++ iface->index = index; ++ iface->name = devm_kstrdup(dchid->dev, name, GFP_KERNEL); ++ iface->dchid = dchid; ++ iface->out_report= -1; ++ init_completion(&iface->out_complete); ++ init_completion(&iface->ready); ++ mutex_init(&iface->out_mutex); ++ iface->wq = alloc_ordered_workqueue("dchid-%s", WQ_MEM_RECLAIM, iface->name); ++ if (!iface->wq) ++ return NULL; ++ ++ /* Comm is not a HID subdevice */ ++ if (!strcmp(name, "comm")) { ++ dchid->ifaces[index] = iface; ++ return iface; ++ } ++ ++ iface->of_node = of_get_child_by_name(dchid->dev->of_node, name); ++ if (!iface->of_node) { ++ dev_warn(dchid->dev, "No OF node for subdevice %s, ignoring.", name); ++ return NULL; ++ } ++ ++ dchid->ifaces[index] = iface; ++ return iface; ++} ++ ++static u32 dchid_checksum(void *p, size_t length) ++{ ++ u32 sum = 0; ++ ++ while (length >= 4) { ++ sum += get_unaligned_le32(p); ++ p += 4; ++ length -= 4; ++ } ++ ++ WARN_ON_ONCE(length); ++ return sum; ++} ++ ++static int dchid_send(struct dchid_iface *iface, u32 flags, void *msg, size_t size) ++{ ++ u32 checksum = 0xffffffff; ++ size_t wsize = round_down(size, 4); ++ size_t tsize = size - wsize; ++ int ret; ++ struct { ++ struct dchid_hdr hdr; ++ struct dchid_subhdr sub; ++ } __packed h; ++ ++ memset(&h, 0, sizeof(h)); ++ h.hdr.hdr_len = sizeof(h.hdr); ++ h.hdr.channel = DCHID_CHANNEL_CMD; ++ h.hdr.length = round_up(size, 4) + sizeof(h.sub); ++ h.hdr.seq = iface->tx_seq; ++ h.hdr.iface = iface->index; ++ h.sub.flags = flags; ++ h.sub.length = size; ++ ++ ret = dockchannel_send(iface->dchid->dc, &h, sizeof(h)); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(&h, sizeof(h)); ++ ++ ret = dockchannel_send(iface->dchid->dc, msg, wsize); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(msg, wsize); ++ ++ if (tsize) { ++ u8 tail[4] = {0, 0, 0, 0}; ++ ++ memcpy(tail, msg + wsize, tsize); ++ ret = dockchannel_send(iface->dchid->dc, tail, sizeof(tail)); ++ if (ret < 0) ++ return ret; ++ checksum -= dchid_checksum(tail, sizeof(tail)); ++ } ++ ++ ret = dockchannel_send(iface->dchid->dc, &checksum, sizeof(checksum)); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int dchid_cmd(struct dchid_iface *iface, u32 type, u32 req, ++ void *data, size_t size, void *resp_buf, size_t resp_size) ++{ ++ int ret; ++ int report_id = *(u8*)data; ++ ++ mutex_lock(&iface->out_mutex); ++ ++ WARN_ON(iface->out_report != -1); ++ iface->out_report = report_id; ++ iface->out_flags = FIELD_PREP(FLAGS_GROUP, type) | FIELD_PREP(FLAGS_REQ, req); ++ iface->resp_buf = resp_buf; ++ iface->resp_size = resp_size; ++ reinit_completion(&iface->out_complete); ++ ++ ret = dchid_send(iface, iface->out_flags, data, size); ++ if (ret < 0) ++ goto done; ++ ++ if (!wait_for_completion_timeout(&iface->out_complete, msecs_to_jiffies(COMMAND_TIMEOUT_MS))) { ++ dev_err(iface->dchid->dev, "output report 0x%x to iface %d (%s) timed out\n", ++ report_id, iface->index, iface->name); ++ ret = -ETIMEDOUT; ++ goto done; ++ } ++ ++ ret = iface->resp_size; ++ if (iface->retcode) { ++ dev_err(iface->dchid->dev, ++ "output report 0x%x to iface %d (%s) failed with err 0x%x\n", ++ report_id, iface->index, iface->name, iface->retcode); ++ ret = -EIO; ++ } ++ ++done: ++ iface->tx_seq++; ++ iface->out_report = -1; ++ iface->out_flags = 0; ++ iface->resp_buf = NULL; ++ iface->resp_size = 0; ++ mutex_unlock(&iface->out_mutex); ++ return ret; ++} ++ ++static int dchid_comm_cmd(struct dockchannel_hid *dchid, void *cmd, size_t size) ++{ ++ return dchid_cmd(dchid->comm, HID_FEATURE_REPORT, REQ_SET_REPORT, cmd, size, NULL, 0); ++} ++ ++static int dchid_enable_interface(struct dchid_iface *iface) ++{ ++ u8 msg[] = { CMD_ENABLE_INTERFACE, iface->index }; ++ ++ return dchid_comm_cmd(iface->dchid, msg, sizeof(msg)); ++} ++ ++static int dchid_reset_interface(struct dchid_iface *iface, int state) ++{ ++ u8 msg[] = { CMD_RESET_INTERFACE, 1, iface->index, state }; ++ ++ return dchid_comm_cmd(iface->dchid, msg, sizeof(msg)); ++} ++ ++static int dchid_send_firmware(struct dchid_iface *iface, void *firmware, size_t size) ++{ ++ struct { ++ u8 cmd; ++ u8 unk1; ++ u8 unk2; ++ u8 iface; ++ u64 addr; ++ u32 size; ++ } __packed msg = { ++ .cmd = CMD_SEND_FIRMWARE, ++ .unk1 = 2, ++ .unk2 = 0, ++ .iface = iface->index, ++ .size = size, ++ }; ++ dma_addr_t addr; ++ void *buf = dmam_alloc_coherent(iface->dchid->dev, size, &addr, GFP_KERNEL); ++ ++ if (IS_ERR_OR_NULL(buf)) ++ return buf ? PTR_ERR(buf) : -ENOMEM; ++ ++ msg.addr = addr; ++ memcpy(buf, firmware, size); ++ wmb(); ++ ++ return dchid_comm_cmd(iface->dchid, &msg, sizeof(msg)); ++} ++ ++static int dchid_get_firmware(struct dchid_iface *iface, void **firmware, size_t *size) ++{ ++ int ret; ++ const char *fw_name; ++ const struct firmware *fw; ++ struct fw_header *hdr; ++ u8 *fw_data; ++ ++ ret = of_property_read_string(iface->of_node, "firmware-name", &fw_name); ++ if (ret) { ++ /* Firmware is only for some devices */ ++ *firmware = NULL; ++ *size = 0; ++ return 0; ++ } ++ ++ ret = request_firmware(&fw, fw_name, iface->dchid->dev); ++ if (ret) ++ return ret; ++ ++ hdr = (struct fw_header *)fw->data; ++ ++ if (hdr->magic != FW_MAGIC || hdr->version != FW_VER || ++ hdr->hdr_length < sizeof(*hdr) || hdr->hdr_length > fw->size || ++ (hdr->hdr_length + (size_t)hdr->data_length) > fw->size || ++ hdr->iface_offset >= hdr->data_length) { ++ dev_warn(iface->dchid->dev, "%s: invalid firmware header\n", ++ fw_name); ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ fw_data = devm_kmemdup(iface->dchid->dev, fw->data + hdr->hdr_length, ++ hdr->data_length, GFP_KERNEL); ++ if (!fw_data) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ if (hdr->iface_offset) ++ fw_data[hdr->iface_offset] = iface->index; ++ ++ *firmware = fw_data; ++ *size = hdr->data_length; ++ ++done: ++ release_firmware(fw); ++ return ret; ++} ++ ++static int dchid_request_gpio(struct dchid_iface *iface) ++{ ++ char prop_name[MAX_GPIO_NAME + 16]; ++ ++ if (iface->gpio) ++ return 0; ++ ++ dev_info(iface->dchid->dev, "Requesting GPIO %s#%d: %s\n", ++ iface->name, iface->gpio_id, iface->gpio_name); ++ ++ snprintf(prop_name, sizeof(prop_name), "apple,%s", iface->gpio_name); ++ ++ iface->gpio = devm_gpiod_get_index(iface->dchid->dev, prop_name, 0, GPIOD_OUT_LOW); ++ ++ if (IS_ERR_OR_NULL(iface->gpio)) { ++ dev_err(iface->dchid->dev, "Failed to request GPIO %s-gpios\n", prop_name); ++ iface->gpio = NULL; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int dchid_start_interface(struct dchid_iface *iface) ++{ ++ void *fw; ++ size_t size; ++ int ret; ++ ++ if (iface->starting) { ++ dev_warn(iface->dchid->dev, "Interface %s is already starting", iface->name); ++ return -EINPROGRESS; ++ } ++ ++ dev_info(iface->dchid->dev, "Starting interface %s\n", iface->name); ++ ++ iface->starting = true; ++ ++ /* Look to see if we need firmware */ ++ ret = dchid_get_firmware(iface, &fw, &size); ++ if (ret < 0) ++ goto err; ++ ++ /* If we need a GPIO, make sure we have it. */ ++ if (iface->gpio_id) { ++ ret = dchid_request_gpio(iface); ++ if (ret < 0) ++ goto err; ++ } ++ ++ /* Only multi-touch has firmware */ ++ if (fw && size) { ++ ++ /* Send firmware to the device */ ++ dev_info(iface->dchid->dev, "Sending firmware for %s\n", iface->name); ++ ret = dchid_send_firmware(iface, fw, size); ++ if (ret < 0) { ++ dev_err(iface->dchid->dev, "Failed to send %s firmwareS", iface->name); ++ goto err; ++ } ++ ++ /* After loading firmware, multi-touch needs a reset */ ++ dev_info(iface->dchid->dev, "Resetting %s\n", iface->name); ++ dchid_reset_interface(iface, 0); ++ dchid_reset_interface(iface, 2); ++ } ++ ++ return 0; ++ ++err: ++ iface->starting = false; ++ return ret; ++} ++ ++static int dchid_start(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ if (iface->keyboard_layout_id) { ++ int ret = device_create_file(&hdev->dev, &dev_attr_apple_layout_id); ++ if (ret) { ++ dev_warn(iface->dchid->dev, "Failed to create apple_layout_id: %d", ret); ++ iface->keyboard_layout_id = 0; ++ } ++ } ++ ++ return 0; ++}; ++ ++static void dchid_stop(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ if (iface->keyboard_layout_id) ++ device_remove_file(&hdev->dev, &dev_attr_apple_layout_id); ++} ++ ++static int dchid_open(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ int ret; ++ ++ if (!completion_done(&iface->ready)) { ++ ret = dchid_start_interface(iface); ++ if (ret < 0) ++ return ret; ++ ++ if (!wait_for_completion_timeout(&iface->ready, msecs_to_jiffies(START_TIMEOUT_MS))) { ++ dev_err(iface->dchid->dev, "iface %s start timed out\n", iface->name); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ iface->open = true; ++ return 0; ++} ++ ++static void dchid_close(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ iface->open = false; ++} ++ ++static int dchid_parse(struct hid_device *hdev) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ return hid_parse_report(hdev, iface->hid_desc, iface->hid_desc_len); ++} ++ ++/* Note: buf excludes report number! For ease of fetching strings/etc. */ ++static int dchid_get_report_cmd(struct dchid_iface *iface, u8 reportnum, void *buf, size_t len) ++{ ++ int ret = dchid_cmd(iface, HID_FEATURE_REPORT, REQ_GET_REPORT, &reportnum, 1, buf, len); ++ ++ return ret <= 0 ? ret : ret - 1; ++} ++ ++/* Note: buf includes report number! */ ++static int dchid_set_report(struct dchid_iface *iface, void *buf, size_t len) ++{ ++ return dchid_cmd(iface, HID_OUTPUT_REPORT, REQ_SET_REPORT, buf, len, NULL, 0); ++} ++ ++static int dchid_raw_request(struct hid_device *hdev, ++ unsigned char reportnum, __u8 *buf, size_t len, ++ unsigned char rtype, int reqtype) ++{ ++ struct dchid_iface *iface = hdev->driver_data; ++ ++ switch (reqtype) { ++ case HID_REQ_GET_REPORT: ++ buf[0] = reportnum; ++ return dchid_cmd(iface, rtype, REQ_GET_REPORT, &reportnum, 1, buf + 1, len - 1); ++ case HID_REQ_SET_REPORT: ++ return dchid_set_report(iface, buf, len); ++ default: ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static struct hid_ll_driver dchid_ll = { ++ .start = &dchid_start, ++ .stop = &dchid_stop, ++ .open = &dchid_open, ++ .close = &dchid_close, ++ .parse = &dchid_parse, ++ .raw_request = &dchid_raw_request, ++}; ++ ++static void dchid_create_interface_work(struct work_struct *ws) ++{ ++ struct dchid_iface *iface = container_of(ws, struct dchid_iface, create_work); ++ struct dockchannel_hid *dchid = iface->dchid; ++ struct hid_device *hid; ++ int ret; ++ ++ if (iface->hid) { ++ dev_warn(dchid->dev, "Interface %s already created!\n", ++ iface->name); ++ return; ++ } ++ ++ dev_info(dchid->dev, "New interface %s\n", iface->name); ++ ++ /* Start the interface. This is not the entire init process, as firmware is loaded later on device open. */ ++ ret = dchid_enable_interface(iface); ++ if (ret < 0) { ++ dev_warn(dchid->dev, "Failed to enable %s: %d\n", iface->name, ret); ++ return; ++ } ++ ++ iface->deferred = false; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return; ++ ++ snprintf(hid->name, sizeof(hid->name), "Apple MTP %s", iface->name); ++ snprintf(hid->phys, sizeof(hid->phys), "%s.%d (%s)", ++ dev_name(dchid->dev), iface->index, iface->name); ++ strscpy(hid->uniq, dchid->serial, sizeof(hid->uniq)); ++ ++ hid->ll_driver = &dchid_ll; ++ hid->bus = BUS_HOST; ++ hid->vendor = dchid->device_id.vendor_id; ++ hid->product = dchid->device_id.product_id; ++ hid->version = dchid->device_id.version_number; ++ hid->type = HID_TYPE_OTHER; ++ if (!strcmp(iface->name, "multi-touch")) { ++ hid->type = HID_TYPE_SPI_MOUSE; ++ } else if (!strcmp(iface->name, "keyboard")) { ++ u32 country_code = 0; ++ ++ hid->type = HID_TYPE_SPI_KEYBOARD; ++ ++ /* ++ * We have to get the country code from the device tree, since the ++ * device provides no reliable way to get this info. ++ */ ++ if (!of_property_read_u32(iface->of_node, "hid-country-code", &country_code)) ++ hid->country = country_code; ++ ++ of_property_read_u32(iface->of_node, "apple,keyboard-layout-id", ++ &iface->keyboard_layout_id); ++ } ++ ++ hid->dev.parent = iface->dchid->dev; ++ hid->driver_data = iface; ++ ++ iface->hid = hid; ++ ++ ret = hid_add_device(hid); ++ if (ret < 0) { ++ iface->hid = NULL; ++ hid_destroy_device(hid); ++ dev_warn(iface->dchid->dev, "Failed to register hid device %s", iface->name); ++ } ++} ++ ++static int dchid_create_interface(struct dchid_iface *iface) ++{ ++ if (iface->creating) ++ return -EBUSY; ++ ++ iface->creating = true; ++ INIT_WORK(&iface->create_work, dchid_create_interface_work); ++ return queue_work(iface->dchid->new_iface_wq, &iface->create_work); ++} ++ ++static void dchid_handle_descriptor(struct dchid_iface *iface, void *hid_desc, size_t desc_len) ++{ ++ if (iface->hid) { ++ dev_warn(iface->dchid->dev, "Tried to initialize already started interface %s!\n", ++ iface->name); ++ return; ++ } ++ ++ iface->hid_desc = devm_kmemdup(iface->dchid->dev, hid_desc, desc_len, GFP_KERNEL); ++ if (!iface->hid_desc) ++ return; ++ ++ iface->hid_desc_len = desc_len; ++} ++ ++static void dchid_handle_ready(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_iface *iface; ++ u8 *pkt = data; ++ u8 index; ++ int i, ret; ++ ++ if (length < 2) { ++ dev_err(dchid->dev, "Bad length for ready message: %zu\n", length); ++ return; ++ } ++ ++ index = pkt[1]; ++ ++ if (index >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Got ready notification for bad iface %d\n", index); ++ return; ++ } ++ ++ iface = dchid->ifaces[index]; ++ if (!iface) { ++ dev_err(dchid->dev, "Got ready notification for unknown iface %d\n", index); ++ return; ++ } ++ ++ dev_info(dchid->dev, "Interface %s is now ready\n", iface->name); ++ complete_all(&iface->ready); ++ ++ /* When STM is ready, grab global device info */ ++ if (!strcmp(iface->name, "stm")) { ++ ret = dchid_get_report_cmd(iface, STM_REPORT_ID, &dchid->device_id, ++ sizeof(dchid->device_id)); ++ if (ret < sizeof(dchid->device_id)) { ++ dev_warn(iface->dchid->dev, "Failed to get device ID from STM!\n"); ++ /* Fake it and keep going. Things might still work... */ ++ memset(&dchid->device_id, 0, sizeof(dchid->device_id)); ++ dchid->device_id.vendor_id = HOST_VENDOR_ID_APPLE; ++ } ++ ret = dchid_get_report_cmd(iface, STM_REPORT_SERIAL, dchid->serial, ++ sizeof(dchid->serial) - 1); ++ if (ret < 0) { ++ dev_warn(iface->dchid->dev, "Failed to get serial from STM!\n"); ++ dchid->serial[0] = 0; ++ } ++ ++ dchid->id_ready = true; ++ for (i = 0; i < MAX_INTERFACES; i++) { ++ if (!dchid->ifaces[i] || !dchid->ifaces[i]->deferred) ++ continue; ++ dchid_create_interface(dchid->ifaces[i]); ++ } ++ } ++} ++ ++static void dchid_handle_init(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_init_hdr *hdr = data; ++ struct dchid_iface *iface; ++ struct dchid_init_block_hdr *blk; ++ ++ if (length < sizeof(*hdr)) ++ return; ++ ++ iface = dchid_get_interface(dchid, hdr->iface, hdr->name); ++ if (!iface) ++ return; ++ ++ data += sizeof(*hdr); ++ length -= sizeof(*hdr); ++ ++ while (length >= sizeof(*blk)) { ++ blk = data; ++ data += sizeof(*blk); ++ length -= sizeof(*blk); ++ ++ if (blk->length > length) ++ break; ++ ++ switch (blk->type) { ++ case INIT_HID_DESCRIPTOR: ++ dchid_handle_descriptor(iface, data, blk->length); ++ break; ++ ++ case INIT_GPIO_REQUEST: { ++ struct dchid_gpio_request *req = data; ++ ++ if (sizeof(*req) > length) ++ break; ++ ++ if (iface->gpio_id) { ++ dev_err(dchid->dev, ++ "Cannot request more than one GPIO per interface!\n"); ++ break; ++ } ++ ++ strscpy(iface->gpio_name, req->name, MAX_GPIO_NAME); ++ iface->gpio_id = req->id; ++ break; ++ } ++ ++ case INIT_TERMINATOR: ++ break; ++ ++ case INIT_PRODUCT_NAME: { ++ char *product = data; ++ ++ if (product[blk->length - 1] != 0) { ++ dev_warn(dchid->dev, "Unterminated product name for %s\n", ++ iface->name); ++ } else { ++ dev_info(dchid->dev, "Product name for %s: %s\n", ++ iface->name, product); ++ } ++ break; ++ } ++ ++ default: ++ dev_warn(dchid->dev, "Unknown init packet %d for %s\n", ++ blk->type, iface->name); ++ break; ++ } ++ ++ data += blk->length; ++ length -= blk->length; ++ ++ if (blk->type == INIT_TERMINATOR) ++ break; ++ } ++ ++ if (hdr->more_packets) ++ return; ++ ++ /* We need to enable STM first, since it'll give us the device IDs */ ++ if (iface->dchid->id_ready || !strcmp(iface->name, "stm")) { ++ dchid_create_interface(iface); ++ } else { ++ iface->deferred = true; ++ } ++} ++ ++static void dchid_handle_gpio(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ struct dchid_gpio_cmd *cmd = data; ++ struct dchid_iface *iface; ++ u32 retcode = 0xe000f00d; /* Give it a random Apple-style error code */ ++ struct dchid_gpio_ack *ack; ++ ++ if (length < sizeof(*cmd)) ++ return; ++ ++ if (cmd->iface >= MAX_INTERFACES || !(iface = dchid->ifaces[cmd->iface])) { ++ dev_err(dchid->dev, "Got GPIO command for bad inteface %d\n", cmd->iface); ++ goto err; ++ } ++ ++ if (dchid_request_gpio(iface) < 0) ++ goto err; ++ ++ if (!iface->gpio || cmd->gpio != iface->gpio_id) { ++ dev_err(dchid->dev, "Got GPIO command for bad GPIO %s#%d\n", ++ iface->name, cmd->gpio); ++ goto err; ++ } ++ ++ dev_info(dchid->dev, "GPIO command: %s#%d: %d\n", iface->name, cmd->gpio, cmd->cmd); ++ ++ switch (cmd->cmd) { ++ case 3: ++ /* Pulse. */ ++ gpiod_set_value_cansleep(iface->gpio, 1); ++ msleep(10); /* Random guess... */ ++ gpiod_set_value_cansleep(iface->gpio, 0); ++ retcode = 0; ++ break; ++ default: ++ dev_err(dchid->dev, "Unknown GPIO command %d\n", cmd->cmd ); ++ break; ++ } ++ ++err: ++ /* Ack it */ ++ ack = kzalloc(sizeof(*ack) + length, GFP_KERNEL); ++ if (!ack) ++ return; ++ ++ ack->type = CMD_ACK_GPIO_CMD; ++ ack->retcode = retcode; ++ memcpy(ack->cmd, data, length); ++ ++ if (dchid_comm_cmd(dchid, ack, sizeof(*ack) + length) < 0) ++ dev_err(dchid->dev, "Failed to ACK GPIO command\n"); ++ ++ kfree(ack); ++} ++ ++static void dchid_handle_event(struct dockchannel_hid *dchid, void *data, size_t length) ++{ ++ u8 *p = data; ++ switch (*p) { ++ case EVENT_INIT: ++ dchid_handle_init(dchid, data, length); ++ break; ++ case EVENT_READY: ++ dchid_handle_ready(dchid, data, length); ++ break; ++ case EVENT_GPIO_CMD: ++ dchid_handle_gpio(dchid, data, length); ++ break; ++ } ++} ++ ++static void dchid_handle_report(struct dchid_iface *iface, void *data, size_t length) ++{ ++ struct dockchannel_hid *dchid = iface->dchid; ++ ++ if (!iface->hid) { ++ dev_warn(dchid->dev, "Report received but %s is not initialized!\n", iface->name); ++ return; ++ } ++ ++ if (!iface->open) ++ return; ++ ++ hid_input_report(iface->hid, HID_INPUT_REPORT, data, length, 1); ++} ++ ++static void dchid_packet_work(struct work_struct *ws) ++{ ++ struct dchid_work *work = container_of(ws, struct dchid_work, work); ++ struct dchid_subhdr *shdr = (void *)work->data; ++ struct dockchannel_hid *dchid = work->iface->dchid; ++ int type = FIELD_GET(FLAGS_GROUP, shdr->flags); ++ u8 *payload = work->data + sizeof(*shdr); ++ ++ if (shdr->length + sizeof(*shdr) > work->hdr.length) { ++ dev_err(dchid->dev, "Bad sub header length (%d > %zu)\n", ++ shdr->length, work->hdr.length - sizeof(*shdr)); ++ return; ++ } ++ ++ switch (type) { ++ case HID_INPUT_REPORT: ++ if (work->hdr.iface == IFACE_COMM) ++ dchid_handle_event(dchid, payload, shdr->length); ++ else ++ dchid_handle_report(work->iface, payload, shdr->length); ++ break; ++ default: ++ dev_err(dchid->dev, "Received unknown packet type %d\n", type); ++ break; ++ } ++ ++ kfree(work); ++} ++ ++static void dchid_handle_ack(struct dchid_iface *iface, struct dchid_hdr *hdr, void *data) ++{ ++ struct dchid_subhdr *shdr = (void *)data; ++ u8 *payload = data + sizeof(*shdr); ++ ++ if (shdr->length + sizeof(*shdr) > hdr->length) { ++ dev_err(iface->dchid->dev, "Bad sub header length (%d > %ld)\n", ++ shdr->length, hdr->length - sizeof(*shdr)); ++ return; ++ } ++ if (shdr->flags != iface->out_flags) { ++ dev_err(iface->dchid->dev, ++ "Received unexpected flags 0x%x on ACK channel (expFected 0x%x)\n", ++ shdr->flags, iface->out_flags); ++ return; ++ } ++ ++ if (shdr->length < 1) { ++ dev_err(iface->dchid->dev, "Received length 0 output report ack\n"); ++ return; ++ } ++ if (iface->tx_seq != hdr->seq) { ++ dev_err(iface->dchid->dev, "Received ACK with bad seq (expected %d, got %d)\n", ++ iface->tx_seq, hdr->seq); ++ return; ++ } ++ if (iface->out_report != payload[0]) { ++ dev_err(iface->dchid->dev, "Received ACK with bad report (expected %d, got %d\n", ++ iface->out_report, payload[0]); ++ return; ++ } ++ ++ if (iface->resp_buf && iface->resp_size) ++ memcpy(iface->resp_buf, payload + 1, min((size_t)shdr->length - 1, iface->resp_size)); ++ ++ iface->resp_size = shdr->length; ++ iface->out_report = -1; ++ iface->retcode = shdr->retcode; ++ complete(&iface->out_complete); ++} ++ ++static void dchid_handle_packet(void *cookie, size_t avail) ++{ ++ struct dockchannel_hid *dchid = cookie; ++ struct dchid_hdr hdr; ++ struct dchid_work *work; ++ struct dchid_iface *iface; ++ u32 checksum; ++ ++ if (dockchannel_recv(dchid->dc, &hdr, sizeof(hdr)) != sizeof(hdr)) { ++ dev_err(dchid->dev, "Read failed (header)\n"); ++ return; ++ } ++ ++ if (hdr.hdr_len != sizeof(hdr)) { ++ dev_err(dchid->dev, "Bad header length %d\n", hdr.hdr_len); ++ goto done; ++ } ++ ++ if (dockchannel_recv(dchid->dc, dchid->pkt_buf, hdr.length + 4) != (hdr.length + 4)) { ++ dev_err(dchid->dev, "Read failed (body)\n"); ++ goto done; ++ } ++ ++ checksum = dchid_checksum(&hdr, sizeof(hdr)); ++ checksum += dchid_checksum(dchid->pkt_buf, hdr.length + 4); ++ ++ if (checksum != 0xffffffff) { ++ dev_err(dchid->dev, "Checksum mismatch (iface %d): 0x%08x != 0xffffffff\n", ++ hdr.iface, checksum); ++ goto done; ++ } ++ ++ ++ if (hdr.iface >= MAX_INTERFACES) { ++ dev_err(dchid->dev, "Bad iface %d\n", hdr.iface); ++ } ++ ++ iface = dchid->ifaces[hdr.iface]; ++ ++ if (!iface) { ++ dev_err(dchid->dev, "Received packet for uninitialized iface %d\n", hdr.iface); ++ goto done; ++ } ++ ++ switch (hdr.channel) { ++ case DCHID_CHANNEL_CMD: ++ dchid_handle_ack(iface, &hdr, dchid->pkt_buf); ++ goto done; ++ case DCHID_CHANNEL_REPORT: ++ break; ++ default: ++ dev_warn(dchid->dev, "Unknown channel 0x%x, treating as report...\n", ++ hdr.channel); ++ break; ++ } ++ ++ work = kzalloc(sizeof(*work) + hdr.length, GFP_KERNEL); ++ if (!work) ++ return; ++ ++ work->hdr = hdr; ++ work->iface = iface; ++ memcpy(work->data, dchid->pkt_buf, hdr.length); ++ INIT_WORK(&work->work, dchid_packet_work); ++ ++ queue_work(iface->wq, &work->work); ++ ++done: ++ dockchannel_await(dchid->dc, dchid_handle_packet, dchid, sizeof(struct dchid_hdr)); ++} ++ ++static int dockchannel_hid_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct dockchannel_hid *dchid; ++ struct device_node *child, *helper; ++ struct platform_device *helper_pdev; ++ struct property *prop; ++ int ret; ++ ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); ++ if (ret) ++ return ret; ++ ++ dchid = devm_kzalloc(dev, sizeof(*dchid), GFP_KERNEL); ++ if (!dchid) { ++ return -ENOMEM; ++ } ++ ++ dchid->dev = dev; ++ ++ /* ++ * First make sure all the GPIOs are available, in cased we need to defer. ++ * This is necessary because MTP will request them by name later, and by then ++ * it's too late to defer the probe. ++ */ ++ ++ for_each_child_of_node(dev->of_node, child) { ++ for_each_property_of_node(child, prop) { ++ size_t len = strlen(prop->name); ++ struct gpio_desc *gpio; ++ ++ if (len < 12 || strncmp("apple,", prop->name, 6) || ++ strcmp("-gpios", prop->name + len - 6)) ++ continue; ++ ++ gpio = fwnode_gpiod_get_index(&child->fwnode, prop->name, 0, GPIOD_ASIS, ++ prop->name); ++ if (IS_ERR_OR_NULL(gpio)) { ++ if (PTR_ERR(gpio) == -EPROBE_DEFER) { ++ of_node_put(child); ++ return -EPROBE_DEFER; ++ } ++ } else { ++ gpiod_put(gpio); ++ } ++ } ++ } ++ ++ /* ++ * Make sure we also have the MTP coprocessor available, and ++ * defer probe if the helper hasn't probed yet. ++ */ ++ helper = of_parse_phandle(dev->of_node, "apple,helper-cpu", 0); ++ if (!helper) { ++ dev_err(dev, "Missing apple,helper-cpu property"); ++ return -EINVAL; ++ } ++ ++ helper_pdev = of_find_device_by_node(helper); ++ of_node_put(helper); ++ if (!helper_pdev) { ++ dev_err(dev, "Failed to find helper device"); ++ return -EINVAL; ++ } ++ ++ dchid->helper_link = device_link_add(dev, &helper_pdev->dev, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ put_device(&helper_pdev->dev); ++ if (!dchid->helper_link) { ++ dev_err(dev, "Failed to link to helper device"); ++ return -EINVAL; ++ } ++ ++ if (dchid->helper_link->supplier->links.status != DL_DEV_DRIVER_BOUND) ++ return -EPROBE_DEFER; ++ ++ /* Now it is safe to begin initializing */ ++ dchid->dc = dockchannel_init(pdev); ++ if (IS_ERR_OR_NULL(dchid->dc)) { ++ return PTR_ERR(dchid->dc); ++ } ++ dchid->new_iface_wq = alloc_workqueue("dchid-new", WQ_MEM_RECLAIM, 0); ++ if (!dchid->new_iface_wq) ++ return -ENOMEM; ++ ++ dchid->comm = dchid_get_interface(dchid, IFACE_COMM, "comm"); ++ if (!dchid->comm) { ++ dev_err(dchid->dev, "Failed to initialize comm interface"); ++ return -EIO; ++ } ++ ++ dev_info(dchid->dev, "Initialized, awaiting packets\n"); ++ dockchannel_await(dchid->dc, dchid_handle_packet, dchid, sizeof(struct dchid_hdr)); ++ ++ return 0; ++} ++ ++static void dockchannel_hid_remove(struct platform_device *pdev) ++{ ++ BUG_ON(1); ++} ++ ++static const struct of_device_id dockchannel_hid_of_match[] = { ++ { .compatible = "apple,dockchannel-hid" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dockchannel_hid_of_match); ++MODULE_FIRMWARE("apple/tpmtfw-*.bin"); ++ ++static struct platform_driver dockchannel_hid_driver = { ++ .driver = { ++ .name = "dockchannel-hid", ++ .of_match_table = dockchannel_hid_of_match, ++ }, ++ .probe = dockchannel_hid_probe, ++ .remove = dockchannel_hid_remove, ++}; ++module_platform_driver(dockchannel_hid_driver); ++ ++MODULE_DESCRIPTION("Apple DockChannel HID transport driver"); ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); +-- +Armbian + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Sun, 3 Jul 2022 23:33:37 +0900 +Subject: soc: apple: Add RTKit helper driver + +This driver can be used for coprocessors that do some background task or +communicate out-of-band, and do not do any mailbox I/O beyond the +standard RTKit initialization. + +Signed-off-by: Hector Martin +--- + drivers/soc/apple/Kconfig | 14 + + drivers/soc/apple/Makefile | 3 + + drivers/soc/apple/rtkit-helper.c | 151 ++++++++++ + 3 files changed, 168 insertions(+) + +diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Kconfig ++++ b/drivers/soc/apple/Kconfig +@@ -38,6 +38,20 @@ config APPLE_RTKIT + + Say 'y' here if you have an Apple SoC. + ++config APPLE_RTKIT_HELPER ++ tristate "Apple Generic RTKit helper co-processor" ++ depends on APPLE_RTKIT ++ depends on ARCH_APPLE || COMPILE_TEST ++ default ARCH_APPLE ++ help ++ Apple SoCs such as the M1 come with various co-processors running ++ their proprietary RTKit operating system. This option enables support ++ for a generic co-processor that does not implement any additional ++ in-band communications. It can be used for testing purposes, or for ++ coprocessors such as MTP that communicate over a different interface. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_SART + tristate "Apple SART DMA address filter" + depends on ARCH_APPLE || COMPILE_TEST +diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile +index 111111111111..222222222222 100644 +--- a/drivers/soc/apple/Makefile ++++ b/drivers/soc/apple/Makefile +@@ -9,5 +9,8 @@ apple-mailbox-y = mailbox.o + obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o + apple-rtkit-y = rtkit.o rtkit-crashlog.o + ++obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o ++apple-rtkit-helper-y = rtkit-helper.o ++ + obj-$(CONFIG_APPLE_SART) += apple-sart.o + apple-sart-y = sart.o +diff --git a/drivers/soc/apple/rtkit-helper.c b/drivers/soc/apple/rtkit-helper.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/drivers/soc/apple/rtkit-helper.c +@@ -0,0 +1,151 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Apple Generic RTKit helper coprocessor ++ * Copyright The Asahi Linux Contributors ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define APPLE_ASC_CPU_CONTROL 0x44 ++#define APPLE_ASC_CPU_CONTROL_RUN BIT(4) ++ ++struct apple_rtkit_helper { ++ struct device *dev; ++ struct apple_rtkit *rtk; ++ ++ void __iomem *asc_base; ++ ++ struct resource *sram; ++ void __iomem *sram_base; ++}; ++ ++static int apple_rtkit_helper_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr) ++{ ++ struct apple_rtkit_helper *helper = cookie; ++ struct resource res = { ++ .start = bfr->iova, ++ .end = bfr->iova + bfr->size - 1, ++ .name = "rtkit_map", ++ }; ++ ++ if (!bfr->iova) { ++ bfr->buffer = dma_alloc_coherent(helper->dev, bfr->size, ++ &bfr->iova, GFP_KERNEL); ++ if (!bfr->buffer) ++ return -ENOMEM; ++ return 0; ++ } ++ ++ if (!helper->sram) { ++ dev_err(helper->dev, ++ "RTKit buffer request with no SRAM region: %pR", &res); ++ return -EFAULT; ++ } ++ ++ res.flags = helper->sram->flags; ++ ++ if (res.end < res.start || !resource_contains(helper->sram, &res)) { ++ dev_err(helper->dev, ++ "RTKit buffer request outside SRAM region: %pR", &res); ++ return -EFAULT; ++ } ++ ++ bfr->iomem = helper->sram_base + (res.start - helper->sram->start); ++ bfr->is_mapped = true; ++ ++ return 0; ++} ++ ++static void apple_rtkit_helper_shmem_destroy(void *cookie, struct apple_rtkit_shmem *bfr) ++{ ++ // no-op ++} ++ ++static const struct apple_rtkit_ops apple_rtkit_helper_ops = { ++ .shmem_setup = apple_rtkit_helper_shmem_setup, ++ .shmem_destroy = apple_rtkit_helper_shmem_destroy, ++}; ++ ++static int apple_rtkit_helper_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct apple_rtkit_helper *helper; ++ int ret; ++ ++ /* 44 bits for addresses in standard RTKit requests */ ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); ++ if (ret) ++ return ret; ++ ++ helper = devm_kzalloc(dev, sizeof(*helper), GFP_KERNEL); ++ if (!helper) ++ return -ENOMEM; ++ ++ helper->dev = dev; ++ platform_set_drvdata(pdev, helper); ++ ++ helper->asc_base = devm_platform_ioremap_resource_byname(pdev, "asc"); ++ if (IS_ERR(helper->asc_base)) ++ return PTR_ERR(helper->asc_base); ++ ++ helper->sram = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); ++ if (helper->sram) { ++ helper->sram_base = devm_ioremap_resource(dev, helper->sram); ++ if (IS_ERR(helper->sram_base)) ++ return dev_err_probe(dev, PTR_ERR(helper->sram_base), ++ "Failed to map SRAM region"); ++ } ++ ++ helper->rtk = ++ devm_apple_rtkit_init(dev, helper, NULL, 0, &apple_rtkit_helper_ops); ++ if (IS_ERR(helper->rtk)) ++ return dev_err_probe(dev, PTR_ERR(helper->rtk), ++ "Failed to intialize RTKit"); ++ ++ writel_relaxed(APPLE_ASC_CPU_CONTROL_RUN, ++ helper->asc_base + APPLE_ASC_CPU_CONTROL); ++ ++ /* Works for both wake and boot */ ++ ret = apple_rtkit_wake(helper->rtk); ++ if (ret != 0) ++ return dev_err_probe(dev, ret, "Failed to wake up coprocessor"); ++ ++ return 0; ++} ++ ++static void apple_rtkit_helper_remove(struct platform_device *pdev) ++{ ++ struct apple_rtkit_helper *helper = platform_get_drvdata(pdev); ++ ++ if (apple_rtkit_is_running(helper->rtk)) ++ apple_rtkit_quiesce(helper->rtk); ++ ++ writel_relaxed(0, helper->asc_base + APPLE_ASC_CPU_CONTROL); ++} ++ ++static const struct of_device_id apple_rtkit_helper_of_match[] = { ++ { .compatible = "apple,rtk-helper-asc4" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, apple_rtkit_helper_of_match); ++ ++static struct platform_driver apple_rtkit_helper_driver = { ++ .driver = { ++ .name = "rtkit-helper", ++ .of_match_table = apple_rtkit_helper_of_match, ++ }, ++ .probe = apple_rtkit_helper_probe, ++ .remove = apple_rtkit_helper_remove, ++}; ++module_platform_driver(apple_rtkit_helper_driver); ++ ++MODULE_AUTHOR("Hector Martin "); ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_DESCRIPTION("Apple RTKit helper driver"); +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch b/patch/kernel/archive/uefi-x86-6.18/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch new file mode 100644 index 000000000..befd35f67 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/4003-HID-apple-ignore-the-trackpad-on-T2-Macs.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Fri, 12 Sep 2025 12:09:01 +0000 +Subject: HID: apple: ignore the trackpad on T2 Macs + +In order to manage the trackpad on T2 Macs by hid-magicmouse driver +we need to ensure that it is not bound by the hid-apple driver. Use +the existing APPLE_IGNORE_MOUSE quirk for the same. + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-apple.c | 27 ++++++---- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -30,7 +30,7 @@ + #include "hid-ids.h" + + #define APPLE_RDESC_JIS BIT(0) +-/* BIT(1) reserved, was: APPLE_IGNORE_MOUSE */ ++#define APPLE_IGNORE_MOUSE BIT(1) + #define APPLE_HAS_FN BIT(2) + /* BIT(3) reserved, was: APPLE_HIDDEV */ + #define APPLE_ISO_TILDE_QUIRK BIT(4) +@@ -951,6 +951,9 @@ static int apple_probe(struct hid_device *hdev, + hdev->type != HID_TYPE_SPI_KEYBOARD) + return -ENODEV; + ++ if (quirks & APPLE_IGNORE_MOUSE && hdev->type == HID_TYPE_USBMOUSE) ++ return -ENODEV; ++ + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); + if (asc == NULL) { + hid_err(hdev, "can't alloc apple descriptor\n"); +@@ -1173,27 +1176,31 @@ static const struct hid_device_id apple_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), +- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | +- APPLE_DISABLE_FKEYS }, ++ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | +- APPLE_DISABLE_FKEYS }, ++ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | +- APPLE_DISABLE_FKEYS }, ++ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | +- APPLE_DISABLE_FKEYS }, ++ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | ++ APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), +- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | ++ APPLE_IGNORE_MOUSE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch b/patch/kernel/archive/uefi-x86-6.18/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch new file mode 100644 index 000000000..1ce0e2d76 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/4004-HID-magicmouse-Add-support-for-trackpads-found-on-T2.patch @@ -0,0 +1,417 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Tue, 11 Mar 2025 18:44:06 +0530 +Subject: HID: magicmouse: Add support for trackpads found on T2 Macs + +This patch adds support for trackpads found on Macs with the T2 +Security Chip. The touch report format differs from other trackpads. +It is the same format as type 4 in bcm5974.c + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-magicmouse.c | 296 +++++++++- + 1 file changed, 275 insertions(+), 21 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -118,6 +118,105 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define TRACKPAD2_RES_Y \ + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) + ++#define J140K_TP_DIMENSION_X (float)12100 ++#define J140K_TP_MIN_X -5318 ++#define J140K_TP_MAX_X 5787 ++#define J140K_TP_RES_X \ ++ ((J140K_TP_MAX_X - J140K_TP_MIN_X) / (J140K_TP_DIMENSION_X / 100)) ++#define J140K_TP_DIMENSION_Y (float)8200 ++#define J140K_TP_MIN_Y -157 ++#define J140K_TP_MAX_Y 7102 ++#define J140K_TP_RES_Y \ ++ ((J140K_TP_MAX_Y - J140K_TP_MIN_Y) / (J140K_TP_DIMENSION_Y / 100)) ++ ++#define J132_TP_DIMENSION_X (float)13500 ++#define J132_TP_MIN_X -6243 ++#define J132_TP_MAX_X 6749 ++#define J132_TP_RES_X \ ++ ((J132_TP_MAX_X - J132_TP_MIN_X) / (J132_TP_DIMENSION_X / 100)) ++#define J132_TP_DIMENSION_Y (float)8400 ++#define J132_TP_MIN_Y -170 ++#define J132_TP_MAX_Y 7685 ++#define J132_TP_RES_Y \ ++ ((J132_TP_MAX_Y - J132_TP_MIN_Y) / (J132_TP_DIMENSION_Y / 100)) ++ ++#define J680_TP_DIMENSION_X (float)16000 ++#define J680_TP_MIN_X -7456 ++#define J680_TP_MAX_X 7976 ++#define J680_TP_RES_X \ ++ ((J680_TP_MAX_X - J680_TP_MIN_X) / (J680_TP_DIMENSION_X / 100)) ++#define J680_TP_DIMENSION_Y (float)10000 ++#define J680_TP_MIN_Y -163 ++#define J680_TP_MAX_Y 9283 ++#define J680_TP_RES_Y \ ++ ((J680_TP_MAX_Y - J680_TP_MIN_Y) / (J680_TP_DIMENSION_Y / 100)) ++ ++#define J680_ALT_TP_DIMENSION_X (float)16000 ++#define J680_ALT_TP_MIN_X -7456 ++#define J680_ALT_TP_MAX_X 7976 ++#define J680_ALT_TP_RES_X \ ++ ((J680_ALT_TP_MAX_X - J680_ALT_TP_MIN_X) / (J680_ALT_TP_DIMENSION_X / 100)) ++#define J680_ALT_TP_DIMENSION_Y (float)10000 ++#define J680_ALT_TP_MIN_Y -163 ++#define J680_ALT_TP_MAX_Y 9283 ++#define J680_ALT_TP_RES_Y \ ++ ((J680_ALT_TP_MAX_Y - J680_ALT_TP_MIN_Y) / (J680_ALT_TP_DIMENSION_Y / 100)) ++ ++#define J213_TP_DIMENSION_X (float)13500 ++#define J213_TP_MIN_X -6243 ++#define J213_TP_MAX_X 6749 ++#define J213_TP_RES_X \ ++ ((J213_TP_MAX_X - J213_TP_MIN_X) / (J213_TP_DIMENSION_X / 100)) ++#define J213_TP_DIMENSION_Y (float)8400 ++#define J213_TP_MIN_Y -170 ++#define J213_TP_MAX_Y 7685 ++#define J213_TP_RES_Y \ ++ ((J213_TP_MAX_Y - J213_TP_MIN_Y) / (J213_TP_DIMENSION_Y / 100)) ++ ++#define J214K_TP_DIMENSION_X (float)13200 ++#define J214K_TP_MIN_X -6046 ++#define J214K_TP_MAX_X 6536 ++#define J214K_TP_RES_X \ ++ ((J214K_TP_MAX_X - J214K_TP_MIN_X) / (J214K_TP_DIMENSION_X / 100)) ++#define J214K_TP_DIMENSION_Y (float)8200 ++#define J214K_TP_MIN_Y -164 ++#define J214K_TP_MAX_Y 7439 ++#define J214K_TP_RES_Y \ ++ ((J214K_TP_MAX_Y - J214K_TP_MIN_Y) / (J214K_TP_DIMENSION_Y / 100)) ++ ++#define J223_TP_DIMENSION_X (float)13200 ++#define J223_TP_MIN_X -6046 ++#define J223_TP_MAX_X 6536 ++#define J223_TP_RES_X \ ++ ((J223_TP_MAX_X - J223_TP_MIN_X) / (J223_TP_DIMENSION_X / 100)) ++#define J223_TP_DIMENSION_Y (float)8200 ++#define J223_TP_MIN_Y -164 ++#define J223_TP_MAX_Y 7439 ++#define J223_TP_RES_Y \ ++ ((J223_TP_MAX_Y - J223_TP_MIN_Y) / (J223_TP_DIMENSION_Y / 100)) ++ ++#define J230K_TP_DIMENSION_X (float)12100 ++#define J230K_TP_MIN_X -5318 ++#define J230K_TP_MAX_X 5787 ++#define J230K_TP_RES_X \ ++ ((J230K_TP_MAX_X - J230K_TP_MIN_X) / (J230K_TP_DIMENSION_X / 100)) ++#define J230K_TP_DIMENSION_Y (float)8200 ++#define J230K_TP_MIN_Y -157 ++#define J230K_TP_MAX_Y 7102 ++#define J230K_TP_RES_Y \ ++ ((J230K_TP_MAX_Y - J230K_TP_MIN_Y) / (J230K_TP_DIMENSION_Y / 100)) ++ ++#define J152F_TP_DIMENSION_X (float)16000 ++#define J152F_TP_MIN_X -7456 ++#define J152F_TP_MAX_X 7976 ++#define J152F_TP_RES_X \ ++ ((J152F_TP_MAX_X - J152F_TP_MIN_X) / (J152F_TP_DIMENSION_X / 100)) ++#define J152F_TP_DIMENSION_Y (float)10000 ++#define J152F_TP_MIN_Y -163 ++#define J152F_TP_MAX_Y 9283 ++#define J152F_TP_RES_Y \ ++ ((J152F_TP_MAX_Y - J152F_TP_MIN_Y) / (J152F_TP_DIMENSION_Y / 100)) ++ + /* These are fallback values, since the real values will be queried from the device. */ + #define J314_TP_DIMENSION_X (float)13000 + #define J314_TP_MIN_X -5900 +@@ -130,7 +229,11 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie + #define J314_TP_RES_Y \ + ((J314_TP_MAX_Y - J314_TP_MIN_Y) / (J314_TP_DIMENSION_Y / 100)) + +-#define J314_TP_MAX_FINGER_ORIENTATION 16384 ++#define T2_TOUCHPAD_ENTRY(model) \ ++ { USB_DEVICE_ID_APPLE_WELLSPRINGT2_##model, model##_TP_MIN_X, model##_TP_MIN_Y, \ ++model##_TP_MAX_X, model##_TP_MAX_Y, model##_TP_RES_X, model##_TP_RES_Y } ++ ++#define INTERNAL_TP_MAX_FINGER_ORIENTATION 16384 + + struct magicmouse_input_ops { + int (*raw_event)(struct hid_device *hdev, +@@ -733,7 +836,7 @@ static void report_finger_data(struct input_dev *input, int slot, + input_report_abs(input, ABS_MT_WIDTH_MINOR, + le16_to_int(f->tool_minor) << 1); + input_report_abs(input, ABS_MT_ORIENTATION, +- J314_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); ++ INTERNAL_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation)); + input_report_abs(input, ABS_MT_PRESSURE, le16_to_int(f->pressure)); + input_report_abs(input, ABS_MT_POSITION_X, pos->x); + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); +@@ -821,6 +924,20 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev, + return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); + } + ++static int magicmouse_raw_event_t2(struct hid_device *hdev, ++ struct hid_report *report, u8 *data, int size) ++{ ++ const size_t hdr_sz = sizeof(struct tp_mouse_report); ++ ++ if (!size) ++ return 0; ++ ++ if (data[0] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz) ++ return 0; ++ ++ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz); ++} ++ + static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { +@@ -1018,8 +1135,32 @@ static int magicmouse_setup_input_usb(struct input_dev *input, + return 0; + } + +-static int magicmouse_setup_input_mtp(struct input_dev *input, +- struct hid_device *hdev) ++struct magicmouse_t2_properties { ++ u32 id; ++ int min_x; ++ int min_y; ++ int max_x; ++ int max_y; ++ int res_x; ++ int res_y; ++}; ++ ++static const struct magicmouse_t2_properties magicmouse_t2_configs[] = { ++ T2_TOUCHPAD_ENTRY(J140K), ++ T2_TOUCHPAD_ENTRY(J132), ++ T2_TOUCHPAD_ENTRY(J680), ++ T2_TOUCHPAD_ENTRY(J680_ALT), ++ T2_TOUCHPAD_ENTRY(J213), ++ T2_TOUCHPAD_ENTRY(J214K), ++ T2_TOUCHPAD_ENTRY(J223), ++ T2_TOUCHPAD_ENTRY(J230K), ++ T2_TOUCHPAD_ENTRY(J152F), ++}; ++ ++static int magicmouse_setup_input_int_tpd(struct input_dev *input, ++ struct hid_device *hdev, int min_x, int min_y, ++ int max_x, int max_y, int res_x, int res_y, ++ bool query_dimensions) + { + int error; + int mt_flags = 0; +@@ -1060,19 +1201,17 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + input_abs_set_res(input, ABS_MT_PRESSURE, 1); + + /* finger orientation */ +- input_set_abs_params(input, ABS_MT_ORIENTATION, -J314_TP_MAX_FINGER_ORIENTATION, +- J314_TP_MAX_FINGER_ORIENTATION, 0, 0); ++ input_set_abs_params(input, ABS_MT_ORIENTATION, -INTERNAL_TP_MAX_FINGER_ORIENTATION, ++ INTERNAL_TP_MAX_FINGER_ORIENTATION, 0, 0); + + /* finger position */ +- input_set_abs_params(input, ABS_MT_POSITION_X, J314_TP_MIN_X, J314_TP_MAX_X, +- 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_X, min_x, max_x, 0, 0); + /* Y axis is inverted */ +- input_set_abs_params(input, ABS_MT_POSITION_Y, -J314_TP_MAX_Y, -J314_TP_MIN_Y, +- 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_Y, -max_y, -min_y, 0, 0); + + /* X/Y resolution */ +- input_abs_set_res(input, ABS_MT_POSITION_X, J314_TP_RES_X); +- input_abs_set_res(input, ABS_MT_POSITION_Y, J314_TP_RES_Y); ++ input_abs_set_res(input, ABS_MT_POSITION_X, res_x); ++ input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); + + input_set_events_per_packet(input, 60); + +@@ -1099,7 +1238,20 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + */ + input->open = magicmouse_open; + input->close = magicmouse_close; +- msc->query_dimensions = true; ++ msc->query_dimensions = query_dimensions; ++ ++ return 0; ++} ++ ++static int magicmouse_setup_input_mtp(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X, ++ J314_TP_MIN_Y, J314_TP_MAX_X, ++ J314_TP_MAX_Y, J314_TP_RES_X, ++ J314_TP_RES_Y, true); ++ if (ret) ++ return ret; + + return 0; + } +@@ -1107,7 +1259,34 @@ static int magicmouse_setup_input_mtp(struct input_dev *input, + static int magicmouse_setup_input_spi(struct input_dev *input, + struct hid_device *hdev) + { +- int ret = magicmouse_setup_input_mtp(input, hdev); ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X, ++ J314_TP_MIN_Y, J314_TP_MAX_X, ++ J314_TP_MAX_Y, J314_TP_RES_X, ++ J314_TP_RES_Y, true); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int magicmouse_setup_input_t2(struct input_dev *input, ++ struct hid_device *hdev) ++{ ++ int min_x, min_y, max_x, max_y, res_x, res_y; ++ ++ for (size_t i = 0; i < ARRAY_SIZE(magicmouse_t2_configs); i++) { ++ if (magicmouse_t2_configs[i].id == hdev->product) { ++ min_x = magicmouse_t2_configs[i].min_x; ++ min_y = magicmouse_t2_configs[i].min_y; ++ max_x = magicmouse_t2_configs[i].max_x; ++ max_y = magicmouse_t2_configs[i].max_y; ++ res_x = magicmouse_t2_configs[i].res_x; ++ res_y = magicmouse_t2_configs[i].res_y; ++ } ++ } ++ ++ int ret = magicmouse_setup_input_int_tpd(input, hdev, min_x, min_y, ++ max_x, max_y, res_x, res_y, false); + if (ret) + return ret; + +@@ -1180,6 +1359,18 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev) + feature = feature_mt_trackpad2_usb; + } + break; ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ feature_size = sizeof(feature_mt_trackpad2_usb); ++ feature = feature_mt_trackpad2_usb; ++ break; + case USB_DEVICE_ID_APPLE_MAGICMOUSE2: + case USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC: + feature_size = sizeof(feature_mt_mouse2); +@@ -1273,8 +1464,23 @@ static int magicmouse_probe(struct hid_device *hdev, + int ret; + + if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE && +- hdev->type != HID_TYPE_SPI_MOUSE) +- return -ENODEV; ++ hdev->type != HID_TYPE_SPI_MOUSE) ++ return -ENODEV; ++ ++ switch (id->product) { ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ if (hdev->type != HID_TYPE_USBMOUSE) ++ return -ENODEV; ++ break; ++ } + + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { +@@ -1284,15 +1490,33 @@ static int magicmouse_probe(struct hid_device *hdev, + + // internal trackpad use a data format use input ops to avoid + // conflicts with the report ID. +- if (id->bus == BUS_HOST) { ++ switch (id->bus) { ++ case BUS_HOST: + msc->input_ops.raw_event = magicmouse_raw_event_mtp; + msc->input_ops.setup_input = magicmouse_setup_input_mtp; +- } else if (id->bus == BUS_SPI) { ++ break; ++ case BUS_SPI: + msc->input_ops.raw_event = magicmouse_raw_event_spi; + msc->input_ops.setup_input = magicmouse_setup_input_spi; +- } else { +- msc->input_ops.raw_event = magicmouse_raw_event_usb; +- msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ break; ++ default: ++ switch (id->product) { ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ msc->input_ops.raw_event = magicmouse_raw_event_t2; ++ msc->input_ops.setup_input = magicmouse_setup_input_t2; ++ break; ++ default: ++ msc->input_ops.raw_event = magicmouse_raw_event_usb; ++ msc->input_ops.setup_input = magicmouse_setup_input_usb; ++ } + } + + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; +@@ -1353,6 +1577,18 @@ static int magicmouse_probe(struct hid_device *hdev, + TRACKPAD2_USB_REPORT_ID, 0); + } + break; ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: ++ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD2_USB_REPORT_ID, 0); ++ break; + case HID_ANY_ID: + switch (id->bus) { + case BUS_HOST: +@@ -1464,6 +1700,24 @@ static const struct hid_device_id magic_mice[] = { + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), .driver_data = 0 }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), .driver_data = 0 }, + { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID), + .driver_data = 0 }, + { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/4005-HID-magicmouse-fix-regression-breaking-support-for-M.patch b/patch/kernel/archive/uefi-x86-6.18/4005-HID-magicmouse-fix-regression-breaking-support-for-M.patch new file mode 100644 index 000000000..26a59fbfd --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/4005-HID-magicmouse-fix-regression-breaking-support-for-M.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Wed, 8 Oct 2025 01:48:18 +0000 +Subject: HID: magicmouse: fix regression breaking support for Magic Trackpad 1 + +The case HID_ANY_ID and default are technically the same, but the first +one was assigning no report to the Magic Trackpad 1, while the second +one assigns the correct report. Since the first case is matched first, +the Magic Trackpad 1 was not being assigned any report, breaking +support for it. + +Signed-off-by: Aditya Garg +--- + drivers/hid/hid-magicmouse.c | 15 ++++------ + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 111111111111..222222222222 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -1589,7 +1589,7 @@ static int magicmouse_probe(struct hid_device *hdev, + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD2_USB_REPORT_ID, 0); + break; +- case HID_ANY_ID: ++ default: + switch (id->bus) { + case BUS_HOST: + report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0); +@@ -1597,15 +1597,12 @@ static int magicmouse_probe(struct hid_device *hdev, + case BUS_SPI: + report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0); + break; +- default: +- break; ++ default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ TRACKPAD_REPORT_ID, 0); ++ report = hid_register_report(hdev, HID_INPUT_REPORT, ++ DOUBLE_REPORT_ID, 0); + } +- break; +- default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- TRACKPAD_REPORT_ID, 0); +- report = hid_register_report(hdev, HID_INPUT_REPORT, +- DOUBLE_REPORT_ID, 0); + } + + if (!report) { +-- +Armbian + diff --git a/patch/kernel/archive/uefi-x86-6.18/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch b/patch/kernel/archive/uefi-x86-6.18/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch new file mode 100644 index 000000000..219906001 --- /dev/null +++ b/patch/kernel/archive/uefi-x86-6.18/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ashish Arora +Date: Sat, 8 Jan 2022 21:43:18 +1100 +Subject: drm/i915: Discard large BIOS framebuffers causing display corruption + +On certain 4k panels, the BIOS framebuffer is larger than what panel +requires causing display corruption. Introduce a check for the same. + +Signed-off-by: Ashish Arora +--- + drivers/gpu/drm/i915/display/intel_fbdev.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/i915/display/intel_fbdev.c ++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c +@@ -224,10 +224,10 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + ifbdev->fb = NULL; + + if (fb && +- (sizes->fb_width > fb->base.width || +- sizes->fb_height > fb->base.height)) { ++ (sizes->fb_width != fb->base.width || ++ sizes->fb_height != fb->base.height)) { + drm_dbg_kms(display->drm, +- "BIOS fb too small (%dx%d), we require (%dx%d)," ++ "BIOS fb not valid (%dx%d), we require (%dx%d)," + " releasing it\n", + fb->base.width, fb->base.height, + sizes->fb_width, sizes->fb_height); +-- +Armbian + diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_radxa-e54c b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_radxa-e54c new file mode 120000 index 000000000..624370e6e --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_radxa-e54c @@ -0,0 +1 @@ +board_rock-5c/ \ No newline at end of file diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-rk3588s_defconfig deleted file mode 100644 index 60c77804f..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-rk3588s_defconfig +++ /dev/null @@ -1,225 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_ROCKCHIP=y -CONFIG_SPL_GPIO_SUPPORT=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_SYS_MALLOC_F_LEN=0x80000 -CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -CONFIG_ROCKCHIP_RK3588=y -CONFIG_ROCKCHIP_USB_BOOT=y -CONFIG_ROCKCHIP_FIT_IMAGE=y -CONFIG_ROCKCHIP_HWID_DTB=y -CONFIG_ROCKCHIP_VENDOR_PARTITION=y -CONFIG_USING_KERNEL_DTB_V2=y -CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -CONFIG_ROCKCHIP_NEW_IDB=y -CONFIG_LOADER_INI="RK3588MINIALL.ini" -CONFIG_TRUST_INI="RK3588TRUST.ini" -CONFIG_SPL_SERIAL_SUPPORT=y -CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -CONFIG_TARGET_EVB_RK3588=y -CONFIG_SPL_LIBDISK_SUPPORT=y -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI_SUPPORT=y -CONFIG_DEFAULT_DEVICE_TREE="rk3588s-nanopi-m6" -CONFIG_DEBUG_UART=y -CONFIG_FIT=y -CONFIG_FIT_IMAGE_POST_PROCESS=y -CONFIG_FIT_HW_CRYPTO=y -CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -CONFIG_SPL_FIT_HW_CRYPTO=y -# CONFIG_SPL_SYS_DCACHE_OFF is not set -CONFIG_BOOTDELAY=0 -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -CONFIG_ANDROID_BOOTLOADER=y -CONFIG_ANDROID_AVB=y -CONFIG_ANDROID_BOOT_IMAGE_HASH=y -CONFIG_SPL_BOARD_INIT=y -# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -CONFIG_SPL_SEPARATE_BSS=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 -CONFIG_SPL_MMC_WRITE=y -CONFIG_SPL_MTD_SUPPORT=y -CONFIG_SPL_ATF=y -CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -CONFIG_FASTBOOT_FLASH=y -CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -CONFIG_CMD_BOOTZ=y -CONFIG_CMD_DTIMG=y -# CONFIG_CMD_ELF is not set -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_IMLS is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_LZMADEC is not set -# CONFIG_CMD_UNZIP is not set -# CONFIG_CMD_FLASH is not set -# CONFIG_CMD_FPGA is not set -CONFIG_CMD_GPT=y -# CONFIG_CMD_LOADB is not set -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_BOOT_ANDROID=y -CONFIG_CMD_MMC=y -CONFIG_CMD_PCI=y -CONFIG_CMD_SF=y -CONFIG_CMD_SPI=y -CONFIG_CMD_USB=y -CONFIG_CMD_USB_MASS_STORAGE=y -# CONFIG_CMD_ITEST is not set -# CONFIG_CMD_SETEXPR is not set -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_TFTP_BOOTM=y -CONFIG_CMD_TFTP_FLASH=y -# CONFIG_CMD_MISC is not set -CONFIG_CMD_MTD_BLK=y -CONFIG_CMD_REGULATOR=y -# CONFIG_SPL_DOS_PARTITION is not set -# CONFIG_ISO_PARTITION is not set -CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -CONFIG_SPL_OF_CONTROL=y -CONFIG_SPL_DTB_MINIMUM=y -CONFIG_OF_LIVE=y -CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" -# CONFIG_NET_TFTP_VARS is not set -CONFIG_REGMAP=y -CONFIG_SPL_REGMAP=y -CONFIG_SYSCON=y -CONFIG_SPL_SYSCON=y -# CONFIG_SARADC_ROCKCHIP is not set -CONFIG_SARADC_ROCKCHIP_V2=y -CONFIG_CLK=y -CONFIG_SPL_CLK=y -CONFIG_CLK_SCMI=y -CONFIG_SPL_CLK_SCMI=y -CONFIG_DM_CRYPTO=y -CONFIG_SPL_DM_CRYPTO=y -CONFIG_ROCKCHIP_CRYPTO_V2=y -CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -CONFIG_DM_RNG=y -CONFIG_RNG_ROCKCHIP=y -CONFIG_SCMI_FIRMWARE=y -CONFIG_SPL_SCMI_FIRMWARE=y -CONFIG_ROCKCHIP_GPIO=y -CONFIG_ROCKCHIP_GPIO_V2=y -CONFIG_SYS_I2C_ROCKCHIP=y -CONFIG_DM_KEY=y -CONFIG_ADC_KEY=y -CONFIG_MISC=y -CONFIG_SPL_MISC=y -CONFIG_MISC_DECOMPRESS=y -CONFIG_SPL_MISC_DECOMPRESS=y -CONFIG_ROCKCHIP_OTP=y -CONFIG_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_ROCKCHIP=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_SDMA=y -CONFIG_MMC_SDHCI_ROCKCHIP=y -CONFIG_MTD=y -CONFIG_MTD_BLK=y -CONFIG_MTD_DEVICE=y -CONFIG_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_SPI_FLASH=y -CONFIG_SF_DEFAULT_SPEED=80000000 -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_WINBOND=y -CONFIG_SPI_FLASH_XMC=y -CONFIG_SPI_FLASH_XTX=y -CONFIG_SPI_FLASH_MTD=y -CONFIG_DM_ETH=y -CONFIG_DM_ETH_PHY=y -CONFIG_DWC_ETH_QOS=y -CONFIG_GMAC_ROCKCHIP=y -CONFIG_NVME=y -CONFIG_PCI=y -CONFIG_DM_PCI=y -CONFIG_DM_PCI_COMPAT=y -CONFIG_PCIE_DW_ROCKCHIP=y -CONFIG_PHY_ROCKCHIP_INNO_USB2=y -CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y -CONFIG_PHY_ROCKCHIP_USBDP=y -CONFIG_PINCTRL=y -CONFIG_SPL_PINCTRL=y -CONFIG_DM_PMIC=y -CONFIG_PMIC_SPI_RK8XX=y -CONFIG_REGULATOR_PWM=y -CONFIG_DM_REGULATOR_FIXED=y -CONFIG_DM_REGULATOR_GPIO=y -CONFIG_REGULATOR_RK860X=y -CONFIG_REGULATOR_RK806=y -CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM=y -CONFIG_SPL_RAM=y -CONFIG_TPL_RAM=y -CONFIG_ROCKCHIP_SDRAM_COMMON=y -CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -CONFIG_DM_RESET=y -CONFIG_SPL_DM_RESET=y -CONFIG_SPL_RESET_ROCKCHIP=y -CONFIG_BAUDRATE=1500000 -CONFIG_DEBUG_UART_BASE=0xFEB50000 -CONFIG_DEBUG_UART_CLOCK=24000000 -CONFIG_DEBUG_UART_SHIFT=2 -CONFIG_ROCKCHIP_SPI=y -CONFIG_SYSRESET=y -CONFIG_USB=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_GENERIC=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_GENERIC=y -CONFIG_USB_DWC3=y -CONFIG_USB_DWC3_GADGET=y -CONFIG_USB_DWC3_GENERIC=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -CONFIG_USB_GADGET_DOWNLOAD=y -CONFIG_DM_VIDEO=y -CONFIG_DISPLAY=y -CONFIG_DRM_ROCKCHIP=y -CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y -CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y -CONFIG_USE_TINY_PRINTF=y -CONFIG_LIB_RAND=y -CONFIG_SPL_TINY_MEMSET=y -CONFIG_RSA=y -CONFIG_SPL_RSA=y -CONFIG_RSA_N_SIZE=0x200 -CONFIG_RSA_E_SIZE=0x10 -CONFIG_RSA_C_SIZE=0x20 -CONFIG_LZ4=y -CONFIG_ERRNO_STR=y -# CONFIG_EFI_LOADER is not set -CONFIG_AVB_LIBAVB=y -CONFIG_AVB_LIBAVB_AB=y -CONFIG_AVB_LIBAVB_ATX=y -CONFIG_AVB_LIBAVB_USER=y -CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_LZMA=y -CONFIG_XBC=y -CONFIG_CMD_SETEXPR=y -CONFIG_AHCI=y -CONFIG_CMD_SCSI=y -CONFIG_DM_SCSI=y -CONFIG_DWC_AHCI=y -CONFIG_LIBATA=y -CONFIG_SCSI_AHCI=y -CONFIG_SCSI=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-spi-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-spi-rk3588s_defconfig deleted file mode 100644 index 8b95a5044..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-m6-spi-rk3588s_defconfig +++ /dev/null @@ -1,226 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_ROCKCHIP=y -CONFIG_SPL_GPIO_SUPPORT=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_SYS_MALLOC_F_LEN=0x80000 -CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -CONFIG_ROCKCHIP_RK3588=y -CONFIG_ROCKCHIP_USB_BOOT=y -CONFIG_ROCKCHIP_FIT_IMAGE=y -CONFIG_ROCKCHIP_HWID_DTB=y -CONFIG_ROCKCHIP_VENDOR_PARTITION=y -CONFIG_USING_KERNEL_DTB_V2=y -CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -CONFIG_ROCKCHIP_NEW_IDB=y -CONFIG_LOADER_INI="RK3588MINIALL.ini" -CONFIG_TRUST_INI="RK3588TRUST.ini" -CONFIG_SPL_SERIAL_SUPPORT=y -CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -CONFIG_TARGET_EVB_RK3588=y -CONFIG_SPL_LIBDISK_SUPPORT=y -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI_SUPPORT=y -CONFIG_DEFAULT_DEVICE_TREE="rk3588s-nanopi-m6-spi" -CONFIG_DEBUG_UART=y -CONFIG_FIT=y -CONFIG_FIT_IMAGE_POST_PROCESS=y -CONFIG_FIT_HW_CRYPTO=y -CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -CONFIG_SPL_FIT_HW_CRYPTO=y -# CONFIG_SPL_SYS_DCACHE_OFF is not set -CONFIG_BOOTDELAY=0 -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -CONFIG_ANDROID_BOOTLOADER=y -CONFIG_ANDROID_AVB=y -CONFIG_ANDROID_BOOT_IMAGE_HASH=y -CONFIG_SPL_BOARD_INIT=y -# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -CONFIG_SPL_SEPARATE_BSS=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 -CONFIG_SPL_MMC_WRITE=y -CONFIG_SPL_MTD_SUPPORT=y -CONFIG_SPL_ATF=y -CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -CONFIG_FASTBOOT_FLASH=y -CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -CONFIG_CMD_BOOTZ=y -CONFIG_CMD_DTIMG=y -# CONFIG_CMD_ELF is not set -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_IMLS is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_LZMADEC is not set -# CONFIG_CMD_UNZIP is not set -# CONFIG_CMD_FLASH is not set -# CONFIG_CMD_FPGA is not set -CONFIG_CMD_GPT=y -# CONFIG_CMD_LOADB is not set -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_BOOT_ANDROID=y -CONFIG_CMD_MMC=y -CONFIG_CMD_PCI=y -CONFIG_CMD_SF=y -CONFIG_CMD_SPI=y -CONFIG_CMD_USB=y -CONFIG_CMD_USB_MASS_STORAGE=y -# CONFIG_CMD_ITEST is not set -# CONFIG_CMD_SETEXPR is not set -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_TFTP_BOOTM=y -CONFIG_CMD_TFTP_FLASH=y -# CONFIG_CMD_MISC is not set -CONFIG_CMD_MTD_BLK=y -CONFIG_CMD_REGULATOR=y -# CONFIG_SPL_DOS_PARTITION is not set -# CONFIG_ISO_PARTITION is not set -CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -CONFIG_SPL_OF_CONTROL=y -CONFIG_SPL_DTB_MINIMUM=y -CONFIG_OF_LIVE=y -CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" -# CONFIG_NET_TFTP_VARS is not set -CONFIG_REGMAP=y -CONFIG_SPL_REGMAP=y -CONFIG_SYSCON=y -CONFIG_SPL_SYSCON=y -# CONFIG_SARADC_ROCKCHIP is not set -CONFIG_SARADC_ROCKCHIP_V2=y -CONFIG_CLK=y -CONFIG_SPL_CLK=y -CONFIG_CLK_SCMI=y -CONFIG_SPL_CLK_SCMI=y -CONFIG_DM_CRYPTO=y -CONFIG_SPL_DM_CRYPTO=y -CONFIG_ROCKCHIP_CRYPTO_V2=y -CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -CONFIG_DM_RNG=y -CONFIG_RNG_ROCKCHIP=y -CONFIG_SCMI_FIRMWARE=y -CONFIG_SPL_SCMI_FIRMWARE=y -CONFIG_ROCKCHIP_GPIO=y -CONFIG_ROCKCHIP_GPIO_V2=y -CONFIG_SYS_I2C_ROCKCHIP=y -CONFIG_DM_KEY=y -CONFIG_ADC_KEY=y -CONFIG_MISC=y -CONFIG_SPL_MISC=y -CONFIG_MISC_DECOMPRESS=y -CONFIG_SPL_MISC_DECOMPRESS=y -CONFIG_ROCKCHIP_OTP=y -CONFIG_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_ROCKCHIP=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_SDMA=y -CONFIG_MMC_SDHCI_ROCKCHIP=y -CONFIG_MTD=y -CONFIG_MTD_BLK=y -CONFIG_MTD_DEVICE=y -CONFIG_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_SPI_FLASH=y -CONFIG_SF_DEFAULT_SPEED=80000000 -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_WINBOND=y -CONFIG_SPI_FLASH_XMC=y -CONFIG_SPI_FLASH_XTX=y -CONFIG_SPI_FLASH_MTD=y -CONFIG_DM_ETH=y -CONFIG_DM_ETH_PHY=y -CONFIG_DWC_ETH_QOS=y -CONFIG_GMAC_ROCKCHIP=y -CONFIG_NVME=y -CONFIG_PCI=y -CONFIG_DM_PCI=y -CONFIG_DM_PCI_COMPAT=y -CONFIG_PCIE_DW_ROCKCHIP=y -CONFIG_PHY_ROCKCHIP_INNO_USB2=y -CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y -CONFIG_PHY_ROCKCHIP_USBDP=y -CONFIG_PINCTRL=y -CONFIG_SPL_PINCTRL=y -CONFIG_DM_PMIC=y -CONFIG_PMIC_SPI_RK8XX=y -CONFIG_REGULATOR_PWM=y -CONFIG_DM_REGULATOR_FIXED=y -CONFIG_DM_REGULATOR_GPIO=y -CONFIG_REGULATOR_RK860X=y -CONFIG_REGULATOR_RK806=y -CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM=y -CONFIG_SPL_RAM=y -CONFIG_TPL_RAM=y -CONFIG_ROCKCHIP_SDRAM_COMMON=y -CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -CONFIG_DM_RESET=y -CONFIG_SPL_DM_RESET=y -CONFIG_SPL_RESET_ROCKCHIP=y -CONFIG_BAUDRATE=1500000 -CONFIG_DEBUG_UART_BASE=0xFEB50000 -CONFIG_DEBUG_UART_CLOCK=24000000 -CONFIG_DEBUG_UART_SHIFT=2 -CONFIG_ROCKCHIP_SPI=y -CONFIG_ROCKCHIP_SFC=y -CONFIG_SYSRESET=y -CONFIG_USB=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_GENERIC=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_GENERIC=y -CONFIG_USB_DWC3=y -CONFIG_USB_DWC3_GADGET=y -CONFIG_USB_DWC3_GENERIC=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -CONFIG_USB_GADGET_DOWNLOAD=y -CONFIG_DM_VIDEO=y -CONFIG_DISPLAY=y -CONFIG_DRM_ROCKCHIP=y -CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y -CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y -CONFIG_USE_TINY_PRINTF=y -CONFIG_LIB_RAND=y -CONFIG_SPL_TINY_MEMSET=y -CONFIG_RSA=y -CONFIG_SPL_RSA=y -CONFIG_RSA_N_SIZE=0x200 -CONFIG_RSA_E_SIZE=0x10 -CONFIG_RSA_C_SIZE=0x20 -CONFIG_LZ4=y -CONFIG_ERRNO_STR=y -# CONFIG_EFI_LOADER is not set -CONFIG_AVB_LIBAVB=y -CONFIG_AVB_LIBAVB_AB=y -CONFIG_AVB_LIBAVB_ATX=y -CONFIG_AVB_LIBAVB_USER=y -CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_LZMA=y -CONFIG_XBC=y -CONFIG_CMD_SETEXPR=y -CONFIG_AHCI=y -CONFIG_CMD_SCSI=y -CONFIG_DM_SCSI=y -CONFIG_DWC_AHCI=y -CONFIG_LIBATA=y -CONFIG_SCSI_AHCI=y -CONFIG_SCSI=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig deleted file mode 100644 index a7a81de9d..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig +++ /dev/null @@ -1,214 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_ROCKCHIP=y -CONFIG_SPL_GPIO_SUPPORT=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_SYS_MALLOC_F_LEN=0x80000 -CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -CONFIG_ROCKCHIP_RK3588=y -CONFIG_ROCKCHIP_USB_BOOT=y -CONFIG_ROCKCHIP_FIT_IMAGE=y -CONFIG_ROCKCHIP_HWID_DTB=y -CONFIG_ROCKCHIP_VENDOR_PARTITION=y -CONFIG_USING_KERNEL_DTB_V2=y -CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -CONFIG_ROCKCHIP_NEW_IDB=y -CONFIG_LOADER_INI="RK3588MINIALL.ini" -CONFIG_TRUST_INI="RK3588TRUST.ini" -CONFIG_SPL_SERIAL_SUPPORT=y -CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -CONFIG_TARGET_EVB_RK3588=y -CONFIG_SPL_LIBDISK_SUPPORT=y -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI_SUPPORT=y -CONFIG_DEFAULT_DEVICE_TREE="rk3588s-nanopi-r6s" -CONFIG_DEBUG_UART=y -CONFIG_FIT=y -CONFIG_FIT_IMAGE_POST_PROCESS=y -CONFIG_FIT_HW_CRYPTO=y -CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -CONFIG_SPL_FIT_HW_CRYPTO=y -# CONFIG_SPL_SYS_DCACHE_OFF is not set -CONFIG_BOOTDELAY=0 -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -CONFIG_ANDROID_BOOTLOADER=y -CONFIG_ANDROID_AVB=y -CONFIG_ANDROID_BOOT_IMAGE_HASH=y -CONFIG_SPL_BOARD_INIT=y -# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -CONFIG_SPL_SEPARATE_BSS=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 -CONFIG_SPL_MMC_WRITE=y -CONFIG_SPL_MTD_SUPPORT=y -CONFIG_SPL_ATF=y -CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -CONFIG_FASTBOOT_FLASH=y -CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -CONFIG_CMD_BOOTZ=y -CONFIG_CMD_DTIMG=y -# CONFIG_CMD_ELF is not set -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_IMLS is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_LZMADEC is not set -# CONFIG_CMD_UNZIP is not set -# CONFIG_CMD_FLASH is not set -# CONFIG_CMD_FPGA is not set -CONFIG_CMD_GPT=y -# CONFIG_CMD_LOADB is not set -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_BOOT_ANDROID=y -CONFIG_CMD_MMC=y -CONFIG_CMD_PCI=y -CONFIG_CMD_SF=y -CONFIG_CMD_SPI=y -CONFIG_CMD_USB=y -CONFIG_CMD_USB_MASS_STORAGE=y -# CONFIG_CMD_ITEST is not set -# CONFIG_CMD_SETEXPR is not set -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_TFTP_BOOTM=y -CONFIG_CMD_TFTP_FLASH=y -# CONFIG_CMD_MISC is not set -CONFIG_CMD_MTD_BLK=y -# CONFIG_SPL_DOS_PARTITION is not set -# CONFIG_ISO_PARTITION is not set -CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -CONFIG_SPL_OF_CONTROL=y -CONFIG_SPL_DTB_MINIMUM=y -CONFIG_OF_LIVE=y -CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" -# CONFIG_NET_TFTP_VARS is not set -CONFIG_REGMAP=y -CONFIG_SPL_REGMAP=y -CONFIG_SYSCON=y -CONFIG_SPL_SYSCON=y -# CONFIG_SARADC_ROCKCHIP is not set -CONFIG_SARADC_ROCKCHIP_V2=y -CONFIG_CLK=y -CONFIG_SPL_CLK=y -CONFIG_CLK_SCMI=y -CONFIG_SPL_CLK_SCMI=y -CONFIG_DM_CRYPTO=y -CONFIG_SPL_DM_CRYPTO=y -CONFIG_ROCKCHIP_CRYPTO_V2=y -CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -CONFIG_DM_RNG=y -CONFIG_RNG_ROCKCHIP=y -CONFIG_SCMI_FIRMWARE=y -CONFIG_SPL_SCMI_FIRMWARE=y -CONFIG_ROCKCHIP_GPIO=y -CONFIG_ROCKCHIP_GPIO_V2=y -CONFIG_SYS_I2C_ROCKCHIP=y -CONFIG_DM_KEY=y -CONFIG_ADC_KEY=y -CONFIG_MISC=y -CONFIG_SPL_MISC=y -CONFIG_MISC_DECOMPRESS=y -CONFIG_SPL_MISC_DECOMPRESS=y -CONFIG_ROCKCHIP_OTP=y -CONFIG_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y -CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_ROCKCHIP=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_SDMA=y -CONFIG_MMC_SDHCI_ROCKCHIP=y -CONFIG_MTD=y -CONFIG_MTD_BLK=y -CONFIG_MTD_DEVICE=y -CONFIG_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_SPI_FLASH=y -CONFIG_SF_DEFAULT_SPEED=80000000 -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_WINBOND=y -CONFIG_SPI_FLASH_XMC=y -CONFIG_SPI_FLASH_XTX=y -CONFIG_SPI_FLASH_MTD=y -CONFIG_DM_ETH=y -CONFIG_DM_ETH_PHY=y -CONFIG_DWC_ETH_QOS=y -CONFIG_GMAC_ROCKCHIP=y -CONFIG_NVME=y -CONFIG_PCI=y -CONFIG_DM_PCI=y -CONFIG_DM_PCI_COMPAT=y -CONFIG_PCIE_DW_ROCKCHIP=y -CONFIG_PHY_ROCKCHIP_INNO_USB2=y -CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y -CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y -CONFIG_PINCTRL=y -CONFIG_SPL_PINCTRL=y -CONFIG_DM_PMIC=y -CONFIG_PMIC_SPI_RK8XX=y -CONFIG_REGULATOR_PWM=y -CONFIG_DM_REGULATOR_FIXED=y -CONFIG_DM_REGULATOR_GPIO=y -CONFIG_REGULATOR_RK860X=y -CONFIG_REGULATOR_RK806=y -CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM=y -CONFIG_SPL_RAM=y -CONFIG_TPL_RAM=y -CONFIG_ROCKCHIP_SDRAM_COMMON=y -CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -CONFIG_DM_RESET=y -CONFIG_SPL_DM_RESET=y -CONFIG_SPL_RESET_ROCKCHIP=y -CONFIG_BAUDRATE=1500000 -CONFIG_DEBUG_UART_BASE=0xFEB50000 -CONFIG_DEBUG_UART_CLOCK=24000000 -CONFIG_DEBUG_UART_SHIFT=2 -CONFIG_ROCKCHIP_SPI=y -CONFIG_ROCKCHIP_SFC=y -CONFIG_SYSRESET=y -CONFIG_USB=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_GENERIC=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_GENERIC=y -CONFIG_USB_DWC3=y -CONFIG_USB_DWC3_GADGET=y -CONFIG_USB_DWC3_GENERIC=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -CONFIG_USB_GADGET_DOWNLOAD=y -CONFIG_DM_VIDEO=y -CONFIG_DISPLAY=y -CONFIG_DRM_ROCKCHIP=y -CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y -CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y -CONFIG_USE_TINY_PRINTF=y -CONFIG_LIB_RAND=y -CONFIG_SPL_TINY_MEMSET=y -CONFIG_RSA=y -CONFIG_SPL_RSA=y -CONFIG_RSA_N_SIZE=0x200 -CONFIG_RSA_E_SIZE=0x10 -CONFIG_RSA_C_SIZE=0x20 -CONFIG_LZ4=y -CONFIG_ERRNO_STR=y -# CONFIG_EFI_LOADER is not set -CONFIG_AVB_LIBAVB=y -CONFIG_AVB_LIBAVB_AB=y -CONFIG_AVB_LIBAVB_ATX=y -CONFIG_AVB_LIBAVB_USER=y -CONFIG_RK_AVB_LIBAVB_USER=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6-spi.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6-spi.dts deleted file mode 100644 index b035051a4..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6-spi.dts +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * Copyright (c) 2024 Rockchip Electronics Co., Ltd - * - */ - -/dts-v1/; -#include "rk3588s-nanopi-m6.dts" - -/ { - model = "NanoPi M6 (SPI)"; -}; - -&sdhci { - status = "disabled"; -}; - -&sfc { - u-boot,dm-pre-reloc; - pinctrl-names = "default"; - pinctrl-0 = <&fspim0_pins>; - status = "okay"; -}; - -&spi_nor { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&pinctrl { - - /delete-node/ fspi; - fspi { - u-boot,dm-spl; - fspim0_pins: fspim0-pins { - u-boot,dm-spl; - rockchip,pins = - /* fspi_clk_m0 */ - <2 RK_PA0 2 &pcfg_pull_none>, - /* fspi_cs0n_m0 */ - <2 RK_PD6 2 &pcfg_pull_none>, - /* fspi_d0_m0 */ - <2 RK_PD0 2 &pcfg_pull_none>, - /* fspi_d1_m0 */ - <2 RK_PD1 2 &pcfg_pull_none>, - /* fspi_d2_m0 */ - <2 RK_PD2 2 &pcfg_pull_none>, - /* fspi_d3_m0 */ - <2 RK_PD3 2 &pcfg_pull_none>; - }; - }; -}; diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6.dts deleted file mode 100644 index 78774bc21..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-m6.dts +++ /dev/null @@ -1,203 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * Copyright (c) 2021 Rockchip Electronics Co., Ltd - * - */ - -/dts-v1/; -#include "rk3588.dtsi" -#include "rk3588-u-boot.dtsi" -#include - -/ { - model = "NanoPi M6"; - compatible = "nanopi,nanopi-m6", "rockchip,rk3588s"; - - vcc12v_dcin: vcc12v-dcin { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "vcc12v_dcin"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; - }; - - vcc5v0_sys: vcc5v0-sys { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc12v_dcin>; - }; - - vcc5v0_usb: vcc5v0-usb { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_usb"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc3v3_pcie_m2: vcc3v3-pcie30 { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - enable-active-high; - gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&pcie_m2_0_pwren>; - regulator-name = "vcc3v3_pcie_m2"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc5v0_host_20: vcc5v0-host-20 { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - enable-active-high; - gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_host20_en>; - regulator-name = "vcc5v0_host_20"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usb>; - }; - - vbus5v0_typec: vbus5v0-typec { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - enable-active-high; - gpio = <&gpio3 RK_PD4 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>; - }; -}; - -&combphy0_ps { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&combphy2_psu { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&pcie2x1l2 { - u-boot,dm-pre-reloc; - pinctrl-names = "default"; - pinctrl-0 = <&pcie_m2_0_prsnt>; - reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; - prsnt-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; - phys = <&combphy0_ps PHY_TYPE_PCIE>; - vpcie3v3-supply = <&vcc3v3_pcie_m2>; - status = "okay"; -}; - -&usb2phy0_grf { - u-boot,dm-pre-reloc; - status = "okay"; -}; - - -&u2phy0 { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&u2phy0_otg { - phy-supply = <&vbus5v0_typec>; - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb2phy2_grf { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&u2phy2 { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&u2phy2_host { - phy-supply = <&vcc5v0_host_20>; - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb2phy3_grf { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&u2phy3 { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&u2phy3_host { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb_host1_ehci { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb_host1_ohci { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb_host0_ehci { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&usb_host0_ohci { - u-boot,dm-pre-reloc; - status = "okay"; -}; - -&pinctrl { - pcie { - u-boot,dm-pre-reloc; - pcie_m2_0_pwren: pcie-m20-pwren { - u-boot,dm-pre-reloc; - rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - pcie_m2_0_prsnt: pcie-m20-prsnt { - u-boot,dm-pre-reloc; - rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - usb { - u-boot,dm-pre-reloc; - typec5v_pwren: typec5v-pwren { - u-boot,dm-pre-reloc; - rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - vcc5v0_host20_en: vcc5v0-host20-en { - u-boot,dm-pre-reloc; - rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-r6s.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-r6s.dts deleted file mode 100644 index 4899e23fa..000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-nanopi-r6s.dts +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * Copyright (c) 2021 Rockchip Electronics Co., Ltd - * - */ - -/dts-v1/; -#include "rk3588.dtsi" -#include "rk3588-u-boot.dtsi" -#include - -/ { - model = "NanoPi R6S"; - compatible = "nanopi,nanopi-r6s", "rockchip,rk3588"; - - vcc12v_dcin: vcc12v-dcin { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "vcc12v_dcin"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; - }; - - vcc5v0_sys: vcc5v0-sys { - u-boot,dm-pre-reloc; - 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>; - }; - - vcc_5v0: vcc-5v0 { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "vcc_5v0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-boot-on; - regulator-always-on; - enable-active-high; - gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc_5v0_en>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc5v0_host: vcc5v0-host-regulator { - u-boot,dm-pre-reloc; - 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_PB5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_host_en>; - vin-supply = <&vcc5v0_sys>; - }; - - led_sys: led-sys { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; - regulator-name = "led_sys"; - enable-active-high; - gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; // Turn on user led - regulator-boot-on; - regulator-always-on; - vin-supply = <&vcc5v0_sys>; - }; -}; - -&usb2phy0_grf { - status = "okay"; - u-boot,dm-pre-reloc; -}; - - -&u2phy0 { - status = "okay"; - u-boot,dm-pre-reloc; -}; - -&u2phy0_otg { - status = "okay"; - u-boot,dm-pre-reloc; -}; - -&usb2phy2_grf { - status = "okay"; - u-boot,dm-pre-reloc; -}; - -&u2phy2 { - status = "okay"; - u-boot,dm-pre-reloc; -}; - -&u2phy2_host { - status = "okay"; - u-boot,dm-pre-reloc; -}; - -&pinctrl { - usb { - u-boot,dm-pre-reloc; - vcc5v0_host_en: vcc5v0-host-en { - u-boot,dm-pre-reloc; - rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - power { - u-boot,dm-spl; - vcc_5v0_en: vcc-5v0-en { - u-boot,dm-spl; - rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/0000.patching_config.yaml b/patch/u-boot/legacy/u-boot-rockchip-buildroot/0000.patching_config.yaml new file mode 100644 index 000000000..719cf56a8 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/0000.patching_config.yaml @@ -0,0 +1,5 @@ +config: + + overlay-directories: + - { source: "defconfig", target: "configs" } # copies all files in defconfig dir to the configs/ dir in the u-boot source tree + - { source: "dt", target: "arch/arm/dts" } # copies all files in dt dir to the arch/arm/dts dir in the u-boot source tree diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/defconfig/luckfox_rv1106_uboot_defconfig b/patch/u-boot/legacy/u-boot-rockchip-buildroot/defconfig/luckfox_rv1106_uboot_defconfig new file mode 100644 index 000000000..06cb1b4f7 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/defconfig/luckfox_rv1106_uboot_defconfig @@ -0,0 +1,161 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x80000 +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_optee.sh" +CONFIG_ROCKCHIP_RV1106=y +CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0 +CONFIG_ROCKCHIP_FIT_IMAGE=y +CONFIG_USING_KERNEL_DTB_V2=y +CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y +# CONFIG_ROCKCHIP_CMD="sd_update -" +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_TARGET_EVB_RV1106=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DEFAULT_DEVICE_TREE="rv1106-evb" +CONFIG_DEBUG_UART=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_ANDROID_BOOT_IMAGE=n +CONFIG_FIT=y +CONFIG_FIT_HW_CRYPTO=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_FIT_HW_CRYPTO=y +# CONFIG_SPL_SYS_DCACHE_OFF is not set +CONFIG_SPL_FIT_IMAGE_KB=512 +CONFIG_SPL_FIT_IMAGE_MULTIPLE=1 +CONFIG_BOOTDELAY=0 +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_ANDROID_BOOTLOADER=n +CONFIG_ANDROID_BOOT_IMAGE_HASH=n +# CONFIG_SKIP_RELOCATE_UBOOT is not set +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set +# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION is not set +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x440 +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_AB=n +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_ELF is not set +CONFIG_CMD_IMI=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_CRC32 is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y +CONFIG_RANDOM_UUID=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BOOT_ANDROID=n +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y +# CONFIG_CMD_ITEST is not set +CONFIG_CMD_SCRIPT_UPDATE=y +CONFIG_CMD_SOURCE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTP_BOOTM=y +CONFIG_CMD_TFTP_FLASH=y +CONFIG_CMD_DHCP=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +# CONFIG_CMD_MISC is not set +CONFIG_CMD_FAT=n +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_DTB_MINIMUM=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_OF_U_BOOT_REMOVE_PROPS="interrupt-parent" +CONFIG_ENVF=n +CONFIG_ENVF_LIST="blkdevparts mtdparts sys_bootargs app reserved ipaddr serverip netmask gatewayip ethaddr" +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +# CONFIG_SARADC_ROCKCHIP is not set +CONFIG_SARADC_ROCKCHIP_V2=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_DM_CRYPTO=y +CONFIG_SPL_DM_CRYPTO=y +CONFIG_ROCKCHIP_CRYPTO_V2=y +CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_ROCKCHIP_GPIO=y +# CONFIG_DM_I2C is not set +CONFIG_DM_KEY=y +CONFIG_ADC_KEY=y +CONFIG_MISC=y +CONFIG_SPL_MISC=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_SPL_ROCKCHIP_SECURE_OTP=y +# CONFIG_SUPPORT_EMMC_RPMB is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MTD=y +CONFIG_MTD_BLK=y +CONFIG_MTD_DEVICE=y +CONFIG_MTD_SPI_NAND=y +# CONFIG_PHY_RK630=y +# CONFIG_DM_ETH=y +# CONFIG_DM_ETH_PHY=y +# CONFIG_DWC_ETH_QOS=y +# CONFIG_DWC_ETH_QOS_FULL is not set +# CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +# CONFIG_DM_REGULATOR is not set +# CONFIG_DM_PWM is not set +CONFIG_RAM=y +CONFIG_TPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_DM_RESET=y +CONFIG_DEBUG_UART_BASE=0xff4c0000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +# CONFIG_SYSRESET_SYSCON_REBOOT is not set +# CONFIG_FAT_WRITE is not set +CONFIG_USE_TINY_PRINTF=y +# CONFIG_REGEX is not set +CONFIG_SPL_TINY_MEMSET=y +CONFIG_RSA=y +CONFIG_SPL_RSA=y +CONFIG_RSA_N_SIZE=0x200 +CONFIG_RSA_E_SIZE=0x10 +CONFIG_RSA_C_SIZE=0x20 +CONFIG_SPL_LZMA=y +CONFIG_SPL_GZIP=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set +CONFIG_ROCKCHIP_EMMC_IOMUX=y +CONFIG_ENV_IS_NOWHERE=y +CONFIG_CMD_GPT=y +CONFIG_PARTITIONS=y +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_UUIDS=y +CONFIG_CMD_SETEXPR=y +CONFIG_CMD_FDT=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_SPL_OPTEE=y +CONFIG_OPTEE=y +CONFIG_MENU=y diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/dt/rv1106-luckfox.dts b/patch/u-boot/legacy/u-boot-rockchip-buildroot/dt/rv1106-luckfox.dts new file mode 100644 index 000000000..a6fa39aa9 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/dt/rv1106-luckfox.dts @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rv1106.dtsi" +#include "rv1106-u-boot.dtsi" +#include + +/ { + model = "Rockchip RV1106 EVB2 Board"; + compatible = "rockchip,rv1106-evb2", "rockchip,rv1106"; + + chosen { + stdout-path = &uart2; + u-boot,spl-boot-order = &sdmmc, &spi_nand, &emmc; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* OP-TEE secure RAM */ + optee@3d00000 { + reg = <0x03d00000 0x00300000>; /* 3 MiB: 0x03D00000..0x04000000 */ + no-map; + }; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + u-boot,dm-spl; + status = "okay"; + + volumeup-key { + u-boot,dm-spl; + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <1750>; + }; + + }; +}; + +&hw_decompress { + u-boot,dm-spl; + status = "okay"; +}; + +&saradc { + u-boot,dm-spl; + status = "okay"; +}; \ No newline at end of file diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-malloc_8_hide_optee.patch b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-malloc_8_hide_optee.patch new file mode 100644 index 000000000..534a2d4b8 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-malloc_8_hide_optee.patch @@ -0,0 +1,28 @@ +diff --git a/include/configs/rv1103b_common.h b/include/configs/rv1103b_common.h +index f6ee6f88dc..32854c2af4 100644 +--- a/include/configs/rv1103b_common.h ++++ b/include/configs/rv1103b_common.h +@@ -10,7 +10,8 @@ + #include "rockchip-common.h" + + #define COUNTER_FREQUENCY 24000000 +-#define CONFIG_SYS_MALLOC_LEN (16 << 20) ++#define CONFIG_SYS_MALLOC_LEN (8 << 20) ++#define CONFIG_SYS_MEM_TOP_HIDE 0x00300000 + #define CONFIG_SYS_CBSIZE 1024 + #define CONFIG_SYS_NS16550_MEM32 + +diff --git a/include/configs/rv1106_common.h b/include/configs/rv1106_common.h +index dc927a8f36..0f062426b1 100644 +--- a/include/configs/rv1106_common.h ++++ b/include/configs/rv1106_common.h +@@ -12,7 +12,8 @@ + #include "rockchip-common.h" + + #define COUNTER_FREQUENCY 24000000 +-#define CONFIG_SYS_MALLOC_LEN (16 << 20) ++#define CONFIG_SYS_MALLOC_LEN (8 << 20) ++#define CONFIG_SYS_MEM_TOP_HIDE 0x00300000 + #define CONFIG_SYS_CBSIZE 1024 + #define CONFIG_SYS_NS16550_MEM32 + diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-mem_layout.patch b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-mem_layout.patch new file mode 100644 index 000000000..d83a0c5a2 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-mem_layout.patch @@ -0,0 +1,62 @@ +diff --git a/include/configs/rv1103b_common.h b/include/configs/rv1103b_common.h +index f6ee6f88dc..f30d0197e0 100644 +--- a/include/configs/rv1103b_common.h ++++ b/include/configs/rv1103b_common.h +@@ -57,19 +57,14 @@ + #ifdef CONFIG_ENV_MEM_LAYOUT + #define ENV_MEM_LAYOUT_SETTINGS CONFIG_ENV_MEM_LAYOUT_SETTINGS + #else +-/* +- * Image: 0 - 8M +- * zImage: 8 - 12M +- * fdt: 12 - 13M +- * ramdisk: 14 ... +- */ + #define ENV_MEM_LAYOUT_SETTINGS \ +- "scriptaddr=0x00b00000\0" \ +- "pxefile_addr_r=0x00c00000\0" \ +- "fdt_addr_r=0x00c00000\0" \ +- "kernel_addr_c=0x00808000\0" \ +- "kernel_addr_r=0x00008000\0" \ +- "ramdisk_addr_r=0x000e00000\0" ++ "scriptaddr=0x02000000\0" \ ++ "fdt_addr_r=0x03800000\0" \ ++ "kernel_addr_r=0x00800000\0" \ ++ "ramdisk_addr_r=0x02400000\0" \ ++ "fdt_high=0x03900000\0" \ ++ "initrd_high=0x03900000\0" \ ++ "load_addr=0x02000000\0" + #endif + + #define CONFIG_EXTRA_ENV_SETTINGS \ +diff --git a/include/configs/rv1106_common.h b/include/configs/rv1106_common.h +index dc927a8f36..d6912a88ba 100644 +--- a/include/configs/rv1106_common.h ++++ b/include/configs/rv1106_common.h +@@ -67,19 +67,14 @@ + #ifdef CONFIG_ENV_MEM_LAYOUT + #define ENV_MEM_LAYOUT_SETTINGS CONFIG_ENV_MEM_LAYOUT_SETTINGS + #else +-/* +- * Image: 0 - 8M +- * zImage: 8 - 12M +- * fdt: 12 - 13M +- * ramdisk: 14 ... +- */ + #define ENV_MEM_LAYOUT_SETTINGS \ +- "scriptaddr=0x00b00000\0" \ +- "pxefile_addr_r=0x00c00000\0" \ +- "fdt_addr_r=0x00c00000\0" \ +- "kernel_addr_c=0x00808000\0" \ +- "kernel_addr_r=0x00008000\0" \ +- "ramdisk_addr_r=0x000e00000\0" ++ "scriptaddr=0x02000000\0" \ ++ "fdt_addr_r=0x03800000\0" \ ++ "kernel_addr_r=0x00800000\0" \ ++ "ramdisk_addr_r=0x02400000\0" \ ++ "fdt_high=0x03900000\0" \ ++ "initrd_high=0x03900000\0" \ ++ "load_addr=0x02000000\0" + #endif + + #define CONFIG_EXTRA_ENV_SETTINGS \ diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-sysboot-extlinux.patch b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-sysboot-extlinux.patch new file mode 100644 index 000000000..5ed84017d --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/rv1103-rv1106-sysboot-extlinux.patch @@ -0,0 +1,30 @@ +diff --git a/include/configs/rv1103b_common.h b/include/configs/rv1103b_common.h +index f30d0197e0..5b22db2e42 100644 +--- a/include/configs/rv1103b_common.h ++++ b/include/configs/rv1103b_common.h +@@ -78,8 +78,8 @@ + "boot_fit;" + #else + #define RKIMG_BOOTCOMMAND \ +- "boot_fit;" \ +- "boot_android ${devtype} ${devnum};" ++ "setenv bootargs;" \ ++ "sysboot mmc 1:1 any ${scriptaddr} /boot/extlinux/extlinux.conf;" + #endif + + /* Update define for tiny image */ +diff --git a/include/configs/rv1106_common.h b/include/configs/rv1106_common.h +index d6912a88ba..b5378106e6 100644 +--- a/include/configs/rv1106_common.h ++++ b/include/configs/rv1106_common.h +@@ -88,8 +88,8 @@ + "boot_fit;" + #else + #define RKIMG_BOOTCOMMAND \ +- "boot_fit;" \ +- "boot_android ${devtype} ${devnum};" ++ "setenv bootargs;" \ ++ "sysboot mmc 1:1 any ${scriptaddr} /boot/extlinux/extlinux.conf;" + #endif + + /* Update define for tiny image */ diff --git a/patch/u-boot/legacy/u-boot-rockchip-buildroot/use-armv7a-for-modern-toolchain.patch b/patch/u-boot/legacy/u-boot-rockchip-buildroot/use-armv7a-for-modern-toolchain.patch new file mode 100644 index 000000000..e14c864d2 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-rockchip-buildroot/use-armv7a-for-modern-toolchain.patch @@ -0,0 +1,17 @@ +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 42c9ed887f..f15e10e995 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -14,10 +14,10 @@ arch-$(CONFIG_CPU_ARM926EJS) =-march=armv5te + arch-$(CONFIG_CPU_ARM946ES) =-march=armv5te + arch-$(CONFIG_CPU_SA1100) =-march=armv4 + arch-$(CONFIG_CPU_PXA) = +-arch-$(CONFIG_CPU_ARM1136) =-march=armv5 ++arch-$(CONFIG_CPU_ARM1136) =-march=armv7-a + arch-$(CONFIG_CPU_ARM1176) =-march=armv5t + arch-$(CONFIG_CPU_V7) =$(call cc-option, -march=armv7-a, \ +- $(call cc-option, -march=armv7, -march=armv5)) ++ $(call cc-option, -march=armv7, -march=armv7-a)) + arch-$(CONFIG_ARM64) =-march=armv8-a+nosimd + + # On Tegra systems we must build SPL for the armv4 core on the device diff --git a/patch/u-boot/u-boot-rk3506/forge1-btrfs.patch b/patch/u-boot/u-boot-rk3506/forge1-btrfs.patch new file mode 100644 index 000000000..e4b3a1528 --- /dev/null +++ b/patch/u-boot/u-boot-rk3506/forge1-btrfs.patch @@ -0,0 +1,12 @@ +diff --git a/configs/forge1-rk3506b_defconfig b/configs/forge1-rk3506b_defconfig +index d006413eec1..a191a649d66 100644 +--- a/configs/forge1-rk3506b_defconfig ++++ b/configs/forge1-rk3506b_defconfig +@@ -27,6 +27,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + # CONFIG_CMD_SETEXPR is not set + CONFIG_CMD_RNG=y + CONFIG_CMD_REGULATOR=y ++CONFIG_CMD_BTRFS=y + # CONFIG_SPL_DOS_PARTITION is not set + CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" + CONFIG_BUTTON=y diff --git a/patch/u-boot/v2025.04/board_bestv-r3300-l/add-board-bestv-r3300-l.patch b/patch/u-boot/v2025.04/board_bestv-r3300-l/add-board-bestv-r3300-l.patch new file mode 100644 index 000000000..939f0cabe --- /dev/null +++ b/patch/u-boot/v2025.04/board_bestv-r3300-l/add-board-bestv-r3300-l.patch @@ -0,0 +1,314 @@ +diff --git a/arch/arm/dts/meson-gxl-s905x-bestv-r3300-l-u-boot.dtsi b/arch/arm/dts/meson-gxl-s905x-bestv-r3300-l-u-boot.dtsi +new file mode 100644 +index 00000000..39270ea7 +--- /dev/null ++++ b/arch/arm/dts/meson-gxl-s905x-bestv-r3300-l-u-boot.dtsi +@@ -0,0 +1,7 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 BayLibre, SAS. ++ * Author: Neil Armstrong ++ */ ++ ++#include "meson-gxl-u-boot.dtsi" +diff --git a/configs/bestv-r3300-l_defconfig b/configs/bestv-r3300-l_defconfig +new file mode 100644 +index 00000000..8b6e9cec +--- /dev/null ++++ b/configs/bestv-r3300-l_defconfig +@@ -0,0 +1,56 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_MESON=y ++CONFIG_TEXT_BASE=0x01000000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y ++CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20000000 ++CONFIG_ENV_SIZE=0x2000 ++CONFIG_DM_GPIO=y ++CONFIG_DEFAULT_DEVICE_TREE="amlogic/meson-gxl-s905x-bestv-r3300-l" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_DM_RESET=y ++CONFIG_MESON_GXL=y ++CONFIG_SYS_LOAD_ADDR=0x1000000 ++CONFIG_DEBUG_UART_BASE=0xc81004c0 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_IDENT_STRING=" r3300-l" ++CONFIG_DEBUG_UART=y ++CONFIG_REMAKE_ELF=y ++CONFIG_FIT=y ++CONFIG_FIT_SIGNATURE=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_OF_BOARD_SETUP=y ++CONFIG_CONSOLE_MUX=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_MISC_INIT_R=y ++CONFIG_SYS_MAXARGS=32 ++# CONFIG_CMD_BDI is not set ++# CONFIG_CMD_IMI is not set ++CONFIG_CMD_GPIO=y ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_REGULATOR=y ++CONFIG_OF_CONTROL=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_MMC_MESON_GX=y ++CONFIG_PHY_MESON_GXL=y ++CONFIG_DM_MDIO=y ++CONFIG_DM_MDIO_MUX=y ++CONFIG_ETH_DESIGNWARE_MESON8B=y ++CONFIG_MDIO_MUX_MESON_GXL=y ++CONFIG_MESON_GXL_USB_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCTRL_MESON_GXL=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DEBUG_UART_ANNOUNCE=y ++CONFIG_DEBUG_UART_SKIP_INIT=y ++CONFIG_MESON_SERIAL=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_MESON_GXL=y +diff --git a/dts/upstream/src/arm64/amlogic/meson-gxl-s905x-bestv-r3300-l.dts b/dts/upstream/src/arm64/amlogic/meson-gxl-s905x-bestv-r3300-l.dts +new file mode 100644 +index 00000000..0b46edbe +--- /dev/null ++++ b/dts/upstream/src/arm64/amlogic/meson-gxl-s905x-bestv-r3300-l.dts +@@ -0,0 +1,233 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2025 retro98boy ++ */ ++ ++/dts-v1/; ++ ++#include "meson-gxl-s905x-p212.dtsi" ++#include ++#include ++#include ++ ++/ { ++ compatible = "bestv,r3300-l", "amlogic,s905x", "amlogic,meson-gxl"; ++ model = "BesTV R3300-L"; ++ ++ /* ++ aliases { ++ rtc1 = &vrtc; ++ }; ++ */ ++ ++ memory@0 { ++ reg = <0x0 0x0 0x0 0x40000000>; ++ }; ++ ++ gpio-keys-polled { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <100>; ++ ++ rst-btn { ++ label = "rst-btn"; ++ linux,code = ; ++ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ /* ++ * The power LED on the device is always on, defaulting to red. ++ * Pulling GPIODV_24 high changes it to green, indicating that the kernel has started. ++ */ ++ pwr-led-green { ++ function = LED_FUNCTION_POWER; ++ color = ; ++ gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ /* ++ * GPIOAO_4 is used to turn on the WLAN LED, defaulting to red, ++ * and GPIODV_27 is used to change the color of the WLAN LED. ++ */ ++ wlan-led-red { ++ function = LED_FUNCTION_WLAN; ++ color = ; ++ gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ /* ++ * modprobe ledtrig-netdev ++ * echo netdev > /sys/class/leds/green\:wlan/trigger ++ * echo wlan0 > /sys/class/leds/green\:wlan/device_name ++ * ++ * echo 1 > /sys/class/leds/green\:wlan/link ++ * or ++ * echo 1 > /sys/class/leds/green\:wlan/rx ++ */ ++ wlan-led-green { ++ function = LED_FUNCTION_WLAN; ++ color = ; ++ gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "netdev"; ++ }; ++ }; ++ ++ dio2128: analog-amplifier { ++ compatible = "simple-audio-amplifier"; ++ sound-name-prefix = "AU2"; ++ VCC-supply = <&hdmi_5v>; ++ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cvbs-connector { ++ compatible = "composite-video-connector"; ++ ++ port { ++ cvbs_connector_in: endpoint { ++ remote-endpoint = <&cvbs_vdac_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++ ++ sound { ++ compatible = "amlogic,gx-sound-card"; ++ model = "S905X-P212"; ++ audio-aux-devs = <&dio2128>; ++ audio-widgets = "Line", "Lineout"; ++ audio-routing = "AU2 INL", "ACODEC LOLN", ++ "AU2 INR", "ACODEC LORN", ++ "Lineout", "AU2 OUTL", ++ "Lineout", "AU2 OUTR"; ++ clocks = <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>, ++ <&clkc CLKID_MPLL2>; ++ ++ assigned-clocks = <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>, ++ <&clkc CLKID_MPLL2>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ dai-link-0 { ++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; ++ }; ++ ++ dai-link-1 { ++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; ++ dai-format = "i2s"; ++ mclk-fs = <256>; ++ ++ codec-0 { ++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>; ++ }; ++ ++ codec-1 { ++ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>; ++ }; ++ }; ++ ++ dai-link-2 { ++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>; ++ ++ codec-0 { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ ++ dai-link-3 { ++ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>; ++ ++ codec-0 { ++ sound-dai = <&acodec>; ++ }; ++ }; ++ }; ++}; ++ ++&acodec { ++ AVDD-supply = <&vddio_ao18>; ++ status = "okay"; ++}; ++ ++&aiu { ++ status = "okay"; ++}; ++ ++&brcmf { ++ /delete-property/ compatible; ++}; ++ ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ ++&cvbs_vdac_port { ++ cvbs_vdac_out: endpoint { ++ remote-endpoint = <&cvbs_connector_in>; ++ }; ++}; ++ ++&emmc_pwrseq { ++ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; /* not sure */ ++}; ++ ++&hdmi_5v { ++ /delete-property/ gpio; ++ /delete-property/ enable-active-high; ++}; ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++ hdmi-supply = <&hdmi_5v>; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ ++&sd_emmc_b { ++ max-frequency = <200000000>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ sd-uhs-ddr50; ++}; ++ ++&sd_emmc_c { ++ mmc-hs400-1_8v; ++}; ++ ++&uart_A { ++ status = "disabled"; ++ /delete-node/ bluetooth; ++}; ++ ++&usb { ++ dr_mode = "otg"; ++}; diff --git a/patch/u-boot/v2025.04/board_rock-5t/0000-Prior-Upstream-DT-hacks.patch b/patch/u-boot/v2025.04/board_rock-5t/0000-Prior-Upstream-DT-hacks.patch new file mode 100644 index 000000000..13f0a2939 --- /dev/null +++ b/patch/u-boot/v2025.04/board_rock-5t/0000-Prior-Upstream-DT-hacks.patch @@ -0,0 +1,2871 @@ +From a7dfe216ceb5718a6a02b7f0ac7cedbe33f8923d Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 2 Apr 2025 19:48:45 +0200 +Subject: [PATCH] [HACK] arm64: dts: rockchip: Copy recent DT for Rock 5B+ + +This is a simple copy of the latest RK3588 DT from upstream +Linux including the ROCK 5B+ devicetree, which I'm currently +working on. The goal is a combined U-Boot image, which works +on the ROCK 5B and the ROCK 5B+ and chooses the correct DT +file at runtime. + +Signed-off-by: Sebastian Reichel +--- + .../src/arm64/rockchip/rk3588-base.dtsi | 293 ++++- + .../src/arm64/rockchip/rk3588-extra.dtsi | 189 +++ + .../arm64/rockchip/rk3588-rock-5b-plus.dts | 113 ++ + .../src/arm64/rockchip/rk3588-rock-5b.dts | 875 +------------ + .../src/arm64/rockchip/rk3588-rock-5b.dtsi | 1088 +++++++++++++++++ + 5 files changed, 1671 insertions(+), 887 deletions(-) + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi + +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi +index a337f3fb837..bb77d5987e7 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi ++++ b/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi +@@ -358,11 +358,6 @@ + }; + + firmware { +- optee: optee { +- compatible = "linaro,optee-tz"; +- method = "smc"; +- }; +- + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82000010>; +@@ -382,6 +377,22 @@ + }; + }; + ++ hdmi0_sound: hdmi0-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "hdmi0"; ++ status = "disabled"; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi0>; ++ }; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s5_8ch>; ++ }; ++ }; ++ + pmu-a55 { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; +@@ -549,22 +560,21 @@ + mmu600_pcie: iommu@fc900000 { + compatible = "arm,smmu-v3"; + reg = <0x0 0xfc900000 0x0 0x200000>; +- interrupts = , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ ; + 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 = , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ ; + interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; + #iommu-cells = <1>; + status = "disabled"; +@@ -580,6 +590,16 @@ + reg = <0x0 0xfd58c000 0x0 0x1000>; + }; + ++ mipidcphy0_grf: syscon@fd5e8000 { ++ compatible = "rockchip,rk3588-dcphy-grf", "syscon"; ++ reg = <0x0 0xfd5e8000 0x0 0x4000>; ++ }; ++ ++ mipidcphy1_grf: syscon@fd5ec000 { ++ compatible = "rockchip,rk3588-dcphy-grf", "syscon"; ++ reg = <0x0 0xfd5ec000 0x0 0x4000>; ++ }; ++ + vop_grf: syscon@fd5a4000 { + compatible = "rockchip,rk3588-vop-grf", "syscon"; + reg = <0x0 0xfd5a4000 0x0 0x2000>; +@@ -865,7 +885,7 @@ + }; + }; + /* These power domains are grouped by VD_GPU */ +- power-domain@RK3588_PD_GPU { ++ pd_gpu: power-domain@RK3588_PD_GPU { + reg = ; + clocks = <&cru CLK_GPU>, + <&cru CLK_GPU_COREGROUP>, +@@ -1238,6 +1258,44 @@ + #iommu-cells = <0>; + }; + ++ vdec0: video-decoder@fdc38000 { ++ compatible = "rockchip,rk3588-vdec"; ++ reg = <0x0 0xfdc38000 0x0 0x100>, <0x0 0xfdc38100 0x0 0x500>, <0x0 0xfdc38600 0x0 0x100>; ++ reg-names = "link", "function", "cache"; ++ interrupts = ; ++ clocks = <&cru ACLK_RKVDEC0>, <&cru HCLK_RKVDEC0>, <&cru CLK_RKVDEC0_CA>, ++ <&cru CLK_RKVDEC0_CORE>, <&cru CLK_RKVDEC0_HEVC_CA>; ++ clock-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; ++ assigned-clocks = <&cru ACLK_RKVDEC0>, <&cru CLK_RKVDEC0_CORE>, ++ <&cru CLK_RKVDEC0_CA>, <&cru CLK_RKVDEC0_HEVC_CA>; ++ assigned-clock-rates = <800000000>, <600000000>, ++ <600000000>, <1000000000>; ++ resets = <&cru SRST_A_RKVDEC0>, <&cru SRST_H_RKVDEC0>, <&cru SRST_RKVDEC0_CA>, ++ <&cru SRST_RKVDEC0_CORE>, <&cru SRST_RKVDEC0_HEVC_CA>; ++ reset-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; ++ power-domains = <&power RK3588_PD_RKVDEC0>; ++ sram = <&vdec0_sram>; ++ }; ++ ++ vdec1: video-decoder@fdc40000 { ++ compatible = "rockchip,rk3588-vdec"; ++ reg = <0x0 0xfdc40000 0x0 0x100>, <0x0 0xfdc40100 0x0 0x500>, <0x0 0xfdc40600 0x0 0x100>; ++ reg-names = "link", "function", "cache"; ++ interrupts = ; ++ clocks = <&cru ACLK_RKVDEC1>, <&cru HCLK_RKVDEC1>, <&cru CLK_RKVDEC1_CA>, ++ <&cru CLK_RKVDEC1_CORE>, <&cru CLK_RKVDEC1_HEVC_CA>; ++ clock-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; ++ assigned-clocks = <&cru ACLK_RKVDEC1>, <&cru CLK_RKVDEC1_CORE>, ++ <&cru CLK_RKVDEC1_CA>, <&cru CLK_RKVDEC1_HEVC_CA>; ++ assigned-clock-rates = <800000000>, <600000000>, ++ <600000000>, <1000000000>; ++ resets = <&cru SRST_A_RKVDEC1>, <&cru SRST_H_RKVDEC1>, <&cru SRST_RKVDEC1_CA>, ++ <&cru SRST_RKVDEC1_CORE>, <&cru SRST_RKVDEC1_HEVC_CA>; ++ reset-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; ++ power-domains = <&power RK3588_PD_RKVDEC1>; ++ sram = <&vdec1_sram>; ++ }; ++ + av1d: video-codec@fdc70000 { + compatible = "rockchip,rk3588-av1-vpu"; + reg = <0x0 0xfdc70000 0x0 0x800>; +@@ -1262,16 +1320,30 @@ + <&cru DCLK_VOP1>, + <&cru DCLK_VOP2>, + <&cru DCLK_VOP3>, +- <&cru PCLK_VOP_ROOT>; ++ <&cru PCLK_VOP_ROOT>, ++ <&hdptxphy0>; + clock-names = "aclk", + "hclk", + "dclk_vp0", + "dclk_vp1", + "dclk_vp2", + "dclk_vp3", +- "pclk_vop"; ++ "pclk_vop", ++ "pll_hdmiphy0"; + iommus = <&vop_mmu>; + power-domains = <&power RK3588_PD_VOP>; ++ resets = <&cru SRST_A_VOP>, ++ <&cru SRST_H_VOP>, ++ <&cru SRST_D_VOP0>, ++ <&cru SRST_D_VOP1>, ++ <&cru SRST_D_VOP2>, ++ <&cru SRST_D_VOP3>; ++ reset-names = "aclk", ++ "hclk", ++ "dclk_vp0", ++ "dclk_vp1", ++ "dclk_vp2", ++ "dclk_vp3"; + rockchip,grf = <&sys_grf>; + rockchip,vop-grf = <&vop_grf>; + rockchip,vo1-grf = <&vo1_grf>; +@@ -1319,6 +1391,21 @@ + status = "disabled"; + }; + ++ spdif_tx2: spdif-tx@fddb0000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfddb0000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF2_DP0_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF2>, <&cru HCLK_SPDIF2_DP0>; ++ dma-names = "tx"; ++ dmas = <&dmac1 6>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_VO0>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s4_8ch: i2s@fddc0000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddc0000 0x0 0x1000>; +@@ -1336,6 +1423,21 @@ + status = "disabled"; + }; + ++ spdif_tx3: spdif-tx@fdde0000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfdde0000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF3_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF3>, <&cru HCLK_SPDIF3>; ++ dma-names = "tx"; ++ dmas = <&dmac1 7>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_VO1>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s5_8ch: i2s@fddf0000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddf0000 0x0 0x1000>; +@@ -1370,6 +1472,62 @@ + status = "disabled"; + }; + ++ dsi0: dsi@fde20000 { ++ compatible = "rockchip,rk3588-mipi-dsi2"; ++ reg = <0x0 0xfde20000 0x0 0x10000>; ++ interrupts = ; ++ clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>; ++ clock-names = "pclk", "sys"; ++ resets = <&cru SRST_P_DSIHOST0>; ++ reset-names = "apb"; ++ power-domains = <&power RK3588_PD_VOP>; ++ phys = <&mipidcphy0>; ++ phy-names = "dcphy"; ++ rockchip,grf = <&vop_grf>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsi0_in: port@0 { ++ reg = <0>; ++ }; ++ ++ dsi0_out: port@1 { ++ reg = <1>; ++ }; ++ }; ++ }; ++ ++ dsi1: dsi@fde30000 { ++ compatible = "rockchip,rk3588-mipi-dsi2"; ++ reg = <0x0 0xfde30000 0x0 0x10000>; ++ interrupts = ; ++ clocks = <&cru PCLK_DSIHOST1>, <&cru CLK_DSIHOST1>; ++ clock-names = "pclk", "sys"; ++ resets = <&cru SRST_P_DSIHOST1>; ++ reset-names = "apb"; ++ power-domains = <&power RK3588_PD_VOP>; ++ phys = <&mipidcphy1>; ++ phy-names = "dcphy"; ++ rockchip,grf = <&vop_grf>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsi1_in: port@0 { ++ reg = <0>; ++ }; ++ ++ dsi1_out: port@1 { ++ reg = <1>; ++ }; ++ }; ++ }; ++ + hdmi0: hdmi@fde80000 { + compatible = "rockchip,rk3588-dw-hdmi-qp"; + reg = <0x0 0xfde80000 0x0 0x20000>; +@@ -1386,7 +1544,7 @@ + , + ; + interrupt-names = "avp", "cec", "earc", "main", "hpd"; +- phys = <&hdptxphy_hdmi0>; ++ phys = <&hdptxphy0>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd + &hdmim0_tx0_scl &hdmim0_tx0_sda>; +@@ -1395,6 +1553,7 @@ + reset-names = "ref", "hdp"; + rockchip,grf = <&sys_grf>; + rockchip,vo-grf = <&vo1_grf>; ++ #sound-dai-cells = <0>; + status = "disabled"; + + ports { +@@ -1686,6 +1845,7 @@ + linux,pci-domain = <3>; + max-link-speed = <2>; + msi-map = <0x3000 &its0 0x3000 0x1000>; ++ iommu-map = <0x3000 &mmu600_pcie 0x3000 0x1000>; + num-lanes = <1>; + phys = <&combphy2_psu PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; +@@ -1737,6 +1897,7 @@ + linux,pci-domain = <4>; + max-link-speed = <2>; + msi-map = <0x4000 &its0 0x4000 0x1000>; ++ iommu-map = <0x4000 &mmu600_pcie 0x4000 0x1000>; + num-lanes = <1>; + phys = <&combphy0_ps PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; +@@ -1920,6 +2081,14 @@ + status = "disabled"; + }; + ++ rng@fe378000 { ++ compatible = "rockchip,rk3588-rng"; ++ reg = <0x0 0xfe378000 0x0 0x200>; ++ interrupts = ; ++ clocks = <&scmi_clk SCMI_HCLK_SECURE_NS>; ++ resets = <&scmi_reset 48>; ++ }; ++ + i2s0_8ch: i2s@fe470000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfe470000 0x0 0x1000>; +@@ -2015,12 +2184,47 @@ + status = "disabled"; + }; + ++ spdif_tx0: spdif-tx@fe4e0000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfe4e0000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF0_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF0>, <&cru HCLK_SPDIF0>; ++ dma-names = "tx"; ++ dmas = <&dmac0 5>; ++ interrupts = ; ++ pinctrl-0 = <&spdif0m0_tx>; ++ pinctrl-names = "default"; ++ power-domains = <&power RK3588_PD_AUDIO>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spdif_tx1: spdif-tx@fe4f0000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfe4f0000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF1_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF1>, <&cru HCLK_SPDIF1>; ++ dma-names = "tx"; ++ dmas = <&dmac1 5>; ++ interrupts = ; ++ pinctrl-0 = <&spdif1m0_tx>; ++ pinctrl-names = "default"; ++ power-domains = <&power RK3588_PD_AUDIO>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@fe600000 { + compatible = "arm,gic-v3"; + reg = <0x0 0xfe600000 0 0x10000>, /* GICD */ + <0x0 0xfe680000 0 0x100000>; /* GICR */ + interrupts = ; + interrupt-controller; ++ dma-noncoherent; + mbi-alias = <0x0 0xfe610000>; + mbi-ranges = <424 56>; + msi-controller; +@@ -2032,6 +2236,7 @@ + its0: msi-controller@fe640000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0xfe640000 0x0 0x20000>; ++ dma-noncoherent; + msi-controller; + #msi-cells = <1>; + }; +@@ -2039,6 +2244,7 @@ + its1: msi-controller@fe660000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0xfe660000 0x0 0x20000>; ++ dma-noncoherent; + msi-controller; + #msi-cells = <1>; + }; +@@ -2667,9 +2873,9 @@ + rockchip,hw-tshut-temp = <120000>; + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */ +- pinctrl-0 = <&tsadc_gpio_func>; +- pinctrl-1 = <&tsadc_shut>; +- pinctrl-names = "gpio", "otpout"; ++ pinctrl-0 = <&tsadc_shut_org>; ++ pinctrl-1 = <&tsadc_gpio_func>; ++ pinctrl-names = "default", "sleep"; + #thermal-sensor-cells = <1>; + status = "disabled"; + }; +@@ -2806,11 +3012,12 @@ + #dma-cells = <1>; + }; + +- hdptxphy_hdmi0: phy@fed60000 { ++ hdptxphy0: phy@fed60000 { + compatible = "rockchip,rk3588-hdptx-phy"; + reg = <0x0 0xfed60000 0x0 0x2000>; + clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>; + clock-names = "ref", "apb"; ++ #clock-cells = <0>; + #phy-cells = <0>; + resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>, + <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>, +@@ -2844,6 +3051,38 @@ + status = "disabled"; + }; + ++ mipidcphy0: phy@feda0000 { ++ compatible = "rockchip,rk3588-mipi-dcphy"; ++ reg = <0x0 0xfeda0000 0x0 0x10000>; ++ rockchip,grf = <&mipidcphy0_grf>; ++ clocks = <&cru PCLK_MIPI_DCPHY0>, ++ <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>; ++ clock-names = "pclk", "ref"; ++ resets = <&cru SRST_M_MIPI_DCPHY0>, ++ <&cru SRST_P_MIPI_DCPHY0>, ++ <&cru SRST_P_MIPI_DCPHY0_GRF>, ++ <&cru SRST_S_MIPI_DCPHY0>; ++ reset-names = "m_phy", "apb", "grf", "s_phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ mipidcphy1: phy@fedb0000 { ++ compatible = "rockchip,rk3588-mipi-dcphy"; ++ reg = <0x0 0xfedb0000 0x0 0x10000>; ++ rockchip,grf = <&mipidcphy1_grf>; ++ clocks = <&cru PCLK_MIPI_DCPHY1>, ++ <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>; ++ clock-names = "pclk", "ref"; ++ resets = <&cru SRST_M_MIPI_DCPHY1>, ++ <&cru SRST_P_MIPI_DCPHY1>, ++ <&cru SRST_P_MIPI_DCPHY1_GRF>, ++ <&cru SRST_S_MIPI_DCPHY1>; ++ reset-names = "m_phy", "apb", "grf", "s_phy"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + combphy0_ps: phy@fee00000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x0 0xfee00000 0x0 0x100>; +@@ -2882,6 +3121,16 @@ + ranges = <0x0 0x0 0xff001000 0xef000>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ vdec0_sram: codec-sram@0 { ++ reg = <0x0 0x78000>; ++ pool; ++ }; ++ ++ vdec1_sram: codec-sram@78000 { ++ reg = <0x78000 0x77000>; ++ pool; ++ }; + }; + + pinctrl: pinctrl { +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-extra.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-extra.dtsi +index 0ce0934ec6b..099edb3fd0f 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-extra.dtsi ++++ b/dts/upstream/src/arm64/rockchip/rk3588-extra.dtsi +@@ -7,6 +7,46 @@ + #include "rk3588-extra-pinctrl.dtsi" + + / { ++ hdmi1_sound: hdmi1-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "hdmi1"; ++ status = "disabled"; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi1>; ++ }; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s6_8ch>; ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* ++ * The 4k HDMI capture controller works only with 32bit ++ * phys addresses and doesn't support IOMMU. HDMI RX CMA ++ * must be reserved below 4GB. ++ * The size of 160MB was determined as follows: ++ * (3840 * 2160 pixels) * (4 bytes/pixel) * (2 frames/buffer) / 10^6 = 66MB ++ * To ensure sufficient support for practical use-cases, ++ * we doubled the 66MB value. ++ */ ++ hdmi_receiver_cma: hdmi-receiver-cma { ++ compatible = "shared-dma-pool"; ++ alloc-ranges = <0x0 0x0 0x0 0xffffffff>; ++ size = <0x0 (160 * 0x100000)>; /* 160MiB */ ++ alignment = <0x0 0x40000>; /* 64K */ ++ no-map; ++ status = "disabled"; ++ }; ++ }; ++ + usb_host1_xhci: usb@fc400000 { + compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; + reg = <0x0 0xfc400000 0x0 0x400000>; +@@ -67,6 +107,26 @@ + }; + }; + ++ hdptxphy1_grf: syscon@fd5e4000 { ++ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon"; ++ reg = <0x0 0xfd5e4000 0x0 0x100>; ++ }; ++ ++ spdif_tx5: spdif-tx@fddb8000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfddb8000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF5_DP1_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF5>, <&cru HCLK_SPDIF5_DP1>; ++ dma-names = "tx"; ++ dmas = <&dmac1 22>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_VO0>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s8_8ch: i2s@fddc8000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddc8000 0x0 0x1000>; +@@ -84,6 +144,21 @@ + status = "disabled"; + }; + ++ spdif_tx4: spdif-tx@fdde8000 { ++ compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfdde8000 0x0 0x1000>; ++ assigned-clock-parents = <&cru PLL_AUPLL>; ++ assigned-clocks = <&cru CLK_SPDIF4_SRC>; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF4>, <&cru HCLK_SPDIF4>; ++ dma-names = "tx"; ++ dmas = <&dmac1 8>; ++ interrupts = ; ++ power-domains = <&power RK3588_PD_VO1>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s6_8ch: i2s@fddf4000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x0 0xfddf4000 0x0 0x1000>; +@@ -135,6 +210,79 @@ + status = "disabled"; + }; + ++ hdmi1: hdmi@fdea0000 { ++ compatible = "rockchip,rk3588-dw-hdmi-qp"; ++ reg = <0x0 0xfdea0000 0x0 0x20000>; ++ clocks = <&cru PCLK_HDMITX1>, ++ <&cru CLK_HDMITX1_EARC>, ++ <&cru CLK_HDMITX1_REF>, ++ <&cru MCLK_I2S6_8CH_TX>, ++ <&cru CLK_HDMIHDP1>, ++ <&cru HCLK_VO1>; ++ clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "avp", "cec", "earc", "main", "hpd"; ++ phys = <&hdptxphy1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd ++ &hdmim1_tx1_scl &hdmim1_tx1_sda>; ++ power-domains = <&power RK3588_PD_VO1>; ++ resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>; ++ reset-names = "ref", "hdp"; ++ rockchip,grf = <&sys_grf>; ++ rockchip,vo-grf = <&vo1_grf>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hdmi1_in: port@0 { ++ reg = <0>; ++ }; ++ ++ hdmi1_out: port@1 { ++ reg = <1>; ++ }; ++ }; ++ }; ++ ++ hdmi_receiver: hdmi_receiver@fdee0000 { ++ compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx"; ++ reg = <0x0 0xfdee0000 0x0 0x6000>; ++ interrupts = , ++ , ++ ; ++ interrupt-names = "cec", "hdmi", "dma"; ++ clocks = <&cru ACLK_HDMIRX>, ++ <&cru CLK_HDMIRX_AUD>, ++ <&cru CLK_CR_PARA>, ++ <&cru PCLK_HDMIRX>, ++ <&cru CLK_HDMIRX_REF>, ++ <&cru PCLK_S_HDMIRX>, ++ <&cru HCLK_VO1>; ++ clock-names = "aclk", ++ "audio", ++ "cr_para", ++ "pclk", ++ "ref", ++ "hclk_s_hdmirx", ++ "hclk_vo1"; ++ memory-region = <&hdmi_receiver_cma>; ++ power-domains = <&power RK3588_PD_VO1>; ++ resets = <&cru SRST_A_HDMIRX>, <&cru SRST_P_HDMIRX>, ++ <&cru SRST_HDMIRX_REF>, <&cru SRST_A_HDMIRX_BIU>; ++ reset-names = "axi", "apb", "ref", "biu"; ++ rockchip,grf = <&sys_grf>; ++ rockchip,vo1-grf = <&vo1_grf>; ++ status = "disabled"; ++ }; ++ + pcie3x4: pcie@fe150000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + #address-cells = <3>; +@@ -162,6 +310,7 @@ + linux,pci-domain = <0>; + max-link-speed = <3>; + msi-map = <0x0000 &its1 0x0000 0x1000>; ++ iommu-map = <0x0000 &mmu600_pcie 0x0000 0x1000>; + num-lanes = <4>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +@@ -248,6 +397,7 @@ + linux,pci-domain = <1>; + max-link-speed = <3>; + msi-map = <0x1000 &its1 0x1000 0x1000>; ++ iommu-map = <0x1000 &mmu600_pcie 0x1000 0x1000>; + num-lanes = <2>; + phys = <&pcie30phy>; + phy-names = "pcie-phy"; +@@ -297,6 +447,7 @@ + linux,pci-domain = <2>; + max-link-speed = <2>; + msi-map = <0x2000 &its0 0x2000 0x1000>; ++ iommu-map = <0x2000 &mmu600_pcie 0x2000 0x1000>; + num-lanes = <1>; + phys = <&combphy1_ps PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; +@@ -395,6 +546,23 @@ + }; + }; + ++ hdptxphy1: phy@fed70000 { ++ compatible = "rockchip,rk3588-hdptx-phy"; ++ reg = <0x0 0xfed70000 0x0 0x2000>; ++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>; ++ clock-names = "ref", "apb"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>, ++ <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>, ++ <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>, ++ <&cru SRST_HDPTX1_LCPLL>; ++ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", ++ "lcpll"; ++ rockchip,grf = <&hdptxphy1_grf>; ++ status = "disabled"; ++ }; ++ + usbdp_phy1: phy@fed90000 { + compatible = "rockchip,rk3588-usbdp-phy"; + reg = <0x0 0xfed90000 0x0 0x10000>; +@@ -446,3 +614,24 @@ + status = "disabled"; + }; + }; ++ ++&vop { ++ clocks = <&cru ACLK_VOP>, ++ <&cru HCLK_VOP>, ++ <&cru DCLK_VOP0>, ++ <&cru DCLK_VOP1>, ++ <&cru DCLK_VOP2>, ++ <&cru DCLK_VOP3>, ++ <&cru PCLK_VOP_ROOT>, ++ <&hdptxphy0>, ++ <&hdptxphy1>; ++ clock-names = "aclk", ++ "hclk", ++ "dclk_vp0", ++ "dclk_vp1", ++ "dclk_vp2", ++ "dclk_vp3", ++ "pclk_vop", ++ "pll_hdmiphy0", ++ "pll_hdmiphy1"; ++}; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts +new file mode 100644 +index 00000000000..74c7b6502e4 +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts +@@ -0,0 +1,113 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk3588-rock-5b.dtsi" ++ ++/ { ++ model = "Radxa ROCK 5B+"; ++ compatible = "radxa,rock-5b-plus", "rockchip,rk3588"; ++ ++ rfkill-wwan { ++ compatible = "rfkill-gpio"; ++ label = "rfkill-m2-wwan"; ++ radio-type = "wwan"; ++ shutdown-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ vcc3v3_4g: regulator-vcc3v3-4g { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ /* pinctrl for the GPIO is requested by vcc3v3_pcie2x1l0 */ ++ regulator-name = "vcc3v3_4g"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <50000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_wwan_pwr: regulator-vcc3v3-wwan { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wwan_power_en>; ++ regulator-name = "vcc3v3_wwan_pwr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc3v3_4g>; ++ }; ++}; ++ ++&gpio0 { ++ wwan-disable2-n-hog { ++ gpios = ; ++ output-low; ++ line-name = "M.2 B-key W_DISABLE2#"; ++ gpio-hog; ++ }; ++}; ++ ++&gpio2 { ++ wwan-reset-n-hog { ++ gpios = ; ++ output-low; ++ line-name = "M.2 B-key RESET#"; ++ gpio-hog; ++ }; ++ ++ wwan-wake-n-hog { ++ gpios = ; ++ input; ++ line-name = "M.2 B-key WoWWAN#"; ++ gpio-hog; ++ }; ++}; ++ ++&pcie30phy { ++ data-lanes = <1 1 2 2>; ++}; ++ ++&pcie3x2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie3x2_rst>; ++ reset-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pcie30>; ++ status = "okay"; ++}; ++ ++&pcie3x4 { ++ num-lanes = <2>; ++}; ++ ++&pinctrl { ++ wwan { ++ wwan_power_en: wwan-pwr-en { ++ rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie3 { ++ pcie3x2_rst: pcie3x2-rst { ++ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&vcc5v0_host { ++ enable-active-high; ++ gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++}; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts +index d597112f1d5..9407a7c9910 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts +@@ -2,462 +2,11 @@ + + /dts-v1/; + +-#include +-#include +-#include +-#include "rk3588.dtsi" ++#include "rk3588-rock-5b.dtsi" + + / { + model = "Radxa ROCK 5B"; + compatible = "radxa,rock-5b", "rockchip,rk3588"; +- +- aliases { +- mmc0 = &sdhci; +- mmc1 = &sdmmc; +- mmc2 = &sdio; +- }; +- +- chosen { +- stdout-path = "serial2:1500000n8"; +- }; +- +- analog-sound { +- compatible = "audio-graph-card"; +- label = "rk3588-es8316"; +- +- widgets = "Microphone", "Mic Jack", +- "Headphone", "Headphones"; +- +- routing = "MIC2", "Mic Jack", +- "Headphones", "HPOL", +- "Headphones", "HPOR"; +- +- dais = <&i2s0_8ch_p0>; +- hp-det-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&hp_detect>; +- }; +- +- hdmi0-con { +- compatible = "hdmi-connector"; +- type = "a"; +- +- port { +- hdmi0_con_in: endpoint { +- remote-endpoint = <&hdmi0_out_con>; +- }; +- }; +- }; +- +- leds { +- compatible = "gpio-leds"; +- pinctrl-names = "default"; +- pinctrl-0 = <&led_rgb_b>; +- +- led_rgb_b { +- function = LED_FUNCTION_STATUS; +- color = ; +- gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "heartbeat"; +- }; +- }; +- +- fan: pwm-fan { +- compatible = "pwm-fan"; +- cooling-levels = <0 120 150 180 210 240 255>; +- fan-supply = <&vcc5v0_sys>; +- pwms = <&pwm1 0 50000 0>; +- #cooling-cells = <2>; +- }; +- +- rfkill { +- compatible = "rfkill-gpio"; +- label = "rfkill-m2-wlan"; +- radio-type = "wlan"; +- shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; +- }; +- +- rfkill-bt { +- compatible = "rfkill-gpio"; +- label = "rfkill-m2-bt"; +- radio-type = "bluetooth"; +- shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; +- }; +- +- vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie2_0_vcc3v3_en>; +- regulator-name = "vcc3v3_pcie2x1l0"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- startup-delay-us = <50000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc3v3_pcie2x1l2: regulator-vcc3v3-pcie2x1l2 { +- 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: regulator-vcc3v3-pcie30 { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie3_vcc3v3_en>; +- regulator-name = "vcc3v3_pcie30"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- startup-delay-us = <5000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc5v0_host: regulator-vcc5v0-host { +- 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: regulator-vcc5v0-sys { +- 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: regulator-vcc-1v1-nldo-s3 { +- 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"; +-}; +- +-&hdmi0 { +- status = "okay"; +-}; +- +-&hdmi0_in { +- hdmi0_in_vp0: endpoint { +- remote-endpoint = <&vp0_out_hdmi0>; +- }; +-}; +- +-&hdmi0_out { +- hdmi0_out_con: endpoint { +- remote-endpoint = <&hdmi0_con_in>; +- }; +-}; +- +-&hdptxphy_hdmi0 { +- 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>; +- #clock-cells = <0>; +- clock-output-names = "hym8563"; +- pinctrl-names = "default"; +- pinctrl-0 = <&hym8563_int>; +- interrupt-parent = <&gpio0>; +- interrupts = ; +- wakeup-source; +- }; +-}; +- +-&i2c7 { +- status = "okay"; +- +- es8316: audio-codec@11 { +- compatible = "everest,es8316"; +- reg = <0x11>; +- clocks = <&cru I2S0_8CH_MCLKOUT>; +- clock-names = "mclk"; +- assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; +- assigned-clock-rates = <12288000>; +- #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>; +- }; +- }; +-}; +- +-&package_thermal { +- polling-delay = <1000>; +- +- trips { +- package_fan0: package-fan0 { +- temperature = <55000>; +- hysteresis = <2000>; +- type = "active"; +- }; +- +- package_fan1: package-fan1 { +- temperature = <65000>; +- hysteresis = <2000>; +- type = "active"; +- }; +- }; +- +- cooling-maps { +- map0 { +- trip = <&package_fan0>; +- cooling-device = <&fan THERMAL_NO_LIMIT 1>; +- }; +- +- map1 { +- trip = <&package_fan1>; +- cooling-device = <&fan 2 THERMAL_NO_LIMIT>; +- }; +- }; +-}; +- +-&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_PB0 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 { +- hym8563 { +- hym8563_int: hym8563-int { +- rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- +- leds { +- led_rgb_b: led-rgb-b { +- 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>; +- }; +- }; +- +- pcie2 { +- pcie2_0_rst: pcie2-0-rst { +- rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- +- pcie2_0_vcc3v3_en: pcie2-0-vcc-en { +- rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- +- pcie2_2_rst: pcie2-2-rst { +- rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- +- pcie3 { +- pcie3_rst: pcie3-rst { +- rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- +- pcie3_vcc3v3_en: pcie3-vcc3v3-en { +- rockchip,pins = <1 RK_PA4 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-hs400-1_8v; +- mmc-hs400-enhanced-strobe; +- status = "okay"; +-}; +- +-&sdmmc { +- max-frequency = <200000000>; +- no-sdio; +- no-mmc; +- bus-width = <4>; +- cap-mmc-highspeed; +- cap-sd-highspeed; +- cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; +- disable-wp; +- sd-uhs-sdr104; +- vmmc-supply = <&vcc_3v3_s3>; +- vqmmc-supply = <&vccio_sd_s0>; +- status = "okay"; + }; + + &sdio { +@@ -481,427 +30,23 @@ + status = "okay"; + }; + +-&sfc { +- pinctrl-names = "default"; +- pinctrl-0 = <&fspim2_pins>; +- status = "okay"; +- +- flash@0 { +- compatible = "jedec,spi-nor"; +- reg = <0>; +- spi-max-frequency = <104000000>; +- spi-rx-bus-width = <4>; +- spi-tx-bus-width = <1>; +- }; +-}; +- + &uart6 { + pinctrl-names = "default"; + pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>; + 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; +- }; +- }; ++&pinctrl { ++ usb { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + }; + +-&tsadc { +- status = "okay"; +-}; +- +-&uart2 { +- pinctrl-0 = <&uart2m0_xfer>; +- status = "okay"; +-}; +- +-&u2phy1 { +- status = "okay"; +-}; +- +-&u2phy1_otg { +- status = "okay"; +-}; +- +-&u2phy2 { +- status = "okay"; +-}; +- +-&u2phy2_host { +- /* connected to USB hub, which is powered by vcc5v0_sys */ +- phy-supply = <&vcc5v0_sys>; +- status = "okay"; +-}; +- +-&u2phy3 { +- status = "okay"; +-}; +- +-&u2phy3_host { +- phy-supply = <&vcc5v0_host>; +- status = "okay"; +-}; +- +-&usbdp_phy1 { +- status = "okay"; +-}; +- +-&usb_host0_ehci { +- status = "okay"; +-}; +- +-&usb_host0_ohci { +- status = "okay"; +-}; +- +-&usb_host1_ehci { +- status = "okay"; +-}; +- +-&usb_host1_ohci { +- status = "okay"; +-}; +- +-&usb_host1_xhci { +- dr_mode = "host"; +- status = "okay"; +-}; +- +-&usb_host2_xhci { +- status = "okay"; +-}; +- +-&vop_mmu { +- status = "okay"; +-}; +- +-&vop { +- status = "okay"; +-}; +- +-&vp0 { +- vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { +- reg = ; +- remote-endpoint = <&hdmi0_in_vp0>; +- }; ++&vcc5v0_host { ++ enable-active-high; ++ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; + }; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi +new file mode 100644 +index 00000000000..4bdc16ea36a +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi +@@ -0,0 +1,1088 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "rk3588.dtsi" ++ ++/ { ++ aliases { ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc; ++ mmc2 = &sdio; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ analog-sound { ++ compatible = "audio-graph-card"; ++ label = "rk3588-es8316"; ++ ++ widgets = "Microphone", "Mic Jack", ++ "Headphone", "Headphones"; ++ ++ routing = "MIC2", "Mic Jack", ++ "Headphones", "HPOL", ++ "Headphones", "HPOR"; ++ ++ dais = <&i2s0_8ch_p0>; ++ hp-det-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_detect>; ++ }; ++ ++ hdmi0-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi0_con_in: endpoint { ++ remote-endpoint = <&hdmi0_out_con>; ++ }; ++ }; ++ }; ++ ++ hdmi1-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi1_con_in: endpoint { ++ remote-endpoint = <&hdmi1_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_rgb_b>; ++ ++ led_rgb_b { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ fan: pwm-fan { ++ compatible = "pwm-fan"; ++ cooling-levels = <0 120 150 180 210 240 255>; ++ fan-supply = <&vcc5v0_sys>; ++ pwms = <&pwm1 0 50000 0>; ++ #cooling-cells = <2>; ++ }; ++ ++ rfkill { ++ compatible = "rfkill-gpio"; ++ label = "rfkill-m2-wlan"; ++ radio-type = "wlan"; ++ shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ rfkill-bt { ++ compatible = "rfkill-gpio"; ++ label = "rfkill-m2-bt"; ++ radio-type = "bluetooth"; ++ shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ ++ vbus5v0_typec: vbus5v0-typec { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vbus5v0_typec_en>; ++ regulator-name = "vbus5v0_typec"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc12v_dcin: regulator-vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_0_vcc3v3_en>; ++ regulator-name = "vcc3v3_pcie2x1l0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <50000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pcie2x1l2: regulator-vcc3v3-pcie2x1l2 { ++ 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: regulator-vcc3v3-pcie30 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie3_vcc3v3_en>; ++ regulator-name = "vcc3v3_pcie30"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <5000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_host: regulator-vcc5v0-host { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_host"; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { ++ 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"; ++}; ++ ++&hdmi0 { ++ status = "okay"; ++}; ++ ++&hdmi0_in { ++ hdmi0_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi0>; ++ }; ++}; ++ ++&hdmi0_out { ++ hdmi0_out_con: endpoint { ++ remote-endpoint = <&hdmi0_con_in>; ++ }; ++}; ++ ++&hdmi0_sound { ++ status = "okay"; ++}; ++ ++&hdmi1 { ++ pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd ++ &hdmim1_tx1_scl &hdmim1_tx1_sda>; ++ status = "okay"; ++}; ++ ++&hdmi1_in { ++ hdmi1_in_vp1: endpoint { ++ remote-endpoint = <&vp1_out_hdmi1>; ++ }; ++}; ++ ++&hdmi1_out { ++ hdmi1_out_con: endpoint { ++ remote-endpoint = <&hdmi1_con_in>; ++ }; ++}; ++ ++&hdmi1_sound { ++ status = "okay"; ++}; ++ ++&hdmi_receiver_cma { ++ status = "okay"; ++}; ++ ++&hdmi_receiver { ++ hpd-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&hdptxphy0 { ++ status = "okay"; ++}; ++ ++&hdptxphy1 { ++ 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; ++ }; ++ }; ++}; ++ ++&i2c3 { ++ status = "okay"; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4m1_xfer>; ++ status = "okay"; ++ ++ usbc0: usb-typec@22 { ++ compatible = "fcs,fusb302"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usbc0_int>; ++ vbus-supply = <&vcc12v_dcin>; ++ /* ++ * When the board is starting to send power-delivery messages ++ * too late (5 seconds according to the specification), the ++ * power-supply reacts with a hard-reset. That removes the ++ * power from VBUS for some time, which resets te whole board. ++ */ ++ status = "fail"; ++ ++ usb_con: connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ data-role = "dual"; ++ power-role = "sink"; ++ try-power-role = "sink"; ++ op-sink-microwatt = <1000000>; ++ sink-pdos = ++ , ++ ; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ usbc0_role_sw: endpoint { ++ remote-endpoint = <&dwc3_0_role_switch>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ usbc0_orien_sw: endpoint { ++ remote-endpoint = <&usbdp_phy0_orientation_switch>; ++ }; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ dp_altmode_mux: endpoint { ++ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c6 { ++ status = "okay"; ++ ++ hym8563: rtc@51 { ++ compatible = "haoyu,hym8563"; ++ reg = <0x51>; ++ #clock-cells = <0>; ++ clock-output-names = "hym8563"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hym8563_int>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ wakeup-source; ++ }; ++}; ++ ++&i2c7 { ++ status = "okay"; ++ ++ es8316: audio-codec@11 { ++ compatible = "everest,es8316"; ++ reg = <0x11>; ++ clocks = <&cru I2S0_8CH_MCLKOUT>; ++ clock-names = "mclk"; ++ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; ++ assigned-clock-rates = <12288000>; ++ #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>; ++ }; ++ }; ++}; ++ ++&i2s5_8ch { ++ status = "okay"; ++}; ++ ++&i2s6_8ch { ++ status = "okay"; ++}; ++ ++&package_thermal { ++ polling-delay = <1000>; ++ ++ trips { ++ package_fan0: package-fan0 { ++ temperature = <55000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ ++ package_fan1: package-fan1 { ++ temperature = <65000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&package_fan0>; ++ cooling-device = <&fan THERMAL_NO_LIMIT 1>; ++ }; ++ ++ map1 { ++ trip = <&package_fan1>; ++ cooling-device = <&fan 2 THERMAL_NO_LIMIT>; ++ }; ++ }; ++}; ++ ++&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_PB0 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"; ++}; ++ ++&pd_gpu { ++ domain-supply = <&vdd_gpu_s0>; ++}; ++ ++&pinctrl { ++ hdmirx { ++ hdmirx_hpd: hdmirx-5v-detection { ++ rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ hym8563 { ++ hym8563_int: hym8563-int { ++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ leds { ++ led_rgb_b: led-rgb-b { ++ 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>; ++ }; ++ }; ++ ++ pcie2 { ++ pcie2_0_rst: pcie2-0-rst { ++ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie2_0_vcc3v3_en: pcie2-0-vcc-en { ++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie2_2_rst: pcie2-2-rst { ++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie3 { ++ pcie3_rst: pcie3-rst { ++ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie3_vcc3v3_en: pcie3-vcc3v3-en { ++ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ usbc0_int: usbc0-int { ++ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vbus5v0_typec_en: vbus5v0-typec-en { ++ rockchip,pins = <2 RK_PB6 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; ++ max-frequency = <150000000>; ++ mmc-hs200-1_8v; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ max-frequency = <200000000>; ++ no-sdio; ++ no-mmc; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_3v3_s3>; ++ vqmmc-supply = <&vccio_sd_s0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fspim2_pins>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <104000000>; ++ spi-rx-bus-width = <4>; ++ spi-tx-bus-width = <1>; ++ }; ++}; ++ ++&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"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ status = "okay"; ++}; ++ ++&u2phy2 { ++ status = "okay"; ++}; ++ ++&u2phy2_host { ++ /* connected to USB hub, which is powered by vcc5v0_sys */ ++ phy-supply = <&vcc5v0_sys>; ++ status = "okay"; ++}; ++ ++&u2phy3 { ++ status = "okay"; ++}; ++ ++&u2phy3_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usbdp_phy1 { ++ 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>; ++ }; ++ }; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ usb-role-switch; ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dwc3_0_role_switch: endpoint { ++ remote-endpoint = <&usbc0_role_sw>; ++ }; ++ }; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host2_xhci { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi0_in_vp0>; ++ }; ++}; ++ ++&vp1 { ++ vp1_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { ++ reg = ; ++ remote-endpoint = <&hdmi1_in_vp1>; ++ }; ++}; +-- +GitLab diff --git a/patch/u-boot/v2025.04/board_rock-5t/0001-Add-Rock5T-dt-modifications.patch b/patch/u-boot/v2025.04/board_rock-5t/0001-Add-Rock5T-dt-modifications.patch new file mode 100644 index 000000000..580c18c9b --- /dev/null +++ b/patch/u-boot/v2025.04/board_rock-5t/0001-Add-Rock5T-dt-modifications.patch @@ -0,0 +1,2176 @@ +From ffa17de2c8f161181e22d42930aacaa8fbc490e0 Mon Sep 17 00:00:00 2001 +From: Nicolas Frattaroli +Date: Fri, 9 May 2025 11:34:30 +0200 +Subject: [PATCH] [HACK] add upstream DTS modifications for ROCK 5T + +Signed-off-by: Nicolas Frattaroli +--- + .../arm64/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 1012 ++++++++++++++++ + .../arm64/rockchip/rk3588-rock-5b-plus.dts | 16 + + .../src/arm64/rockchip/rk3588-rock-5b.dts | 12 + + .../src/arm64/rockchip/rk3588-rock-5b.dtsi | 1018 +---------------- + 4 files changed, 1048 insertions(+), 1010 deletions(-) + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-rock-5b-5bp-5t.dtsi + +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-5bp-5t.dtsi +new file mode 100644 +index 00000000000..f086f0ff9f6 +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-5bp-5t.dtsi +@@ -0,0 +1,1012 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "rk3588.dtsi" ++ ++/ { ++ aliases { ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc; ++ mmc2 = &sdio; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ hdmi0-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi0_con_in: endpoint { ++ remote-endpoint = <&hdmi0_out_con>; ++ }; ++ }; ++ }; ++ ++ hdmi1-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi1_con_in: endpoint { ++ remote-endpoint = <&hdmi1_out_con>; ++ }; ++ }; ++ }; ++ ++ fan: pwm-fan { ++ compatible = "pwm-fan"; ++ cooling-levels = <0 120 150 180 210 240 255>; ++ fan-supply = <&vcc5v0_sys>; ++ pwms = <&pwm1 0 50000 0>; ++ #cooling-cells = <2>; ++ }; ++ ++ rfkill-bt { ++ compatible = "rfkill-gpio"; ++ label = "rfkill-m2-bt"; ++ radio-type = "bluetooth"; ++ shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ vcc12v_dcin: regulator-vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc3v3_pcie2x1l0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <50000>; ++ vin-supply = <&vcc5v0_sys>; ++ status = "disabled"; ++ }; ++ ++ vcc3v3_pcie2x1l2: regulator-vcc3v3-pcie2x1l2 { ++ 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: regulator-vcc3v3-pcie30 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie3_vcc3v3_en>; ++ regulator-name = "vcc3v3_pcie30"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <5000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_host: regulator-vcc5v0-host { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_host"; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vbus5v0_typec: vbus5v0-typec { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vbus5v0_typec_en>; ++ regulator-name = "vbus5v0_typec"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { ++ 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"; ++}; ++ ++&hdmi0 { ++ status = "okay"; ++}; ++ ++&hdmi0_in { ++ hdmi0_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi0>; ++ }; ++}; ++ ++&hdmi0_out { ++ hdmi0_out_con: endpoint { ++ remote-endpoint = <&hdmi0_con_in>; ++ }; ++}; ++ ++&hdmi0_sound { ++ status = "okay"; ++}; ++ ++&hdmi1 { ++ pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd ++ &hdmim1_tx1_scl &hdmim1_tx1_sda>; ++ status = "okay"; ++}; ++ ++&hdmi1_in { ++ hdmi1_in_vp1: endpoint { ++ remote-endpoint = <&vp1_out_hdmi1>; ++ }; ++}; ++ ++&hdmi1_out { ++ hdmi1_out_con: endpoint { ++ remote-endpoint = <&hdmi1_con_in>; ++ }; ++}; ++ ++&hdmi1_sound { ++ status = "okay"; ++}; ++ ++&hdmi_receiver_cma { ++ status = "okay"; ++}; ++ ++&hdmi_receiver { ++ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; ++ pinctrl-names = "default"; ++}; ++ ++&hdptxphy0 { ++ status = "okay"; ++}; ++ ++&hdptxphy1 { ++ 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; ++ }; ++ }; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4m1_xfer>; ++ status = "okay"; ++ ++ usbc0: usb-typec@22 { ++ compatible = "fcs,fusb302"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usbc0_int>; ++ vbus-supply = <&vbus5v0_typec>; ++ /* ++ * When the board is starting to send power-delivery messages ++ * too late (5 seconds according to the specification), the ++ * power-supply reacts with a hard-reset. That removes the ++ * power from VBUS for some time, which resets te whole board. ++ */ ++ status = "fail"; ++ ++ usb_con: connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ data-role = "dual"; ++ power-role = "sink"; ++ try-power-role = "sink"; ++ op-sink-microwatt = <1000000>; ++ sink-pdos = ++ , ++ ; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ usbc0_role_sw: endpoint { ++ remote-endpoint = <&dwc3_0_role_switch>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ usbc0_orien_sw: endpoint { ++ remote-endpoint = <&usbdp_phy0_orientation_switch>; ++ }; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ dp_altmode_mux: endpoint { ++ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c6 { ++ status = "okay"; ++ ++ hym8563: rtc@51 { ++ compatible = "haoyu,hym8563"; ++ reg = <0x51>; ++ #clock-cells = <0>; ++ clock-output-names = "hym8563"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hym8563_int>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ wakeup-source; ++ }; ++}; ++ ++&i2c7 { ++ status = "okay"; ++ ++ es8316: audio-codec@11 { ++ compatible = "everest,es8316"; ++ reg = <0x11>; ++ clocks = <&cru I2S0_8CH_MCLKOUT>; ++ clock-names = "mclk"; ++ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; ++ assigned-clock-rates = <12288000>; ++ #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>; ++ }; ++ }; ++}; ++ ++&i2s5_8ch { ++ status = "okay"; ++}; ++ ++&i2s6_8ch { ++ status = "okay"; ++}; ++ ++&package_thermal { ++ polling-delay = <1000>; ++ ++ trips { ++ package_fan0: package-fan0 { ++ temperature = <55000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ ++ package_fan1: package-fan1 { ++ temperature = <65000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&package_fan0>; ++ cooling-device = <&fan THERMAL_NO_LIMIT 1>; ++ }; ++ ++ map1 { ++ trip = <&package_fan1>; ++ cooling-device = <&fan 2 THERMAL_NO_LIMIT>; ++ }; ++ }; ++}; ++ ++&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_PB0 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"; ++}; ++ ++&pd_gpu { ++ domain-supply = <&vdd_gpu_s0>; ++}; ++ ++&pinctrl { ++ hym8563 { ++ hym8563_int: hym8563-int { ++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ 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_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie3 { ++ pcie3_rst: pcie3-rst { ++ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie3_vcc3v3_en: pcie3-vcc3v3-en { ++ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ usbc0_int: usbc0-int { ++ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vbus5v0_typec_en: vbus5v0-typec-en { ++ rockchip,pins = <2 RK_PB6 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-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ max-frequency = <200000000>; ++ no-sdio; ++ no-mmc; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_3v3_s3>; ++ vqmmc-supply = <&vccio_sd_s0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fspim2_pins>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <104000000>; ++ spi-rx-bus-width = <4>; ++ spi-tx-bus-width = <1>; ++ vcc-supply = <&vcc_3v3_s3>; ++ }; ++}; ++ ++&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"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ status = "okay"; ++}; ++ ++&u2phy2 { ++ status = "okay"; ++}; ++ ++&u2phy2_host { ++ /* connected to USB hub, which is powered by vcc5v0_sys */ ++ phy-supply = <&vcc5v0_sys>; ++ status = "okay"; ++}; ++ ++&u2phy3 { ++ status = "okay"; ++}; ++ ++&u2phy3_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usbdp_phy0 { ++ mode-switch; ++ orientation-switch; ++ 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 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ 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_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi0_in_vp0>; ++ }; ++}; ++ ++&vp1 { ++ vp1_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { ++ reg = ; ++ remote-endpoint = <&hdmi1_in_vp1>; ++ }; ++}; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts +index 74c7b6502e4..4096cd853f9 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b-plus.dts +@@ -99,12 +99,28 @@ + }; + + usb { ++ usbc_sbu_dc: usbc-sbu-dc { ++ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>, ++ <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + }; + ++&usbc0 { ++ status = "okay"; ++}; ++ ++&usbdp_phy0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usbc_sbu_dc>; ++ sbu1-dc-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; ++ sbu2-dc-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; ++}; ++ + &vcc5v0_host { + enable-active-high; + gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts +index 9407a7c9910..ca354a1b0e6 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dts +@@ -36,8 +36,20 @@ + status = "okay"; + }; + ++&usbdp_phy0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usbc_sbu_dc>; ++ sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; ++ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; ++}; ++ + &pinctrl { + usb { ++ usbc_sbu_dc: usbc-sbu-dc { ++ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>, ++ <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi +index 4bdc16ea36a..e5c474e4d02 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5b.dtsi +@@ -2,23 +2,9 @@ + + /dts-v1/; + +-#include +-#include +-#include +-#include +-#include "rk3588.dtsi" ++#include "rk3588-rock-5b-5bp-5t.dtsi" + + / { +- aliases { +- mmc0 = &sdhci; +- mmc1 = &sdmmc; +- mmc2 = &sdio; +- }; +- +- chosen { +- stdout-path = "serial2:1500000n8"; +- }; +- + analog-sound { + compatible = "audio-graph-card"; + label = "rk3588-es8316"; +@@ -36,28 +22,6 @@ + pinctrl-0 = <&hp_detect>; + }; + +- hdmi0-con { +- compatible = "hdmi-connector"; +- type = "a"; +- +- port { +- hdmi0_con_in: endpoint { +- remote-endpoint = <&hdmi0_out_con>; +- }; +- }; +- }; +- +- hdmi1-con { +- compatible = "hdmi-connector"; +- type = "a"; +- +- port { +- hdmi1_con_in: endpoint { +- remote-endpoint = <&hdmi1_out_con>; +- }; +- }; +- }; +- + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; +@@ -71,457 +35,19 @@ + }; + }; + +- fan: pwm-fan { +- compatible = "pwm-fan"; +- cooling-levels = <0 120 150 180 210 240 255>; +- fan-supply = <&vcc5v0_sys>; +- pwms = <&pwm1 0 50000 0>; +- #cooling-cells = <2>; +- }; +- + rfkill { + compatible = "rfkill-gpio"; + label = "rfkill-m2-wlan"; + radio-type = "wlan"; + shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; + }; +- +- rfkill-bt { +- compatible = "rfkill-gpio"; +- label = "rfkill-m2-bt"; +- radio-type = "bluetooth"; +- shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; +- }; +- +- +- vbus5v0_typec: vbus5v0-typec { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpio = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&vbus5v0_typec_en>; +- regulator-name = "vbus5v0_typec"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc12v_dcin: regulator-vcc12v-dcin { +- compatible = "regulator-fixed"; +- regulator-name = "vcc12v_dcin"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <12000000>; +- regulator-max-microvolt = <12000000>; +- }; +- +- vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie2_0_vcc3v3_en>; +- regulator-name = "vcc3v3_pcie2x1l0"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- startup-delay-us = <50000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc3v3_pcie2x1l2: regulator-vcc3v3-pcie2x1l2 { +- 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: regulator-vcc3v3-pcie30 { +- compatible = "regulator-fixed"; +- enable-active-high; +- gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie3_vcc3v3_en>; +- regulator-name = "vcc3v3_pcie30"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- startup-delay-us = <5000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc5v0_host: regulator-vcc5v0-host { +- compatible = "regulator-fixed"; +- regulator-name = "vcc5v0_host"; +- regulator-boot-on; +- regulator-always-on; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- vin-supply = <&vcc5v0_sys>; +- }; +- +- vcc5v0_sys: regulator-vcc5v0-sys { +- compatible = "regulator-fixed"; +- regulator-name = "vcc5v0_sys"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- vin-supply = <&vcc12v_dcin>; +- }; +- +- vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { +- 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"; +-}; +- +-&hdmi0 { +- status = "okay"; +-}; +- +-&hdmi0_in { +- hdmi0_in_vp0: endpoint { +- remote-endpoint = <&vp0_out_hdmi0>; +- }; +-}; +- +-&hdmi0_out { +- hdmi0_out_con: endpoint { +- remote-endpoint = <&hdmi0_con_in>; +- }; +-}; +- +-&hdmi0_sound { +- status = "okay"; +-}; +- +-&hdmi1 { +- pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd +- &hdmim1_tx1_scl &hdmim1_tx1_sda>; +- status = "okay"; +-}; +- +-&hdmi1_in { +- hdmi1_in_vp1: endpoint { +- remote-endpoint = <&vp1_out_hdmi1>; +- }; +-}; +- +-&hdmi1_out { +- hdmi1_out_con: endpoint { +- remote-endpoint = <&hdmi1_con_in>; +- }; +-}; +- +-&hdmi1_sound { +- status = "okay"; +-}; +- +-&hdmi_receiver_cma { +- status = "okay"; + }; + + &hdmi_receiver { + hpd-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>; +- pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&hdptxphy0 { +- status = "okay"; +-}; +- +-&hdptxphy1 { +- 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; +- }; +- }; +-}; +- +-&i2c3 { +- status = "okay"; +-}; +- +-&i2c4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c4m1_xfer>; +- status = "okay"; +- +- usbc0: usb-typec@22 { +- compatible = "fcs,fusb302"; +- reg = <0x22>; +- interrupt-parent = <&gpio3>; +- interrupts = ; +- pinctrl-names = "default"; +- pinctrl-0 = <&usbc0_int>; +- vbus-supply = <&vcc12v_dcin>; +- /* +- * When the board is starting to send power-delivery messages +- * too late (5 seconds according to the specification), the +- * power-supply reacts with a hard-reset. That removes the +- * power from VBUS for some time, which resets te whole board. +- */ +- status = "fail"; +- +- usb_con: connector { +- compatible = "usb-c-connector"; +- label = "USB-C"; +- data-role = "dual"; +- power-role = "sink"; +- try-power-role = "sink"; +- op-sink-microwatt = <1000000>; +- sink-pdos = +- , +- ; +- +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- usbc0_role_sw: endpoint { +- remote-endpoint = <&dwc3_0_role_switch>; +- }; +- }; +- +- port@1 { +- reg = <1>; +- usbc0_orien_sw: endpoint { +- remote-endpoint = <&usbdp_phy0_orientation_switch>; +- }; +- }; +- +- port@2 { +- reg = <2>; +- dp_altmode_mux: endpoint { +- remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; +- }; +- }; +- }; +- }; +- }; +-}; +- +-&i2c6 { +- status = "okay"; +- +- hym8563: rtc@51 { +- compatible = "haoyu,hym8563"; +- reg = <0x51>; +- #clock-cells = <0>; +- clock-output-names = "hym8563"; +- pinctrl-names = "default"; +- pinctrl-0 = <&hym8563_int>; +- interrupt-parent = <&gpio0>; +- interrupts = ; +- wakeup-source; +- }; +-}; +- +-&i2c7 { +- status = "okay"; +- +- es8316: audio-codec@11 { +- compatible = "everest,es8316"; +- reg = <0x11>; +- clocks = <&cru I2S0_8CH_MCLKOUT>; +- clock-names = "mclk"; +- assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; +- assigned-clock-rates = <12288000>; +- #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>; +- }; +- }; +-}; +- +-&i2s5_8ch { +- status = "okay"; +-}; +- +-&i2s6_8ch { +- status = "okay"; +-}; +- +-&package_thermal { +- polling-delay = <1000>; +- +- trips { +- package_fan0: package-fan0 { +- temperature = <55000>; +- hysteresis = <2000>; +- type = "active"; +- }; +- +- package_fan1: package-fan1 { +- temperature = <65000>; +- hysteresis = <2000>; +- type = "active"; +- }; +- }; +- +- cooling-maps { +- map0 { +- trip = <&package_fan0>; +- cooling-device = <&fan THERMAL_NO_LIMIT 1>; +- }; +- +- map1 { +- trip = <&package_fan1>; +- cooling-device = <&fan 2 THERMAL_NO_LIMIT>; +- }; +- }; +-}; +- +-&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_PB0 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"; + }; + +-&pd_gpu { +- domain-supply = <&vdd_gpu_s0>; +-}; +- + &pinctrl { + hdmirx { + hdmirx_hpd: hdmirx-5v-detection { +@@ -529,560 +55,32 @@ + }; + }; + +- hym8563 { +- hym8563_int: hym8563-int { +- rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- + leds { + led_rgb_b: led-rgb-b { + 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>; +- }; +- }; +- + pcie2 { +- pcie2_0_rst: pcie2-0-rst { +- rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- + pcie2_0_vcc3v3_en: pcie2-0-vcc-en { + rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; +- +- pcie2_2_rst: pcie2-2-rst { +- rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; +- }; + }; + +- pcie3 { +- pcie3_rst: pcie3-rst { +- rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- +- pcie3_vcc3v3_en: pcie3-vcc3v3-en { +- rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- +- usb { +- usbc0_int: usbc0-int { +- rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- +- vbus5v0_typec_en: vbus5v0-typec-en { +- rockchip,pins = <2 RK_PB6 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; +- max-frequency = <150000000>; +- mmc-hs200-1_8v; +- status = "okay"; +-}; +- +-&sdmmc { +- max-frequency = <200000000>; +- no-sdio; +- no-mmc; +- bus-width = <4>; +- cap-mmc-highspeed; +- cap-sd-highspeed; +- cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; +- disable-wp; +- sd-uhs-sdr104; +- vmmc-supply = <&vcc_3v3_s3>; +- vqmmc-supply = <&vccio_sd_s0>; +- status = "okay"; +-}; +- +-&sfc { +- pinctrl-names = "default"; +- pinctrl-0 = <&fspim2_pins>; +- status = "okay"; +- +- flash@0 { +- compatible = "jedec,spi-nor"; +- reg = <0>; +- spi-max-frequency = <104000000>; +- spi-rx-bus-width = <4>; +- spi-tx-bus-width = <1>; +- }; +-}; +- +-&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"; +-}; +- +-&u2phy0 { +- status = "okay"; +-}; +- +-&u2phy0_otg { +- status = "okay"; +-}; +- +-&u2phy1 { +- status = "okay"; +-}; +- +-&u2phy1_otg { +- status = "okay"; +-}; +- +-&u2phy2 { +- status = "okay"; +-}; +- +-&u2phy2_host { +- /* connected to USB hub, which is powered by vcc5v0_sys */ +- phy-supply = <&vcc5v0_sys>; +- status = "okay"; +-}; +- +-&u2phy3 { +- status = "okay"; +-}; +- +-&u2phy3_host { +- phy-supply = <&vcc5v0_host>; +- status = "okay"; +-}; +- +-&usbdp_phy1 { +- 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>; +- }; +- }; +-}; +- +-&usb_host0_ehci { +- status = "okay"; +-}; +- +-&usb_host0_ohci { +- status = "okay"; +-}; +- +-&usb_host0_xhci { +- usb-role-switch; +- status = "okay"; +- +- port { +- #address-cells = <1>; +- #size-cells = <0>; +- +- dwc3_0_role_switch: endpoint { +- remote-endpoint = <&usbc0_role_sw>; ++ sound { ++ hp_detect: hp-detect { ++ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + }; + +-&usb_host1_ehci { +- status = "okay"; +-}; +- +-&usb_host1_ohci { +- status = "okay"; +-}; +- +-&usb_host1_xhci { +- dr_mode = "host"; +- status = "okay"; +-}; +- + &usb_host2_xhci { + status = "okay"; + }; + +-&vop { +- status = "okay"; +-}; +- +-&vop_mmu { ++&vcc3v3_pcie2x1l0 { ++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_0_vcc3v3_en>; + status = "okay"; + }; +- +-&vp0 { +- vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { +- reg = ; +- remote-endpoint = <&hdmi0_in_vp0>; +- }; +-}; +- +-&vp1 { +- vp1_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { +- reg = ; +- remote-endpoint = <&hdmi1_in_vp1>; +- }; +-}; +-- +GitLab diff --git a/patch/u-boot/v2025.04/board_rock-5t/0002-Add-Rock5T-dts-to-upstream-dir.patch b/patch/u-boot/v2025.04/board_rock-5t/0002-Add-Rock5T-dts-to-upstream-dir.patch new file mode 100644 index 000000000..adb627951 --- /dev/null +++ b/patch/u-boot/v2025.04/board_rock-5t/0002-Add-Rock5T-dts-to-upstream-dir.patch @@ -0,0 +1,124 @@ +From 72217a692f1b47375c47c749897e63d4a188c03a Mon Sep 17 00:00:00 2001 +From: Nicolas Frattaroli +Date: Fri, 9 May 2025 11:35:13 +0200 +Subject: [PATCH] [HACK] add ROCK 5T dts to upstream dir + +Signed-off-by: Nicolas Frattaroli +--- + .../src/arm64/rockchip/rk3588-rock-5t.dts | 105 ++++++++++++++++++ + 1 file changed, 105 insertions(+) + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-rock-5t.dts + +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-rock-5t.dts b/dts/upstream/src/arm64/rockchip/rk3588-rock-5t.dts +new file mode 100644 +index 00000000000..258c7400301 +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-rock-5t.dts +@@ -0,0 +1,105 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk3588-rock-5b-5bp-5t.dtsi" ++ ++/ { ++ model = "Radxa ROCK 5T"; ++ compatible = "radxa,rock-5t", "rockchip,rk3588"; ++ ++ analog-sound { ++ compatible = "audio-graph-card"; ++ label = "rk3588-es8316"; ++ ++ widgets = "Microphone", "Mic Jack", ++ "Headphone", "Headphones"; ++ ++ routing = "MIC2", "Mic Jack", ++ "Headphones", "HPOL", ++ "Headphones", "HPOR"; ++ ++ dais = <&i2s0_8ch_p0>; ++ hp-det-gpios = <&gpio4 RK_PC3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_detect>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_rgb_b>; ++ ++ led_rgb_b { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ rfkill { ++ compatible = "rfkill-gpio"; ++ label = "rfkill-m2-wlan"; ++ radio-type = "wlan"; ++ shutdown-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ vcc3v3_pcie2x1l1: regulator-vcc3v3-pcie2x1l2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie2x1l1"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <5000>; ++ vin-supply = <&vcc_3v3_s3>; ++ }; ++}; ++ ++&hdmi_receiver { ++ hpd-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++}; ++ ++&pcie2x1l1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_1_rst>; ++ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pcie2x1l1>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ hdmirx { ++ hdmirx_hpd: hdmirx-5v-detection { ++ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ leds { ++ led_rgb_b: led-rgb-b { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie2 { ++ pcie2_1_rst: pcie2-1-rst { ++ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ pcie2_0_vcc3v3_en: pcie2-0-vcc-en { ++ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sound { ++ hp_detect: hp-detect { ++ rockchip,pins = <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&vcc3v3_pcie2x1l0 { ++ gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie2_0_vcc3v3_en>; ++ status = "okay"; ++}; +-- +GitLab diff --git a/patch/u-boot/v2025.04/board_rock-5t/0003-Add-Rock5T-support.patch b/patch/u-boot/v2025.04/board_rock-5t/0003-Add-Rock5T-support.patch new file mode 100644 index 000000000..644718ef6 --- /dev/null +++ b/patch/u-boot/v2025.04/board_rock-5t/0003-Add-Rock5T-support.patch @@ -0,0 +1,323 @@ +From 79954f1b4f1291431bdf8e175eac60154938a089 Mon Sep 17 00:00:00 2001 +From: Nicolas Frattaroli +Date: Fri, 9 May 2025 11:37:46 +0200 +Subject: [PATCH] board: radxa: add ROCK 5T support + +The ROCK 5T is quite similar to the ROCK 5B+. Since we can't tell it +apart from the ROCK 5B+ based on memory type, as both always ship with +LPDDR5, add it as its own separate board without the auto FDT detection. + +Signed-off-by: Nicolas Frattaroli +--- + arch/arm/dts/rk3588-rock-5t-u-boot.dtsi | 77 ++++++++++++++++ + arch/arm/mach-rockchip/rk3588/Kconfig | 28 ++++++ + board/radxa/rock5t-rk3588/Kconfig | 12 +++ + board/radxa/rock5t-rk3588/MAINTAINERS | 7 ++ + configs/rock5t-rk3588_defconfig | 111 ++++++++++++++++++++++++ + include/configs/rock5t-rk3588.h | 14 +++ + 6 files changed, 249 insertions(+) + create mode 100644 arch/arm/dts/rk3588-rock-5t-u-boot.dtsi + create mode 100644 board/radxa/rock5t-rk3588/Kconfig + create mode 100644 board/radxa/rock5t-rk3588/MAINTAINERS + create mode 100644 configs/rock5t-rk3588_defconfig + create mode 100644 include/configs/rock5t-rk3588.h + +diff --git a/arch/arm/dts/rk3588-rock-5t-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5t-u-boot.dtsi +new file mode 100644 +index 00000000000..c9440382587 +--- /dev/null ++++ b/arch/arm/dts/rk3588-rock-5t-u-boot.dtsi +@@ -0,0 +1,77 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2025 Collabora Ltd. ++ */ ++ ++#include ++#include "rk3588-u-boot.dtsi" ++ ++/ { ++ leds { ++ led_rgb_b { ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&fspim2_pins { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4m1_xfer>; ++ status = "okay"; ++ ++ usbc0: usb-typec@22 { ++ compatible = "fcs,fusb302"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ usb_con: connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ data-role = "dual"; ++ power-role = "sink"; ++ try-power-role = "sink"; ++ op-sink-microwatt = <1000000>; ++ sink-pdos = ++ , ++ ; ++ }; ++ }; ++}; ++ ++&sdhci { ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++}; ++ ++&sfc { ++ flash@0 { ++ bootph-pre-ram; ++ bootph-some-ram; ++ }; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&usbdp_phy0 { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ dr_mode = "peripheral"; ++ maximum-speed = "high-speed"; ++ status = "okay"; ++}; +diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig +index 155b8f00ca2..1deb7597bb2 100644 +--- a/arch/arm/mach-rockchip/rk3588/Kconfig ++++ b/arch/arm/mach-rockchip/rk3588/Kconfig +@@ -302,6 +302,33 @@ config TARGET_ROCK_5C_RK3588S + 2x USB 2.0 Type-A HOST port + 1x USB Type-C 5V power port + ++config TARGET_ROCK5T_RK3588 ++ bool "Radxa ROCK5T RK3588 board" ++ select BOARD_LATE_INIT ++ help ++ Radxa ROCK5T is a Rockchip RK3588 based SBC (Single Board Computer) ++ by Radxa. ++ ++ Specification: ++ ++ Rockchip Rk3588 SoC ++ 4x ARM Cortex-A76, 4x ARM Cortex-A55 ++ 4/8/16/24/32GB memory LPDDR5 ++ Mali G610MC4 GPU ++ 2x 4-lane or 4x 2-lane MIPI CSI input ++ soldered eMMC (optional) ++ SPI flash for bootloader ++ uSD slot ++ 2x USB 2.0 Type-A, 2x USB 3.1 Gen1 Type-A, 1x USB 3.1 Gen1 Type-C ++ 2x HDMI 2.1 output, 1x HDMI input ++ 2x 2.5 Gbps Ethernet port ++ 2x M.2 M-key connector, PCIe 3 2-lanes each ++ On-board PCIe Wi-Fi/BT module ++ 40-pin IO header including UART, SPI, I2C and 5V DC power in ++ USB PD over USB Type-C ++ 5.5mm OD x 2.5mm ID barrel jack power input ++ Size: 110mm x 82mm ++ + config TARGET_SIGE7_RK3588 + bool "ArmSoM Sige7 RK3588 board" + select BOARD_LATE_INIT +@@ -440,6 +467,7 @@ source "board/pine64/quartzpro64-rk3588/Kconfig" + source "board/turing/turing-rk1-rk3588/Kconfig" + source "board/radxa/rock5a-rk3588s/Kconfig" + source "board/radxa/rock5b-rk3588/Kconfig" ++source "board/radxa/rock5t-rk3588/Kconfig" + source "board/radxa/rock-5-itx-rk3588/Kconfig" + source "board/radxa/rock-5c-rk3588s/Kconfig" + source "board/rockchip/evb_rk3588/Kconfig" +diff --git a/board/radxa/rock5t-rk3588/Kconfig b/board/radxa/rock5t-rk3588/Kconfig +new file mode 100644 +index 00000000000..82613ab3c2e +--- /dev/null ++++ b/board/radxa/rock5t-rk3588/Kconfig +@@ -0,0 +1,12 @@ ++if TARGET_ROCK5T_RK3588 ++ ++config SYS_BOARD ++ default "rock5t-rk3588" ++ ++config SYS_VENDOR ++ default "radxa" ++ ++config SYS_CONFIG_NAME ++ default "rock5t-rk3588" ++ ++endif +diff --git a/board/radxa/rock5t-rk3588/MAINTAINERS b/board/radxa/rock5t-rk3588/MAINTAINERS +new file mode 100644 +index 00000000000..677fe7d971b +--- /dev/null ++++ b/board/radxa/rock5t-rk3588/MAINTAINERS +@@ -0,0 +1,7 @@ ++ROCK5T-RK3588 ++M: Nicolas Frattaroli ++S: Maintained ++F: board/radxa/rock5t-rk3588 ++F: include/configs/rock5t-rk3588.h ++F: configs/rock5t-rk3588_defconfig ++F: arch/arm/dts/rk3588-rock-5t-u-boot.dtsi +diff --git a/configs/rock5t-rk3588_defconfig b/configs/rock5t-rk3588_defconfig +new file mode 100644 +index 00000000000..fa27c549758 +--- /dev/null ++++ b/configs/rock5t-rk3588_defconfig +@@ -0,0 +1,111 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SF_DEFAULT_SPEED=24000000 ++CONFIG_SF_DEFAULT_MODE=0x2000 ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588-rock-5t" ++CONFIG_ROCKCHIP_RK3588=y ++CONFIG_ROCKCHIP_SPI_IMAGE=y ++CONFIG_SPL_SERIAL=y ++CONFIG_TARGET_ROCK5T_RK3588=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_SF_DEFAULT_BUS=5 ++CONFIG_DEBUG_UART_BASE=0xFEB50000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI=y ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_AHCI=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-rock-5t.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_SPI_LOAD=y ++CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 ++CONFIG_SPL_ATF=y ++CONFIG_CMD_TCPM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_ROCKUSB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_SPL_DM_SEQ_ALIAS=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_AHCI_PCI=y ++CONFIG_DWC_AHCI=y ++CONFIG_SPL_CLK=y ++# CONFIG_USB_FUNCTION_FASTBOOT is not set ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MISC=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_SPI_FLASH_SFDP_SUPPORT=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_XTX=y ++CONFIG_PHYLIB=y ++CONFIG_RTL8169=y ++CONFIG_NVME_PCI=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_PHY_ROCKCHIP_USBDP=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_SCSI=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_SPL_USB_DWC3_GENERIC=y ++CONFIG_TYPEC_TCPM=y ++CONFIG_TYPEC_FUSB302=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=y ++CONFIG_USB_ETHER_ASIX88179=y ++CONFIG_USB_ETHER_LAN75XX=y ++CONFIG_USB_ETHER_LAN78XX=y ++CONFIG_USB_ETHER_MCS7830=y ++CONFIG_USB_ETHER_RTL8152=y ++CONFIG_USB_ETHER_SMSC95XX=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_USB_FUNCTION_ROCKUSB=y ++CONFIG_ERRNO_STR=y ++CONFIG_NET_PREFER_ROM_MAC_ADDR=y +diff --git a/include/configs/rock5t-rk3588.h b/include/configs/rock5t-rk3588.h +new file mode 100644 +index 00000000000..a0e2e84e9ff +--- /dev/null ++++ b/include/configs/rock5t-rk3588.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0+ ++ * Copyright (c) 2025 Collabora Ltd. ++ */ ++ ++#ifndef __ROCK5T_RK3588_H ++#define __ROCK5T_RK3588_H ++ ++#define ROCKCHIP_DEVICE_SETTINGS \ ++ "stdout=serial,vidconsole\0" \ ++ "stderr=serial,vidconsole\0" ++ ++#include ++ ++#endif /* __ROCK5T_RK3588_H */ +-- +GitLab diff --git a/patch/u-boot/v2025.07/board_orangepi5/0001-add-sata-dts-and-defconfig-for-OPi5.patch b/patch/u-boot/v2025.07/board_orangepi5/0001-add-sata-dts-and-defconfig-for-OPi5.patch deleted file mode 100644 index 6bce8605c..000000000 --- a/patch/u-boot/v2025.07/board_orangepi5/0001-add-sata-dts-and-defconfig-for-OPi5.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muhammed Efe Cetin -Date: Sat, 26 Apr 2025 15:45:44 +0300 -Subject: add sata dts and defconfig for OPi5 - ---- - arch/arm/dts/rk3588s-orangepi-5-sata-u-boot.dtsi | 16 ++ - configs/orangepi-5-sata-rk3588s_defconfig | 93 ++++++++++ - dts/upstream/src/arm64/rockchip/rk3588s-orangepi-5-sata.dts | 33 ++++ - 3 files changed, 142 insertions(+) - -diff --git a/arch/arm/dts/rk3588s-orangepi-5-sata-u-boot.dtsi b/arch/arm/dts/rk3588s-orangepi-5-sata-u-boot.dtsi -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/arch/arm/dts/rk3588s-orangepi-5-sata-u-boot.dtsi -@@ -0,0 +1,16 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+#include "rk3588s-u-boot.dtsi" -+#include "rk3588s-orangepi-5-u-boot.dtsi" -+ -+/ { -+ chosen { -+ u-boot,spl-boot-order = "same-as-spl", &sdmmc; -+ }; -+}; -+ -+&binman { -+ simple-bin-spi { -+ filename = "u-boot-rockchip-spi-sata.bin"; -+ }; -+}; -\ No newline at end of file -diff --git a/configs/orangepi-5-sata-rk3588s_defconfig b/configs/orangepi-5-sata-rk3588s_defconfig -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/configs/orangepi-5-sata-rk3588s_defconfig -@@ -0,0 +1,93 @@ -+CONFIG_ARM=y -+CONFIG_SKIP_LOWLEVEL_INIT=y -+CONFIG_COUNTER_FREQUENCY=24000000 -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SF_DEFAULT_SPEED=24000000 -+CONFIG_SF_DEFAULT_MODE=0x2000 -+CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588s-orangepi-5-sata" -+CONFIG_ROCKCHIP_RK3588=y -+CONFIG_ROCKCHIP_SPI_IMAGE=y -+CONFIG_SPL_SERIAL=y -+CONFIG_TARGET_EVB_RK3588=y -+CONFIG_SYS_LOAD_ADDR=0xc00800 -+CONFIG_SF_DEFAULT_BUS=5 -+CONFIG_DEBUG_UART_BASE=0xFEB50000 -+CONFIG_DEBUG_UART_CLOCK=24000000 -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI=y -+CONFIG_PCI=y -+CONFIG_DEBUG_UART=y -+CONFIG_AHCI=y -+CONFIG_FIT=y -+CONFIG_FIT_VERBOSE=y -+CONFIG_SPL_FIT_SIGNATURE=y -+CONFIG_SPL_LOAD_FIT=y -+CONFIG_LEGACY_IMAGE_FORMAT=y -+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-orangepi-5-sata.dtb" -+# CONFIG_DISPLAY_CPUINFO is not set -+CONFIG_DISPLAY_BOARDINFO_LATE=y -+CONFIG_SPL_MAX_SIZE=0x40000 -+CONFIG_SPL_PAD_TO=0x7f8000 -+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -+CONFIG_SPL_SPI_LOAD=y -+CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 -+CONFIG_SPL_ATF=y -+CONFIG_CMD_GPIO=y -+CONFIG_CMD_GPT=y -+CONFIG_CMD_I2C=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_USB=y -+# CONFIG_CMD_SETEXPR is not set -+CONFIG_CMD_REGULATOR=y -+# CONFIG_SPL_DOS_PARTITION is not set -+CONFIG_SPL_OF_CONTROL=y -+CONFIG_OF_LIVE=y -+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" -+CONFIG_SPL_DM_SEQ_ALIAS=y -+CONFIG_SPL_REGMAP=y -+CONFIG_SPL_SYSCON=y -+CONFIG_AHCI_PCI=y -+CONFIG_DWC_AHCI=y -+CONFIG_SPL_CLK=y -+CONFIG_ROCKCHIP_GPIO=y -+CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_MISC=y -+CONFIG_SUPPORT_EMMC_RPMB=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_SPI_FLASH_SFDP_SUPPORT=y -+CONFIG_SPI_FLASH_XMC=y -+CONFIG_PHY_MOTORCOMM=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_DWC_ETH_QOS_ROCKCHIP=y -+CONFIG_NVME_PCI=y -+CONFIG_PCIE_DW_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -+CONFIG_PHY_ROCKCHIP_USBDP=y -+CONFIG_SPL_PINCTRL=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_SPL_RAM=y -+CONFIG_SCSI=y -+CONFIG_BAUDRATE=1500000 -+CONFIG_DEBUG_UART_SHIFT=2 -+CONFIG_SYS_NS16550_MEM32=y -+CONFIG_ROCKCHIP_SFC=y -+CONFIG_SYSRESET=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GENERIC=y -+CONFIG_ERRNO_STR=y -+CONFIG_AHCI=y -+CONFIG_CMD_SCSI=y -+CONFIG_DM_SCSI=y -+CONFIG_DWC_AHCI=y -+CONFIG_LIBATA=y -+CONFIG_SCSI_AHCI=y -+CONFIG_SCSI=y -diff --git a/dts/upstream/src/arm64/rockchip/rk3588s-orangepi-5-sata.dts b/dts/upstream/src/arm64/rockchip/rk3588s-orangepi-5-sata.dts -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/dts/upstream/src/arm64/rockchip/rk3588s-orangepi-5-sata.dts -@@ -0,0 +1,33 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+ -+#include "rk3588s-orangepi-5.dtsi" -+#include -+#include -+ -+/ { -+ model = "Xunlong Orange Pi 5 (Sata)"; -+ compatible = "xunlong,orangepi-5", "rockchip,rk3588s"; -+}; -+ -+&sata0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sata_reset>; -+ status = "okay"; -+ -+ phys = <&combphy0_ps PHY_TYPE_SATA>; -+ phy-names = "sata-phy"; -+}; -+ -+&sfc { -+ status = "okay"; -+}; -+ -+&pinctrl { -+ sata { -+ sata_reset: sata-reset { -+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; --- -Armbian - diff --git a/patch/u-boot/v2025.10/board_9tripod-x3568-v4/0001-arm-rockchip-Add-support-for-the-9Tripod-X3568-v4.patch b/patch/u-boot/v2025.10/board_9tripod-x3568-v4/0001-arm-rockchip-Add-support-for-the-9Tripod-X3568-v4.patch new file mode 100644 index 000000000..dbe3a1ec9 --- /dev/null +++ b/patch/u-boot/v2025.10/board_9tripod-x3568-v4/0001-arm-rockchip-Add-support-for-the-9Tripod-X3568-v4.patch @@ -0,0 +1,1084 @@ +From 16f95686b5137a6eafdf338867991331f94a6643 Mon Sep 17 00:00:00 2001 +From: Coia Prant +Date: Fri, 7 Nov 2025 21:45:20 +0800 +Subject: [PATCH] arm: rockchip: Add support for the 9Tripod X3568 v4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The 9Tripod X3568 v4 is an RK3568-based SBC, just like the RK3568-EVB. +It always uses soldered connections between the X3568CV2/X3568CV3/X3568CV4 core board +and the X3568bv4 I/O board. + +The differences between the core boards +- PCB size, layout +- CPU (RKK3568B2/RK3568J) +- Memory type (DDR4/LPDDR4/LPDDR4X) and size +- eMMC size +- DSI/EDP resistor values +Although the components vary, they maintain full compatibility. + +The X3568 board has multiple hardware revisions, and we currently support v4 (I/O board). + +Specification: +- SoC: RockChip RK3568 ARM64 (4 cores) +- eMMC: 16-128 GB +- RAM: 2-16 GB +- Power: DC 12V 2A +- Ethernet: 2x YT8521SC RGMII (10/100/1000 Mbps) +- Wireless radio: 802.11b/g/n/ac/ax dual-band +- LED: + Power: AlwaysOn + User: GPIO +- Button: + VOL+: SARADC/0 <35k µV> + VOL-: SARADC/0 <450k µV> + Power/Reset: PMIC RK809 +- CAN + CAN/1: 4-pin (PH 2.0) +- PWM + PWM/4: Backlight DSI/0 DSI/1 + PWM/7: IR Receiver [may not install] +- UART: + UART/2: Debug TTL - 1500000 8N1 (1.25mm) + UART/3: TTL (PH 2.0) + UART/4: TTL (PH 2.0) + UART/8: AP6275S Bluetooth + UART/9: TTL (PH 2.0) +- I2C: + I2C/0: PMIC RK809 + I2C/1: Touchscreen DSI/0 DSI/1 + I2C/4: Camera + I2C/5: RTC@51 PCF8563 +- I2S: + I2S/0: miniHDMI Sound + I2S/1: RK809 Audio Codec + I2S/3: AP6275S Bluetooth Sound +- SDMMC: + SDMMC/0: microSD (TF) slot + SDMMC/2: AP6275S SDIO WiFi card +- Camera: 1x CSI +- Video: miniHDMI / DSI0 (MIPI/LVDS) / DSI1 (MIPI/EDP) +- Audio: miniHDMI / MIC on-board / Speaker / SPDIF / 3.5mm Headphones / AP6275S Bluetooth +- USB: + USB 2.0 HOST x2 + USB 2.0 HOST x3 (4-pin) + USB 2.0 OTG x1 (shared with USB 3.0 OTG/HOST) [slot may not install] + USB 3.0 HOST x1 + USB 3.0 OTG/HOST x1 +- SATA: 1x SATA 3.0 with Power/4-pin [slot may not install] +- PCIe: 1x PCIe 3.0 x2 (x4 connecter) [power/clock/slot may not install] + +Link: +- https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf +- https://blog.gov.cooking/archives/research-ninetripod-x3568-v4-and-flash.html + +Signed-off-by: Coia Prant +--- + arch/arm/dts/Makefile | 3 + + .../dts/rk3568-9tripod-x3568-v4-u-boot.dtsi | 3 + + arch/arm/dts/rk3568-9tripod-x3568-v4.dts | 880 ++++++++++++++++++ + configs/9tripod-x3568-v4-rk3568_defconfig | 80 ++ + 4 files changed, 966 insertions(+) + create mode 100644 arch/arm/dts/rk3568-9tripod-x3568-v4-u-boot.dtsi + create mode 100644 arch/arm/dts/rk3568-9tripod-x3568-v4.dts + create mode 100644 configs/9tripod-x3568-v4-rk3568_defconfig + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 7c8cf3a5a1d..8ab0044789a 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -74,6 +74,9 @@ dtb-$(CONFIG_ROCKCHIP_RK3368) += \ + rk3368-geekbox.dtb \ + rk3368-px5-evb.dtb \ + ++dtb-$(CONFIG_ROCKCHIP_RK3568) += \ ++ rk3568-9tripod-x3568-v4.dtb ++ + dtb-$(CONFIG_ARCH_S5P4418) += \ + s5p4418-nanopi2.dtb + +diff --git a/arch/arm/dts/rk3568-9tripod-x3568-v4-u-boot.dtsi b/arch/arm/dts/rk3568-9tripod-x3568-v4-u-boot.dtsi +new file mode 100644 +index 00000000000..e0cb8e3e7c8 +--- /dev/null ++++ b/arch/arm/dts/rk3568-9tripod-x3568-v4-u-boot.dtsi +@@ -0,0 +1,3 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3568-u-boot.dtsi" +diff --git a/arch/arm/dts/rk3568-9tripod-x3568-v4.dts b/arch/arm/dts/rk3568-9tripod-x3568-v4.dts +new file mode 100644 +index 00000000000..ad4d620603c +--- /dev/null ++++ b/arch/arm/dts/rk3568-9tripod-x3568-v4.dts +@@ -0,0 +1,880 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include ++#include ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "9Tripod X3568 v4"; ++ compatible = "9tripod,x3568-v4", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc0; ++ mmc2 = &sdmmc2; ++ rtc0 = &rtc0; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 0>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ button-vol-up { ++ label = "volume up"; ++ linux,code = ; ++ press-threshold-microvolt = <50000>; ++ }; ++ ++ button-vol-down { ++ label = "volume down"; ++ linux,code = ; ++ press-threshold-microvolt = <500000>; ++ }; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_work: led-0 { ++ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; ++ function = LED_FUNCTION_HEARTBEAT; ++ color = ; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_work_en>; ++ }; ++ }; ++ ++ rk809-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "Analog RK809"; ++ simple-audio-card,mclk-fs = <256>; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_8ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&rk809>; ++ }; ++ }; ++ ++ pdm_codec: pdm-codec { ++ compatible = "dmic-codec"; ++ num-channels = <2>; ++ #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>; ++ }; ++ }; ++ ++ spdif_dit: spdif-dit { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ spdif_sound: spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_dit>; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk809 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable>; ++ post-power-on-delay-ms = <100>; ++ power-off-delay-us = <300>; ++ reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; ++ }; ++ ++ dc_12v: regulator-dc-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_12v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_sys: regulator-vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc3v3_pcie: regulator-vcc3v3-pcie { ++ compatible = "regulator-gpio"; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-min-microvolt = <100000>; ++ regulator-max-microvolt = <3300000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc3v3_pcie_en_pin>; ++ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; ++ gpios-states = <1>; ++ states = <100000 0>, <3300000 1>; ++ startup-delay-us = <5000>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc5v0_usb: regulator-vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc5v0_usb_host: regulator-vcc5v0-usb-host { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_host_en>; ++ regulator-name = "vcc5v0_usb_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc5v0_usb_otg: regulator-vcc5v0-usb-otg { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 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_usb>; ++ }; ++}; ++ ++&can1 { ++ assigned-clocks = <&cru CLK_CAN1>; ++ assigned-clock-rates = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can1m1_pins>; ++ status = "okay"; ++}; ++ ++/* used for usb_host0_xhci */ ++&combphy0 { ++ status = "okay"; ++}; ++ ++/* used for usb_host1_xhci */ ++&combphy1 { ++ status = "okay"; ++}; ++ ++/* connected to sata2 */ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii-id"; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ phy-handle = <&rgmii_phy1>; ++ phy-mode = "rgmii-id"; ++ 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 = ; ++ assigned-clocks = <&cru I2S1_MCLKOUT_TX>; ++ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; ++ #clock-cells = <1>; ++ clock-names = "mclk"; ++ clocks = <&cru I2S1_MCLKOUT_TX>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; ++ system-power-controller; ++ #sound-dai-cells = <0>; ++ 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; ++ ++ 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; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_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; ++ }; ++ }; ++ ++ 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-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; ++ }; ++ }; ++ }; ++ ++ codec { ++ rockchip,mic-in-differential; ++ }; ++ }; ++}; ++ ++&i2c5 { ++ status = "okay"; ++ ++ rtc0: rtc@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ #clock-cells = <0>; ++ }; ++}; ++ ++&i2s0_8ch { ++ status = "okay"; ++}; ++ ++&i2s1_8ch { ++ pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>; ++ rockchip,trcm-sync-tx-only; ++ status = "okay"; ++}; ++ ++/* used for AP6275S Bluetooth Sound */ ++&i2s3_2ch { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@3 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <3>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@1 { ++ reg = <1>; ++ color = ; ++ function = LED_FUNCTION_LAN; ++ default-state = "keep"; ++ }; ++ ++ /* Note: The LED polarity is inverted */ ++ led@2 { ++ reg = <2>; ++ color = ; ++ function = LED_FUNCTION_LAN; ++ default-state = "keep"; ++ }; ++ }; ++ }; ++}; ++ ++&mdio1 { ++ rgmii_phy1: ethernet-phy@2 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <2>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ ++ leds { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@1 { ++ reg = <1>; ++ color = ; ++ function = LED_FUNCTION_LAN; ++ default-state = "keep"; ++ }; ++ ++ /* Note: The LED polarity is inverted */ ++ led@2 { ++ reg = <2>; ++ color = ; ++ function = LED_FUNCTION_LAN; ++ default-state = "keep"; ++ }; ++ }; ++ }; ++}; ++ ++&pcie30phy { ++ status = "okay"; ++}; ++ ++&pcie3x2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pin>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pcie>; ++ status = "okay"; ++}; ++ ++&pdm { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ leds { ++ led_work_en: led_work_en { ++ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable: wifi-enable { ++ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ vcc5v0_usb_host_en: vcc5v0_usb_host_en { ++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_reset_pin: pcie-reset-pin { ++ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin { ++ rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio2-supply = <&vcc_1v8>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&pwm4 { ++ status = "okay"; ++}; ++ ++/* Required remotectl for IR receiver */ ++&pwm7 { ++ status = "disabled"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sata2 { ++ status = "okay"; ++}; ++ ++/* used for eMMC */ ++&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>; ++ status = "okay"; ++}; ++ ++/* used for microSD (TF) Slot */ ++&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-sdr104; ++ vmmc-supply = <&vcc3v3_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++/* used for AP6275S WiFi */ ++&sdmmc2 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v3_sys>; ++ vqmmc-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&spdif { ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++/* used for Debug */ ++&uart2 { ++ status = "okay"; ++}; ++ ++&uart3 { ++ pinctrl-0 = <&uart3m1_xfer>; ++ status = "okay"; ++}; ++ ++&uart4 { ++ pinctrl-0 = <&uart4m1_xfer>; ++ status = "okay"; ++}; ++ ++/* used for WiFi/BT AP6275S */ ++&uart8 { ++ pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn>; ++ status = "okay"; ++}; ++ ++&uart9 { ++ pinctrl-0 = <&uart9m1_xfer>; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ extcon = <&usb2phy0>; ++ 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_usb_host>; ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ phy-supply = <&vcc5v0_usb_otg>; ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_usb_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_usb_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 = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; +diff --git a/configs/9tripod-x3568-v4-rk3568_defconfig b/configs/9tripod-x3568-v4-rk3568_defconfig +new file mode 100644 +index 00000000000..6f3bdc1c544 +--- /dev/null ++++ b/configs/9tripod-x3568-v4-rk3568_defconfig +@@ -0,0 +1,80 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3568-9tripod-x3568-v4" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_SPL_SERIAL=y ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_AHCI=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-9tripod-x3568-v4.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_ATF=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++# CONFIG_OF_UPSTREAM is not set ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_SPL_DM_SEQ_ALIAS=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_DWC_AHCI=y ++CONFIG_SPL_CLK=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_PHY_MOTORCOMM=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_DWC_ETH_QOS_ROCKCHIP=y ++CONFIG_NVME_PCI=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_SCSI=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_ERRNO_STR=y +-- +2.47.3 + diff --git a/patch/u-boot/v2025.10/board_khadas-edge2/0001-khadas-edge2-add-support-for-KBI-and-apply-some-patc.patch b/patch/u-boot/v2025.10/board_khadas-edge2/0001-khadas-edge2-add-support-for-KBI-and-apply-some-patc.patch new file mode 100644 index 000000000..edb7db1dc --- /dev/null +++ b/patch/u-boot/v2025.10/board_khadas-edge2/0001-khadas-edge2-add-support-for-KBI-and-apply-some-patc.patch @@ -0,0 +1,908 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Muhammed Efe Cetin +Date: Wed, 22 Oct 2025 12:44:49 +0200 +Subject: khadas-edge2: add support for KBI and apply some patches from BSP + uboot + +--- + arch/arm/dts/rk3588-khadas-edge2-u-boot.dtsi | 3 + + board/khadas/khadas-edge2-rk3588s/Makefile | 3 + + board/khadas/khadas-edge2-rk3588s/khadas-edge2-rk3588s.c | 95 ++ + cmd/Kconfig | 6 + + cmd/Makefile | 1 + + cmd/kbi.c | 710 ++++++++++ + configs/khadas-edge2-rk3588s_defconfig | 6 + + 7 files changed, 824 insertions(+) + +diff --git a/arch/arm/dts/rk3588-khadas-edge2-u-boot.dtsi b/arch/arm/dts/rk3588-khadas-edge2-u-boot.dtsi +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/arch/arm/dts/rk3588-khadas-edge2-u-boot.dtsi +@@ -0,0 +1,3 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3588s-u-boot.dtsi" +\ No newline at end of file +diff --git a/board/khadas/khadas-edge2-rk3588s/Makefile b/board/khadas/khadas-edge2-rk3588s/Makefile +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/board/khadas/khadas-edge2-rk3588s/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0+ ++ ++obj-y += khadas-edge2-rk3588s.o +diff --git a/board/khadas/khadas-edge2-rk3588s/khadas-edge2-rk3588s.c b/board/khadas/khadas-edge2-rk3588s/khadas-edge2-rk3588s.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/board/khadas/khadas-edge2-rk3588s/khadas-edge2-rk3588s.c +@@ -0,0 +1,95 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2022 Wesion Technology Co., Ltd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define HW_VERSION_ADC_VALUE_TOLERANCE 0x28 ++#define HW_VERSION_ADC_VAL_EDGE2_V11 0x2b3 ++#define HW_VERSION_ADC_VAL_EDGE2_V12 0x56d ++#define HW_VERSION_ADC_VAL_EDGE2_V13 0x807 ++ ++static int set_hw_version(void) ++{ ++ unsigned int val = 0; ++ int ret; ++ struct udevice *dev; ++ int current_channel = 5; ++ ++ ret = uclass_get_device_by_name(UCLASS_ADC, "adc@fec10000", &dev); ++ if (ret) { ++ printf("%s uclass_get_device_by_name fail! ret=%d\n", __func__, ret); ++ return 0; ++ } ++ ++ udelay(100); ++ ++ ret = adc_start_channel(dev, current_channel); ++ if (ret) { ++ printf("%s adc_start_channel fail! ret=%d\n", __func__, ret); ++ return 0; ++ } ++ ++ ret = adc_channel_data(dev, current_channel, &val); ++ if (ret) { ++ printf("%s adc_channel_data fail! ret=%d\n", __func__, ret); ++ return 0; ++ } ++ ++ if ((val >= HW_VERSION_ADC_VAL_EDGE2_V11 - HW_VERSION_ADC_VALUE_TOLERANCE) && ++ (val <= HW_VERSION_ADC_VAL_EDGE2_V11 + HW_VERSION_ADC_VALUE_TOLERANCE)) { ++ env_set("hwver", "EDGE2.V11"); ++ } else if ((val >= HW_VERSION_ADC_VAL_EDGE2_V12 - HW_VERSION_ADC_VALUE_TOLERANCE) && ++ (val <= HW_VERSION_ADC_VAL_EDGE2_V12 + HW_VERSION_ADC_VALUE_TOLERANCE)) { ++ env_set("hwver", "EDGE2.V12"); ++ } else if ((val >= HW_VERSION_ADC_VAL_EDGE2_V13 - HW_VERSION_ADC_VALUE_TOLERANCE) && ++ (val <= HW_VERSION_ADC_VAL_EDGE2_V13 + HW_VERSION_ADC_VALUE_TOLERANCE)) { ++ env_set("hwver", "EDGE2.V13"); ++ } else { ++ env_set("hwver", "Unknown"); ++ } ++ ++ return 0; ++} ++ ++int rk_board_late_init(void) ++{ ++ unsigned int val; ++ u8 linebuf[1]; ++ ++ /* Set FAN test */ ++ run_command("i2c dev 2; i2c mw 18 96 1", 0); ++ ++ /* Set Green LED on */ ++ run_command("gpio set 138; gpio clear 139; gpio clear 140", 0); ++ ++ /* GPIO4_A2 vcc 5v */ ++ run_command("gpio set 130", 0); ++ ++ /* Enable Pogo power */ ++ int ret = adc_channel_single_shot("adc@fec10000", 2, &val); ++ if (ret) { ++ printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret); ++ return 0; ++ } ++ ++ if (!ret && val < 50) { ++ run_command("gpio set 105", 1); /* pogo_power_enable */ ++ } ++ ++ set_hw_version(); ++ ++ return 0; ++} +\ No newline at end of file +diff --git a/cmd/Kconfig b/cmd/Kconfig +index 111111111111..222222222222 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -190,6 +190,12 @@ config CMD_FWU_METADATA + help + Command to read the metadata and dump it's contents + ++config CMD_KHADAS_KBI ++ bool "khadas_kbi" ++ default y ++ help ++ Command to show KBI instructions. ++ + config CMD_HELP + bool "help" + default y +diff --git a/cmd/Makefile b/cmd/Makefile +index 111111111111..222222222222 100644 +--- a/cmd/Makefile ++++ b/cmd/Makefile +@@ -12,6 +12,7 @@ obj-y += panic.o + obj-y += version.o + + # command ++obj-$(CONFIG_CMD_KHADAS_KBI) += kbi.o + obj-$(CONFIG_CMD_ARMFFA) += armffa.o + obj-$(CONFIG_CMD_2048) += 2048.o + obj-$(CONFIG_CMD_ACPI) += acpi.o +diff --git a/cmd/kbi.c b/cmd/kbi.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/cmd/kbi.c +@@ -0,0 +1,710 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * KBI (Khadas Bootloader Instructions) driver ++ * ++ * Copyright (C) 2025 Khadas ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* MCU I2C Configuration */ ++#define KBI_MCU_ADDR 0x18 ++#define KBI_I2C_BUS_NUM 2 ++ ++/* Register Map */ ++#define REG_PASSWD_VENDOR 0x00 ++#define REG_USID 0x06 ++#define REG_VERSION 0x12 ++ ++#define REG_BOOT_MODE 0x20 ++#define REG_BOOT_EN_DCIN 0x21 ++#define REG_BOOT_EN_RTC 0x22 ++#define REG_LED_ON 0x23 ++#define REG_LED_OFF 0x24 ++#define REG_LED_RGB_ON_R 0x25 ++#define REG_LED_RGB_ON_G 0x26 ++#define REG_LED_RGB_ON_B 0x27 ++#define REG_LED_RGB_OFF_R 0x28 ++#define REG_LED_RGB_OFF_G 0x29 ++#define REG_LED_RGB_OFF_B 0x2A ++#define REG_REST_CONF 0x2C ++#define REG_SLEEP_EN 0x2E ++ ++#define REG_PWD_WRITE 0x81 ++#define REG_PWD_DATA 0x82 ++#define REG_LED_ON_RAM 0x89 ++#define REG_FAN_CTRL 0x8A ++#define REG_WDT_EN 0x8B ++ ++#define REG_SYS_RST 0x91 ++#define REG_BOOT_FLAG 0x92 ++#define REG_FAN_TEST 0x96 ++ ++/* Configuration Constants */ ++#define VERSION_LENGTH 2 ++#define USID_LENGTH 7 ++ ++#define HW_VERSION_ADC_CHANNEL 5 ++#define HW_VERSION_ADC_TOLERANCE 0x28 ++#define HW_VERSION_ADC_VAL_V11 0x2b3 ++#define HW_VERSION_ADC_VAL_V12 0x56d ++#define HW_VERSION_ADC_VAL_V13 0x807 ++ ++/* LED Modes */ ++enum led_mode { ++ LED_MODE_OFF = 0, ++ LED_MODE_ON, ++ LED_MODE_R_BREATHE, ++ LED_MODE_G_BREATHE, ++ LED_MODE_B_BREATHE, ++ LED_MODE_RG_BREATHE, ++ LED_MODE_RB_BREATHE, ++ LED_MODE_GB_BREATHE, ++ LED_MODE_RGB_BREATHE, ++ LED_MODE_R_HEARTBEAT, ++ LED_MODE_G_HEARTBEAT, ++ LED_MODE_B_HEARTBEAT, ++ LED_MODE_RG_HEARTBEAT, ++ LED_MODE_RB_HEARTBEAT, ++ LED_MODE_GB_HEARTBEAT, ++ LED_MODE_RGB_HEARTBEAT, ++ LED_MODE_MAX ++}; ++ ++enum led_system_state { ++ LED_SYSTEM_OFF = 0, ++ LED_SYSTEM_ON ++}; ++ ++enum boot_trigger { ++ BOOT_TRIGGER_RTC = 1, ++ BOOT_TRIGGER_DCIN ++}; ++ ++/* LED mode string mapping */ ++static const char * const led_mode_str[] = { ++ [LED_MODE_OFF] = "off", ++ [LED_MODE_ON] = "on", ++ [LED_MODE_R_BREATHE] = "r_breathe", ++ [LED_MODE_G_BREATHE] = "g_breathe", ++ [LED_MODE_B_BREATHE] = "b_breathe", ++ [LED_MODE_RG_BREATHE] = "rg_breathe", ++ [LED_MODE_RB_BREATHE] = "rb_breathe", ++ [LED_MODE_GB_BREATHE] = "gb_breathe", ++ [LED_MODE_RGB_BREATHE] = "rgb_breathe", ++ [LED_MODE_R_HEARTBEAT] = "r_heartbeat", ++ [LED_MODE_G_HEARTBEAT] = "g_heartbeat", ++ [LED_MODE_B_HEARTBEAT] = "b_heartbeat", ++ [LED_MODE_RG_HEARTBEAT] = "rg_heartbeat", ++ [LED_MODE_RB_HEARTBEAT] = "rb_heartbeat", ++ [LED_MODE_GB_HEARTBEAT] = "gb_heartbeat", ++ [LED_MODE_RGB_HEARTBEAT] = "rgb_heartbeat", ++}; ++ ++/** ++ * struct kbi_mcu - KBI MCU instance data ++ * @i2c_dev: I2C device for MCU communication ++ */ ++struct kbi_mcu { ++ struct udevice *i2c_dev; ++}; ++ ++static struct kbi_mcu g_kbi; ++ ++/** ++ * kbi_i2c_init() - Initialize I2C communication with MCU ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_i2c_init(void) ++{ ++ struct udevice *bus; ++ int ret; ++ ++ if (g_kbi.i2c_dev) ++ return 0; ++ ++ ret = uclass_get_device_by_seq(UCLASS_I2C, KBI_I2C_BUS_NUM, &bus); ++ if (ret) { ++ printf("KBI: Failed to get I2C bus %d: %d\n", ++ KBI_I2C_BUS_NUM, ret); ++ return ret; ++ } ++ ++ ret = i2c_get_chip(bus, KBI_MCU_ADDR, 1, &g_kbi.i2c_dev); ++ if (ret) { ++ printf("KBI: Failed to get I2C chip 0x%x: %d\n", ++ KBI_MCU_ADDR, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * kbi_i2c_read_reg() - Read a single register from MCU ++ * @reg: Register address ++ * @val: Pointer to store read value ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_i2c_read_reg(u8 reg, u8 *val) ++{ ++ int ret; ++ ++ ret = kbi_i2c_init(); ++ if (ret) ++ return ret; ++ ++ ret = dm_i2c_read(g_kbi.i2c_dev, reg, val, 1); ++ if (ret) { ++ printf("KBI: Failed to read reg 0x%02x: %d\n", reg, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * kbi_i2c_write_reg() - Write a single register to MCU ++ * @reg: Register address ++ * @val: Value to write ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_i2c_write_reg(u8 reg, u8 val) ++{ ++ int ret; ++ ++ ret = kbi_i2c_init(); ++ if (ret) ++ return ret; ++ ++ ret = dm_i2c_write(g_kbi.i2c_dev, reg, &val, 1); ++ if (ret) { ++ printf("KBI: Failed to write reg 0x%02x: %d\n", reg, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * kbi_i2c_read_block() - Read multiple consecutive registers ++ * @start_reg: Starting register address ++ * @buf: Buffer to store read data ++ * @len: Number of bytes to read ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_i2c_read_block(u8 start_reg, u8 *buf, size_t len) ++{ ++ int ret; ++ ++ if (!buf || len == 0) ++ return -EINVAL; ++ ++ ret = kbi_i2c_init(); ++ if (ret) ++ return ret; ++ ++ ret = dm_i2c_read(g_kbi.i2c_dev, start_reg, buf, len); ++ if (ret) { ++ printf("KBI: Failed to read block at 0x%02x: %d\n", ++ start_reg, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * kbi_get_version() - Read and display MCU firmware version ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_get_version(void) ++{ ++ u8 version[VERSION_LENGTH]; ++ int ret; ++ int i; ++ ++ ret = kbi_i2c_read_block(REG_VERSION, version, VERSION_LENGTH); ++ if (ret) ++ return ret; ++ ++ printf("MCU firmware version: "); ++ for (i = 0; i < VERSION_LENGTH; i++) ++ printf("%02x ", version[i]); ++ printf("\n"); ++ ++ return 0; ++} ++ ++/** ++ * kbi_get_usid() - Read USID and store in environment ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_get_usid(void) ++{ ++ u8 usid[USID_LENGTH]; ++ char serial[USID_LENGTH * 2 + 1]; ++ int ret; ++ int i; ++ ++ ret = kbi_i2c_read_block(REG_USID, usid, USID_LENGTH); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < USID_LENGTH; i++) ++ sprintf(serial + i * 2, "%02X", usid[i]); ++ ++ printf("USID: %s\n", serial); ++ env_set("usid", serial); ++ ++ return 0; ++} ++ ++/** ++ * kbi_get_hw_version() - Detect hardware version via ADC ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_get_hw_version(void) ++{ ++ struct udevice *dev; ++ unsigned int adc_val; ++ const char *hw_ver_str; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_ADC, ++ DM_DRIVER_GET(rockchip_saradc), ++ &dev); ++ if (ret) { ++ printf("KBI: Failed to get ADC device: %d\n", ret); ++ return ret; ++ } ++ ++ ret = adc_channel_single_shot(dev->name, HW_VERSION_ADC_CHANNEL, &adc_val); ++ if (ret) { ++ printf("KBI: Failed to read ADC: %d\n", ret); ++ return ret; ++ } ++ ++ printf("ADC channel %d value: 0x%x (%u)\n", ++ HW_VERSION_ADC_CHANNEL, adc_val, adc_val); ++ ++ /* Determine hardware version based on ADC value */ ++ if (adc_val >= HW_VERSION_ADC_VAL_V11 - HW_VERSION_ADC_TOLERANCE && ++ adc_val <= HW_VERSION_ADC_VAL_V11 + HW_VERSION_ADC_TOLERANCE) { ++ hw_ver_str = "EDGE2.V11"; ++ } else if (adc_val >= HW_VERSION_ADC_VAL_V12 - HW_VERSION_ADC_TOLERANCE && ++ adc_val <= HW_VERSION_ADC_VAL_V12 + HW_VERSION_ADC_TOLERANCE) { ++ hw_ver_str = "EDGE2.V12"; ++ } else if (adc_val >= HW_VERSION_ADC_VAL_V13 - HW_VERSION_ADC_TOLERANCE && ++ adc_val <= HW_VERSION_ADC_VAL_V13 + HW_VERSION_ADC_TOLERANCE) { ++ hw_ver_str = "EDGE2.V13"; ++ } else { ++ hw_ver_str = "Unknown"; ++ } ++ ++ printf("Hardware version: %s\n", hw_ver_str); ++ env_set("hwver", hw_ver_str); ++ ++ return 0; ++} ++ ++/** ++ * led_str_to_mode() - Convert LED mode string to enum value ++ * @str: LED mode string ++ * ++ * Return: LED mode enum value, or -EINVAL if invalid ++ */ ++static int led_str_to_mode(const char *str) ++{ ++ int i; ++ ++ if (!str) ++ return -EINVAL; ++ ++ for (i = 0; i < ARRAY_SIZE(led_mode_str); i++) { ++ if (strcmp(str, led_mode_str[i]) == 0) ++ return i; ++ } ++ ++ return -EINVAL; ++} ++ ++/** ++ * kbi_get_led_mode() - Read and display current LED mode ++ * @state: LED_SYSTEM_OFF or LED_SYSTEM_ON ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_get_led_mode(enum led_system_state state) ++{ ++ u8 mode, r, g, b; ++ u8 mode_reg, r_reg, g_reg, b_reg; ++ int ret; ++ const char *state_str; ++ ++ if (state == LED_SYSTEM_OFF) { ++ mode_reg = REG_LED_OFF; ++ r_reg = REG_LED_RGB_OFF_R; ++ g_reg = REG_LED_RGB_OFF_G; ++ b_reg = REG_LED_RGB_OFF_B; ++ state_str = "systemoff"; ++ } else { ++ mode_reg = REG_LED_ON; ++ r_reg = REG_LED_RGB_ON_R; ++ g_reg = REG_LED_RGB_ON_G; ++ b_reg = REG_LED_RGB_ON_B; ++ state_str = "systemon"; ++ } ++ ++ ret = kbi_i2c_read_reg(mode_reg, &mode); ++ if (ret) ++ return ret; ++ ++ if (mode >= LED_MODE_MAX) { ++ printf("Invalid LED mode: 0x%02x\n", mode); ++ return -EINVAL; ++ } ++ ++ printf("[%s] LED mode: %s", state_str, led_mode_str[mode]); ++ ++ /* For static on/off modes, also display RGB values */ ++ if (mode == LED_MODE_ON || mode == LED_MODE_OFF) { ++ ret = kbi_i2c_read_reg(r_reg, &r); ++ if (ret) ++ return ret; ++ ret = kbi_i2c_read_reg(g_reg, &g); ++ if (ret) ++ return ret; ++ ret = kbi_i2c_read_reg(b_reg, &b); ++ if (ret) ++ return ret; ++ ++ printf(" [R:0x%02x G:0x%02x B:0x%02x]", r, g, b); ++ } ++ ++ printf("\n"); ++ return 0; ++} ++ ++/** ++ * kbi_set_led_rgb() - Set RGB LED color values ++ * @state: LED_SYSTEM_OFF or LED_SYSTEM_ON ++ * @r: Red value (0-255) ++ * @g: Green value (0-255) ++ * @b: Blue value (0-255) ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_set_led_rgb(enum led_system_state state, u8 r, u8 g, u8 b) ++{ ++ u8 r_reg, g_reg, b_reg; ++ int ret; ++ ++ if (state == LED_SYSTEM_OFF) { ++ r_reg = REG_LED_RGB_OFF_R; ++ g_reg = REG_LED_RGB_OFF_G; ++ b_reg = REG_LED_RGB_OFF_B; ++ } else { ++ r_reg = REG_LED_RGB_ON_R; ++ g_reg = REG_LED_RGB_ON_G; ++ b_reg = REG_LED_RGB_ON_B; ++ } ++ ++ ret = kbi_i2c_write_reg(r_reg, r); ++ if (ret) ++ return ret; ++ ++ ret = kbi_i2c_write_reg(g_reg, g); ++ if (ret) ++ return ret; ++ ++ ret = kbi_i2c_write_reg(b_reg, b); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/** ++ * kbi_set_led_mode() - Set LED mode ++ * @state: LED_SYSTEM_OFF or LED_SYSTEM_ON ++ * @color: Color string ("r", "g", "b", "rg", "rb", "gb", "rgb") ++ * @mode_str: Mode string (see led_mode_str array) ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_set_led_mode(enum led_system_state state, ++ const char *color, const char *mode_str) ++{ ++ char full_mode_str[32]; ++ int mode; ++ u8 mode_reg; ++ u8 r = 0, g = 0, b = 0; ++ int ret; ++ ++ if (!color || !mode_str) ++ return -EINVAL; ++ ++ /* Handle on/off modes with color specification */ ++ if (strcmp(mode_str, "on") == 0 || strcmp(mode_str, "off") == 0) { ++ /* Validate color string */ ++ if (strcmp(color, "r") != 0 && strcmp(color, "g") != 0 && ++ strcmp(color, "b") != 0 && strcmp(color, "rg") != 0 && ++ strcmp(color, "rb") != 0 && strcmp(color, "gb") != 0 && ++ strcmp(color, "rgb") != 0) { ++ printf("Invalid color: %s\n", color); ++ return -EINVAL; ++ } ++ ++ mode = (strcmp(mode_str, "on") == 0) ? LED_MODE_ON : LED_MODE_OFF; ++ ++ /* Set RGB values based on color and mode */ ++ if (mode == LED_MODE_ON) { ++ if (strchr(color, 'r')) ++ r = 0xff; ++ if (strchr(color, 'g')) ++ g = 0xff; ++ if (strchr(color, 'b')) ++ b = 0xff; ++ } ++ } else { ++ /* Combine color and mode for other modes (e.g., "r_breathe") */ ++ snprintf(full_mode_str, sizeof(full_mode_str), "%s_%s", ++ color, mode_str); ++ mode = led_str_to_mode(full_mode_str); ++ if (mode < 0) { ++ printf("Invalid LED mode: %s\n", full_mode_str); ++ return -EINVAL; ++ } ++ } ++ ++ mode_reg = (state == LED_SYSTEM_OFF) ? REG_LED_OFF : REG_LED_ON; ++ ++ /* Set LED mode first */ ++ ret = kbi_i2c_write_reg(mode_reg, mode); ++ if (ret) ++ return ret; ++ ++ /* For on/off modes, set RGB values */ ++ if (mode == LED_MODE_ON || mode == LED_MODE_OFF) { ++ ret = kbi_set_led_rgb(state, r, g, b); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * kbi_get_boot_trigger() - Read boot trigger enable state ++ * @trigger: BOOT_TRIGGER_RTC or BOOT_TRIGGER_DCIN ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_get_boot_trigger(enum boot_trigger trigger) ++{ ++ u8 enable; ++ u8 reg; ++ const char *name; ++ int ret; ++ ++ if (trigger == BOOT_TRIGGER_RTC) { ++ reg = REG_BOOT_EN_RTC; ++ name = "RTC"; ++ } else if (trigger == BOOT_TRIGGER_DCIN) { ++ reg = REG_BOOT_EN_DCIN; ++ name = "DCIN"; ++ } else { ++ return -EINVAL; ++ } ++ ++ ret = kbi_i2c_read_reg(reg, &enable); ++ if (ret) ++ return ret; ++ ++ printf("Boot trigger %s: %s\n", name, ++ enable ? "enabled" : "disabled"); ++ ++ return 0; ++} ++ ++/** ++ * kbi_set_boot_trigger() - Set boot trigger enable state ++ * @trigger: BOOT_TRIGGER_RTC or BOOT_TRIGGER_DCIN ++ * @enable: 1 to enable, 0 to disable ++ * ++ * Return: 0 on success, negative error code on failure ++ */ ++static int kbi_set_boot_trigger(enum boot_trigger trigger, bool enable) ++{ ++ u8 reg; ++ ++ if (trigger == BOOT_TRIGGER_RTC) { ++ reg = REG_BOOT_EN_RTC; ++ } else if (trigger == BOOT_TRIGGER_DCIN) { ++ reg = REG_BOOT_EN_DCIN; ++ } else { ++ return -EINVAL; ++ } ++ ++ return kbi_i2c_write_reg(reg, enable ? 1 : 0); ++} ++ ++/* Command implementations */ ++ ++static int do_kbi_version(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ return kbi_get_version(); ++} ++ ++static int do_kbi_usid(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ return kbi_get_usid(); ++} ++ ++static int do_kbi_hwver(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ return kbi_get_hw_version(); ++} ++ ++static int do_kbi_led(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ enum led_system_state state; ++ const char *op; ++ const char *color; ++ const char *mode; ++ ++ if (argc < 3) ++ return CMD_RET_USAGE; ++ ++ /* Parse system state */ ++ if (strcmp(argv[1], "systemoff") == 0) { ++ state = LED_SYSTEM_OFF; ++ } else if (strcmp(argv[1], "systemon") == 0) { ++ state = LED_SYSTEM_ON; ++ } else { ++ return CMD_RET_USAGE; ++ } ++ ++ op = argv[2]; ++ ++ if (strcmp(op, "r") == 0) { ++ /* Read LED mode */ ++ return kbi_get_led_mode(state); ++ } else if (strcmp(op, "w") == 0) { ++ /* Write LED mode */ ++ if (argc < 5) ++ return CMD_RET_USAGE; ++ ++ color = argv[3]; ++ mode = argv[4]; ++ ++ return kbi_set_led_mode(state, color, mode); ++ } ++ ++ return CMD_RET_USAGE; ++} ++ ++static int do_kbi_trigger(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ enum boot_trigger trigger; ++ const char *op; ++ int enable; ++ ++ if (argc < 3) ++ return CMD_RET_USAGE; ++ ++ /* Parse trigger type */ ++ if (strcmp(argv[1], "rtc") == 0) { ++ trigger = BOOT_TRIGGER_RTC; ++ } else if (strcmp(argv[1], "dcin") == 0) { ++ trigger = BOOT_TRIGGER_DCIN; ++ } else { ++ return CMD_RET_USAGE; ++ } ++ ++ op = argv[2]; ++ ++ if (strcmp(op, "r") == 0) { ++ /* Read trigger state */ ++ return kbi_get_boot_trigger(trigger); ++ } else if (strcmp(op, "w") == 0) { ++ /* Write trigger state */ ++ if (argc < 4) ++ return CMD_RET_USAGE; ++ ++ enable = simple_strtoul(argv[3], NULL, 10); ++ if (enable != 0 && enable != 1) { ++ printf("Invalid value: %s (must be 0 or 1)\n", argv[3]); ++ return CMD_RET_USAGE; ++ } ++ ++ return kbi_set_boot_trigger(trigger, enable); ++ } ++ ++ return CMD_RET_USAGE; ++} ++ ++static struct cmd_tbl cmd_kbi_sub[] = { ++ U_BOOT_CMD_MKENT(version, 1, 1, do_kbi_version, "", ""), ++ U_BOOT_CMD_MKENT(usid, 1, 1, do_kbi_usid, "", ""), ++ U_BOOT_CMD_MKENT(hwver, 1, 1, do_kbi_hwver, "", ""), ++ U_BOOT_CMD_MKENT(led, 5, 1, do_kbi_led, "", ""), ++ U_BOOT_CMD_MKENT(trigger, 4, 1, do_kbi_trigger, "", ""), ++}; ++ ++static int do_kbi(struct cmd_tbl *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ struct cmd_tbl *c; ++ ++ if (argc < 2) ++ return CMD_RET_USAGE; ++ ++ /* Strip off leading 'kbi' command argument */ ++ argc--; ++ argv++; ++ ++ c = find_cmd_tbl(argv[0], cmd_kbi_sub, ARRAY_SIZE(cmd_kbi_sub)); ++ ++ if (c) ++ return c->cmd(cmdtp, flag, argc, argv); ++ else ++ return CMD_RET_USAGE; ++} ++ ++U_BOOT_CMD( ++ kbi, 6, 1, do_kbi, ++ "KBI (Khadas Bootloader Instructions)", ++ "version - Read MCU firmware version\n" ++ "kbi usid - Read unique serial ID\n" ++ "kbi hwver - Read hardware version\n" ++ "kbi led [systemoff|systemon] r - Read LED mode\n" ++ "kbi led [systemoff|systemon] w - Set LED mode\n" ++ " color: r, g, b, rg, rb, gb, rgb\n" ++ " mode: off, on, breathe, heartbeat\n" ++ "kbi trigger [rtc|dcin] r - Read boot trigger state\n" ++ "kbi trigger [rtc|dcin] w <0|1> - Set boot trigger (0=disable, 1=enable)" ++); +\ No newline at end of file +diff --git a/configs/khadas-edge2-rk3588s_defconfig b/configs/khadas-edge2-rk3588s_defconfig +index 111111111111..222222222222 100644 +--- a/configs/khadas-edge2-rk3588s_defconfig ++++ b/configs/khadas-edge2-rk3588s_defconfig +@@ -38,6 +38,7 @@ CONFIG_CMD_I2C=y + CONFIG_CMD_MMC=y + CONFIG_CMD_SPI=y + CONFIG_CMD_USB=y ++CONFIG_CMD_KHADAS_KBI=y + CONFIG_CMD_USB_MASS_STORAGE=y + # CONFIG_CMD_SETEXPR is not set + CONFIG_CMD_TFTPPUT=y +@@ -104,3 +105,8 @@ CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_PRODUCT_NUM=0x350a + CONFIG_SPL_TINY_MEMSET=y + CONFIG_ERRNO_STR=y ++CONFIG_SPL_ADC=y ++CONFIG_CMD_ADC=y ++CONFIG_BUTTON_ADC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_RK8XX=y +\ No newline at end of file +-- +Armbian + diff --git a/patch/u-boot/v2025.04/board_nanopi-r3s-lts/Add-board-NanoPi-R3S-LTS.patch b/patch/u-boot/v2025.10/board_nanopi-r3s-lts/Add-board-NanoPi-R3S-LTS.patch similarity index 100% rename from patch/u-boot/v2025.04/board_nanopi-r3s-lts/Add-board-NanoPi-R3S-LTS.patch rename to patch/u-boot/v2025.10/board_nanopi-r3s-lts/Add-board-NanoPi-R3S-LTS.patch diff --git a/patch/u-boot/v2025.10/board_rock-5b-plus/0001-Set-NET_PREFER_ROM_MAC_ADDR.patch b/patch/u-boot/v2025.10/board_rock-5b-plus/0001-Set-NET_PREFER_ROM_MAC_ADDR.patch new file mode 100644 index 000000000..ce55032cc --- /dev/null +++ b/patch/u-boot/v2025.10/board_rock-5b-plus/0001-Set-NET_PREFER_ROM_MAC_ADDR.patch @@ -0,0 +1,20 @@ +From 4491dae1a3408161be4d665e986aa2d5987c9251 Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 22 Apr 2024 09:56:19 -0400 +Subject: [PATCH] configs/rock5b: Set NET_PREFER_ROM_MAC_ADDR to y + +--- + configs/rock5b-rk3588_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/rock5b-rk3588_defconfig b/configs/rock5b-rk3588_defconfig +index 6349e879145..9c1e5df0924 100644 +--- a/configs/rock5b-rk3588_defconfig ++++ b/configs/rock5b-rk3588_defconfig +@@ -108,3 +108,4 @@ CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_DOWNLOAD=y + CONFIG_USB_FUNCTION_ROCKUSB=y + CONFIG_ERRNO_STR=y ++CONFIG_NET_PREFER_ROM_MAC_ADDR=y +-- +GitLab diff --git a/patch/u-boot/v2025.10/board_rock-5b-plus/0002-Add-ROCK-5BPlus-support.patch b/patch/u-boot/v2025.10/board_rock-5b-plus/0002-Add-ROCK-5BPlus-support.patch new file mode 100644 index 000000000..22003ed87 --- /dev/null +++ b/patch/u-boot/v2025.10/board_rock-5b-plus/0002-Add-ROCK-5BPlus-support.patch @@ -0,0 +1,96 @@ +From 698bf35ed797f2a9ffdbeea5e83ea4ad7ed5a7b2 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 2 Apr 2025 19:54:47 +0200 +Subject: [PATCH] board: rock5b-rk3588: add ROCK 5B+ support + +The ROCK 5B and ROCK 5B+ are quite similar, but there are also a +few changes, which require a different device tree. Most of the +changes are not easily detectable at runtime, but it is possible +to tell the boards apart by checking the memory type. All ROCK +5B models use LPDDR4 and all ROCK 5B+ models use LPDDR5. + +Signed-off-by: Sebastian Reichel +--- + board/radxa/rock5b-rk3588/rock5b-rk3588.c | 65 +++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/board/radxa/rock5b-rk3588/rock5b-rk3588.c b/board/radxa/rock5b-rk3588/rock5b-rk3588.c +index fc2f69db224..afe10ca0d16 100644 +--- a/board/radxa/rock5b-rk3588/rock5b-rk3588.c ++++ b/board/radxa/rock5b-rk3588/rock5b-rk3588.c +@@ -5,6 +5,10 @@ + + #include + #include ++#include ++#include ++#include ++#include + + #ifdef CONFIG_OF_BOARD_SETUP + int ft_board_setup(void *blob, struct bd_info *bd) +@@ -14,3 +18,64 @@ int ft_board_setup(void *blob, struct bd_info *bd) + return 0; + } + #endif ++ ++enum { ++ ROCKCHIP_DDR4 = 0, ++ ROCKCHIP_DDR2 = 2, ++ ROCKCHIP_DDR3 = 3, ++ ROCKCHIP_LPDDR2 = 5, ++ ROCKCHIP_LPDDR3 = 6, ++ ROCKCHIP_LPDDR4 = 7, ++ ROCKCHIP_LPDDR4X = 8, ++ ROCKCHIP_LPDDR5 = 9, ++ ROCKCHIP_DDR5 = 10, ++ ROCKCHIP_UNUSED = 0xFF ++}; ++ ++#define RK3588_PMUGRF_BASE_ADDR 0xfd58a000 ++#define RK3588_PMUGRF_OS_REG2 0x208 ++#define RK3588_PMUGRF_OS_REG2_DRAMTYPE_INFO GENMASK(15, 13) ++#define RK3588_PMUGRF_OS_REG3 0x20c ++#define RK3588_PMUGRF_OS_REG3_SYSREG_VERSION GENMASK(31, 28) ++#define RK3588_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3 GENMASK(13, 12) ++ ++static int rk3588_get_memory_type(void) ++{ ++ u32 reg2 = readl(RK3588_PMUGRF_BASE_ADDR + RK3588_PMUGRF_OS_REG2); ++ u32 reg3 = readl(RK3588_PMUGRF_BASE_ADDR + RK3588_PMUGRF_OS_REG3); ++ u32 ddr_type; ++ ++ /* lower 3 bits of the DDR type */ ++ ddr_type = FIELD_GET(RK3588_PMUGRF_OS_REG2_DRAMTYPE_INFO, reg2); ++ ++ /* ++ * For version three and higher the upper two bits of the DDR type are ++ * in RK3588_PMUGRF_OS_REG3 ++ */ ++ if (FIELD_GET(RK3588_PMUGRF_OS_REG3_SYSREG_VERSION, reg3) >= 0x3) ++ ddr_type |= FIELD_GET(RK3588_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3, reg3) << 3; ++ ++ return ddr_type; ++} ++ ++static const char* rock5_get_model_devicetree(void) ++{ ++ switch (rk3588_get_memory_type()) { ++ case ROCKCHIP_LPDDR5: ++ return "rockchip/rk3588-rock-5b-plus.dtb"; ++ case ROCKCHIP_LPDDR4: ++ default: ++ return "rockchip/rk3588-rock-5b.dtb"; ++ } ++} ++ ++int board_fit_config_name_match(const char *name) ++{ ++ return strcmp(name, rock5_get_model_devicetree()); ++} ++ ++int rk_board_late_init(void) ++{ ++ env_set("fdtfile", rock5_get_model_devicetree()); ++ return 0; ++} diff --git a/patch/u-boot/v2025.04/board_youyeetoo-r1-v3/youyeetoo-r1-v3-add-support.patch b/patch/u-boot/v2025.10/board_youyeetoo-r1-v3/youyeetoo-r1-v3-add-support.patch similarity index 100% rename from patch/u-boot/v2025.04/board_youyeetoo-r1-v3/youyeetoo-r1-v3-add-support.patch rename to patch/u-boot/v2025.10/board_youyeetoo-r1-v3/youyeetoo-r1-v3-add-support.patch diff --git a/patch/u-boot/v2025.04/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch b/patch/u-boot/v2025.10/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch similarity index 99% rename from patch/u-boot/v2025.04/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch rename to patch/u-boot/v2025.10/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch index ad0a39018..1fdc9e473 100644 --- a/patch/u-boot/v2025.04/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch +++ b/patch/u-boot/v2025.10/board_youyeetoo-r1-v3/youyeetoo-r1-v3-upstream-dts.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: SuperKali -Date: Sat, 10 May 2025 13:10:27 +0000 +Date: Thu, 23 Oct 2025 07:48:02 +0000 Subject: Add Youyeetoo R1 upstream patch Signed-off-by: SuperKali @@ -10,7 +10,7 @@ Signed-off-by: SuperKali diff --git a/dts/upstream/src/arm64/rockchip/rk3588s-youyeetoo-r1.dts b/dts/upstream/src/arm64/rockchip/rk3588s-youyeetoo-r1.dts new file mode 100644 -index 000000000000..111111111111 +index 00000000000..592d2b87e00 --- /dev/null +++ b/dts/upstream/src/arm64/rockchip/rk3588s-youyeetoo-r1.dts @@ -0,0 +1,884 @@ @@ -278,7 +278,7 @@ index 000000000000..111111111111 +}; + + -+&hdptxphy_hdmi0 { ++&hdptxphy0 { + status = "okay"; +}; + diff --git a/patch/u-boot/v2025.10/cmd-fileenv-read-string-from-file-into-env.patch b/patch/u-boot/v2025.10/cmd-fileenv-read-string-from-file-into-env.patch index 80d0ffe2e..c66c77a8b 100644 --- a/patch/u-boot/v2025.10/cmd-fileenv-read-string-from-file-into-env.patch +++ b/patch/u-boot/v2025.10/cmd-fileenv-read-string-from-file-into-env.patch @@ -18,7 +18,7 @@ diff --git a/cmd/Kconfig b/cmd/Kconfig index 111111111111..222222222222 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig -@@ -1825,6 +1825,11 @@ config CMD_XXD +@@ -1841,6 +1841,11 @@ config CMD_XXD help Print file as hexdump to standard output @@ -34,7 +34,7 @@ diff --git a/cmd/Makefile b/cmd/Makefile index 111111111111..222222222222 100644 --- a/cmd/Makefile +++ b/cmd/Makefile -@@ -173,6 +173,7 @@ obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o +@@ -175,6 +175,7 @@ obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o obj-$(CONFIG_CMD_SEAMA) += seama.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o @@ -53,7 +53,7 @@ index 000000000000..111111111111 +#include +#include +#include -+ ++#include "env.h" +static char *fs_argv[5]; + +int do_fileenv(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) diff --git a/patch/u-boot/v2025.10/defconfig/nanopi-m6-rk3588s_defconfig b/patch/u-boot/v2025.10/defconfig/nanopi-m6-rk3588s_defconfig new file mode 100644 index 000000000..5c162cee2 --- /dev/null +++ b/patch/u-boot/v2025.10/defconfig/nanopi-m6-rk3588s_defconfig @@ -0,0 +1,92 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SF_DEFAULT_SPEED=24000000 +CONFIG_SF_DEFAULT_MODE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588s-nanopi-m6" +CONFIG_ROCKCHIP_RK3588=y +CONFIG_SPL_SERIAL=y +CONFIG_TARGET_EVB_RK3588=y +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_SF_DEFAULT_BUS=5 +CONFIG_DEBUG_UART_BASE=0xFEB50000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI=y +CONFIG_PCI=y +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-nanopi-m6.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x40000 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 +CONFIG_SPL_ATF=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +CONFIG_AHCI_PCI=y +CONFIG_DWC_AHCI=y +CONFIG_SPL_CLK=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_PHY_GIGE=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y +CONFIG_MII=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_ROCKCHIP=y +CONFIG_RTL8169=y +CONFIG_PHYLIB=y +CONFIG_NVME_PCI=y +CONFIG_PCIE_DW_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y +CONFIG_PHY_ROCKCHIP_USBDP=y +CONFIG_SPL_PINCTRL=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_SPL_RAM=y +CONFIG_SCSI=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_ERRNO_STR=y diff --git a/patch/u-boot/v2025.10/defconfig/nanopi-m6-spi-rk3588s_defconfig b/patch/u-boot/v2025.10/defconfig/nanopi-m6-spi-rk3588s_defconfig new file mode 100644 index 000000000..3f4829a88 --- /dev/null +++ b/patch/u-boot/v2025.10/defconfig/nanopi-m6-spi-rk3588s_defconfig @@ -0,0 +1,97 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SF_DEFAULT_SPEED=24000000 +CONFIG_SF_DEFAULT_MODE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588s-nanopi-m6-spi" +CONFIG_ROCKCHIP_RK3588=y +CONFIG_ROCKCHIP_SPI_IMAGE=y +CONFIG_SPL_SERIAL=y +CONFIG_TARGET_EVB_RK3588=y +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_SF_DEFAULT_BUS=5 +CONFIG_DEBUG_UART_BASE=0xFEB50000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_PCI=y +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-nanopi-m6.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x40000 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 +CONFIG_SPL_ATF=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +CONFIG_AHCI_PCI=y +CONFIG_DWC_AHCI=y +CONFIG_SPL_CLK=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_PHY_GIGE=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y +CONFIG_MII=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_ROCKCHIP=y +CONFIG_RTL8169=y +CONFIG_PHYLIB=y +CONFIG_NVME_PCI=y +CONFIG_PCIE_DW_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y +CONFIG_PHY_ROCKCHIP_USBDP=y +CONFIG_SPL_PINCTRL=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_SPL_RAM=y +CONFIG_SCSI=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_ERRNO_STR=y diff --git a/patch/u-boot/v2025.10/defconfig/orangepi-5-sata-rk3588s_defconfig b/patch/u-boot/v2025.10/defconfig/orangepi-5-sata-rk3588s_defconfig new file mode 100644 index 000000000..bed04dea3 --- /dev/null +++ b/patch/u-boot/v2025.10/defconfig/orangepi-5-sata-rk3588s_defconfig @@ -0,0 +1,93 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SF_DEFAULT_SPEED=24000000 +CONFIG_SF_DEFAULT_MODE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588s-orangepi-5-sata" +CONFIG_ROCKCHIP_RK3588=y +CONFIG_ROCKCHIP_SPI_IMAGE=y +CONFIG_SPL_SERIAL=y +CONFIG_TARGET_EVB_RK3588=y +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_SF_DEFAULT_BUS=5 +CONFIG_DEBUG_UART_BASE=0xFEB50000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_PCI=y +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-orangepi-5-sata.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x40000 +CONFIG_SPL_PAD_TO=0x7f8000 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 +CONFIG_SPL_ATF=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +CONFIG_AHCI_PCI=y +CONFIG_DWC_AHCI=y +CONFIG_SPL_CLK=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_PHY_MOTORCOMM=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_ROCKCHIP=y +CONFIG_NVME_PCI=y +CONFIG_PCIE_DW_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y +CONFIG_PHY_ROCKCHIP_USBDP=y +CONFIG_SPL_PINCTRL=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_SPL_RAM=y +CONFIG_SCSI=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_ERRNO_STR=y +CONFIG_AHCI=y +CONFIG_CMD_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_DWC_AHCI=y +CONFIG_LIBATA=y +CONFIG_SCSI_AHCI=y +CONFIG_SCSI=y diff --git a/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-spi-u-boot.dtsi b/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-spi-u-boot.dtsi new file mode 100644 index 000000000..e0db0dfb5 --- /dev/null +++ b/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-spi-u-boot.dtsi @@ -0,0 +1,19 @@ +#include "rk3588s-u-boot.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc; + }; +}; + +&fspim0_pins { + bootph-pre-ram; + bootph-some-ram; +}; + +&sfc { + flash@0 { + bootph-pre-ram; + bootph-some-ram; + }; +}; diff --git a/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-u-boot.dtsi b/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-u-boot.dtsi new file mode 100644 index 000000000..c4a6693a1 --- /dev/null +++ b/patch/u-boot/v2025.10/dt_uboot/rk3588s-nanopi-m6-u-boot.dtsi @@ -0,0 +1 @@ +#include "rk3588s-u-boot.dtsi" diff --git a/patch/u-boot/v2025.10/dt_uboot/rk3588s-orangepi-5-sata-u-boot.dtsi b/patch/u-boot/v2025.10/dt_uboot/rk3588s-orangepi-5-sata-u-boot.dtsi new file mode 100644 index 000000000..56c225f93 --- /dev/null +++ b/patch/u-boot/v2025.10/dt_uboot/rk3588s-orangepi-5-sata-u-boot.dtsi @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3588s-u-boot.dtsi" +#include "rk3588s-orangepi-5-u-boot.dtsi" + + / { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc; + }; +}; + +&binman { + simple-bin-spi { + filename = "u-boot-rockchip-spi-sata.bin"; + }; +}; diff --git a/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6-spi.dts b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6-spi.dts new file mode 100644 index 000000000..fcac0d6cb --- /dev/null +++ b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6-spi.dts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include "rk3588s-nanopi-m6.dts" + +/ { + model = "FriendlyElec NanoPi M6 (SPI)"; + compatible = "friendlyelec,nanopi-m6", "rockchip,rk3588s"; +}; + +&sdhci { + status = "disabled"; +}; + +&sfc { + pinctrl-names = "default"; + pinctrl-0 = <&fspim0_pins>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <50000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <1>; + }; +}; diff --git a/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6.dts b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6.dts new file mode 100644 index 000000000..30c10ce8d --- /dev/null +++ b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-nanopi-m6.dts @@ -0,0 +1,907 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include +#include +#include +#include +#include "rk3588s.dtsi" + +/ { + model = "FriendlyElec NanoPi M6"; + compatible = "friendlyelec,nanopi-m6", "rockchip,rk3588s"; + + aliases { + ethernet0 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + analog-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "realtek,rt5616-codec"; + + simple-audio-card,routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "MIC1", "Microphone Jack", + "Microphone Jack", "micbias1"; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Microphone", "Microphone Jack"; + + simple-audio-card,cpu { + sound-dai = <&i2s0_8ch>; + }; + + simple-audio-card,codec { + sound-dai = <&rt5616>; + }; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "Maskrom"; + linux,code = ; + press-threshold-microvolt = <1800>; + }; + }; + + adc-keys-1 { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "Recovery"; + linux,code = ; + press-threshold-microvolt = <1800>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi0_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + sys_led: led-0 { + label = "sys_led"; + gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_led_pin>; + }; + + user_led: led-1 { + label = "user_led"; + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&user_led_pin>; + }; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + 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: regulator-vcc-1v1-nldo-s3 { + 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>; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s0"; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_3v3_sd_s0: regulator-vcc-3v3-sd-s0 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sd_s0_pwr>; + regulator-name = "vcc_3v3_sd_s0"; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_3v3_pcie20: regulator-vcc3v3-pcie20 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_pcie20"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_3v3_pcie20_m2: regulator-vcc3v3-pcie20-m2 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_m2_0_pwren>; + regulator-name = "vcc_3v3_pcie20_m2"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_host_20: regulator-vcc5v0-host-20 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host20_en>; + regulator-name = "vcc5v0_host_20"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_otg0: regulator-vbus5v0-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren>; + regulator-name = "vcc5v0_usb_otg0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; +}; + +&combphy0_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>; +}; + +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-rxid"; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + pinctrl-names = "default"; + tx_delay = <0x42>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&hdmi0 { + status = "okay"; +}; + +&hdmi0_in { + hdmi0_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi0>; + }; +}; + +&hdmi0_out { + hdmi0_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdptxphy0 { + 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"; + + vdd_npu_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_npu_s0"; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <2300>; + regulator-boot-on; + regulator-always-on; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c6 { + clock-frequency = <200000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m0_xfer>; + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int>; + interrupt-parent = <&gpio0>; + interrupts = ; + wakeup-source; + }; +}; + +&i2c7 { + clock-frequency = <200000>; + status = "okay"; + + rt5616: audio-codec@1b { + compatible = "realtek,rt5616"; + reg = <0x1b>; + clocks = <&cru I2S0_8CH_MCLKOUT>; + clock-names = "mclk"; + assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; + assigned-clock-rates = <12288000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_mclk>; + status = "okay"; + #sound-dai-cells = <0>; + }; +}; + +&i2s0_8ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_lrck + &i2s0_sclk + &i2s0_sdi0 + &i2s0_sdo0>; + status = "okay"; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x1>; + pinctrl-names = "default"; + pinctrl-0 = <&rtl8211f_rst>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + }; +}; + +&pcie2x1l1 { + reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_pcie20>; + status = "okay"; +}; + +&pcie2x1l2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_m2_0_prsnt>; + reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_pcie20_m2>; + status = "okay"; +}; + +&pinctrl { + gpio-leds { + sys_led_pin: sys-led-pin { + rockchip,pins = + <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + user_led_pin: lan1-led-pin { + rockchip,pins = + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_m2_0_pwren: pcie-m20-pwren { + rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + pcie_m2_0_prsnt: pcie-m20-prsnt { + rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + hym8563 { + rtc_int: rtc-int { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdmmc { + sd_s0_pwr: sd-s0-pwr { + rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + typec5v_pwren: typec5v-pwren { + rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_host20_en: vcc5v0-host20-en { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + rtl8211f { + rtl8211f_rst: rtl8211f-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&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-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + no-mmc; + no-sdio; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_sd_s0>; + vqmmc-supply = <&vccio_sd_s0>; + 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; + regulator-suspend-microvolt = <1800000>; + }; + }; + + 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; + }; + }; + + avcc_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <12500>; + regulator-name = "avcc_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>; + }; + }; + + avdd_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "avdd_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; + }; + }; + + avdd_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "avdd_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"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + phy-supply = <&vcc5v0_usb_otg0>; + status = "okay"; +}; + +&u2phy2 { + status = "okay"; +}; + +&u2phy2_host { + phy-supply = <&vcc5v0_host_20>; + status = "okay"; +}; + +&u2phy3 { + status = "okay"; +}; + +&u2phy3_host { + phy-supply = <&vcc5v0_host_20>; + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + status = "okay"; +}; + +&usbdp_phy0 { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi0_in_vp0>; + }; +}; diff --git a/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-orangepi-5-sata.dts b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-orangepi-5-sata.dts new file mode 100644 index 000000000..57314f472 --- /dev/null +++ b/patch/u-boot/v2025.10/dt_upstream_rockchip/rk3588s-orangepi-5-sata.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include "rk3588s-orangepi-5.dtsi" +#include +#include + + / { + model = "Xunlong Orange Pi 5 (Sata)"; + compatible = "xunlong,orangepi-5", "rockchip,rk3588s"; +}; + +&sata0 { + pinctrl-names = "default"; + pinctrl-0 = <&sata_reset>; + status = "okay"; + + phys = <&combphy0_ps PHY_TYPE_SATA>; + phy-names = "sata-phy"; +}; + +&sfc { + status = "okay"; +}; + +&pinctrl { + sata { + sata_reset: sata-reset { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/patch/u-boot/v2025.10/general-dw-hdmi-disable.patch b/patch/u-boot/v2025.10/general-dw-hdmi-disable.patch index acf5cadc9..6ec7f6ae2 100644 --- a/patch/u-boot/v2025.10/general-dw-hdmi-disable.patch +++ b/patch/u-boot/v2025.10/general-dw-hdmi-disable.patch @@ -40,7 +40,7 @@ diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h index 111111111111..222222222222 100644 --- a/include/dw_hdmi.h +++ b/include/dw_hdmi.h -@@ -562,6 +562,7 @@ int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi); +@@ -559,6 +559,7 @@ int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi); void dw_hdmi_phy_init(struct dw_hdmi *hdmi); int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid); diff --git a/patch/u-boot/v2025.10/general-dwc-otg-usb-fix.patch b/patch/u-boot/v2025.10/general-dwc-otg-usb-fix.patch index 46b59a2ce..4f848bbc8 100644 --- a/patch/u-boot/v2025.10/general-dwc-otg-usb-fix.patch +++ b/patch/u-boot/v2025.10/general-dwc-otg-usb-fix.patch @@ -42,15 +42,15 @@ diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 111111111111..222222222222 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c -@@ -441,6 +441,8 @@ static void dwc_otg_core_init(struct udevice *dev) +@@ -361,6 +361,8 @@ static void dwc_otg_core_init(struct udevice *dev) - writel(usbcfg, ®s->gusbcfg); + writel(usbcfg, ®s->global_regs.gusbcfg); + mdelay(10); + /* Program the GAHBCFG Register. */ - switch (readl(®s->ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) { - case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY: + switch (FIELD_GET(GHWCFG2_ARCHITECTURE_MASK, readl(®s->global_regs.ghwcfg2))) { + case GHWCFG2_SLAVE_ONLY_ARCH: -- Armbian diff --git a/patch/u-boot/v2025.10/rk3288-fix-kernel-iommu-page-fault.patch b/patch/u-boot/v2025.10/rk3288-fix-kernel-iommu-page-fault.patch index 58e089db3..447eb58d5 100644 --- a/patch/u-boot/v2025.10/rk3288-fix-kernel-iommu-page-fault.patch +++ b/patch/u-boot/v2025.10/rk3288-fix-kernel-iommu-page-fault.patch @@ -1,18 +1,18 @@ -From eb780535ef9545a927dea283ca576ca6bc2b14e1 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Wed, 17 Sep 2025 12:03:15 +0200 -Subject: [PATCH] Fix Linux kernel complaining about IOMMU page fault +Subject: Fix Linux kernel complaining about IOMMU page fault rk3288 remove handle does not get called at all because the driver is missing the DM_FLAG_OS_PREPARE flag. Also adds proper reset of VOP clocks to further clean up VOP state. --- - drivers/video/rockchip/rk3288_vop.c | 22 ++++++++++++++++++++-- + drivers/video/rockchip/rk3288_vop.c | 22 +++++++++- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c -index 282831eaac..9e88f3538b 100644 +index 111111111111..222222222222 100644 --- a/drivers/video/rockchip/rk3288_vop.c +++ b/drivers/video/rockchip/rk3288_vop.c @@ -10,6 +10,7 @@ @@ -67,5 +67,5 @@ index 282831eaac..9e88f3538b 100644 + .flags = DM_FLAG_OS_PREPARE }; -- -2.43.0 +Armbian diff --git a/patch/u-boot/v2026.01/0000.patching_config.yaml b/patch/u-boot/v2026.01/0000.patching_config.yaml new file mode 100644 index 000000000..99b2cd214 --- /dev/null +++ b/patch/u-boot/v2026.01/0000.patching_config.yaml @@ -0,0 +1,6 @@ +config: + + overlay-directories: + - { source: "defconfig", target: "configs" } # copies all files in defconfig dir to the configs/ dir in the u-boot source tree + - { source: "dt_upstream_rockchip", target: "dts/upstream/src/arm64/rockchip" } # copies all files in dt_upstream_rockchip dir to the dts/upstream/src/arm64/rockchip dir in the u-boot source tree + - { source: "dt_uboot", target: "arch/arm/dts" } # copies all files in dt_uboot dir to the arch/arm/dts dir in the u-boot source tree diff --git a/patch/u-boot/v2024.01/board_khadas-vim3l/meson64-boot-usb-nvme-scsi-first.patch b/patch/u-boot/v2026.01/board_khadas-vim3l/kvim3l-boot-usb-sata-sd.patch similarity index 52% rename from patch/u-boot/v2024.01/board_khadas-vim3l/meson64-boot-usb-nvme-scsi-first.patch rename to patch/u-boot/v2026.01/board_khadas-vim3l/kvim3l-boot-usb-sata-sd.patch index e6233adef..239cf2b7e 100644 --- a/patch/u-boot/v2024.01/board_khadas-vim3l/meson64-boot-usb-nvme-scsi-first.patch +++ b/patch/u-boot/v2026.01/board_khadas-vim3l/kvim3l-boot-usb-sata-sd.patch @@ -1,32 +1,30 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ricardo Pardini -Date: Sun, 14 Jan 2024 13:44:58 +0100 -Subject: meson64: change `BOOT_TARGET_DEVICES` to try to boot USB, NVME and - SCSI before SD, MMC, PXE, DHCP +Date: Sat, 15 Nov 2025 00:04:36 +0100 +Subject: kvim3l: boot order: SD -> NVME -> USB -> eMMC -> PXE --- - include/configs/meson64.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) + include/configs/meson64.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/configs/meson64.h b/include/configs/meson64.h -index efab9a624dc5..32c25098e674 100644 +index f3275b37a51..85b06c0579d 100644 --- a/include/configs/meson64.h +++ b/include/configs/meson64.h -@@ -99,12 +99,12 @@ +@@ -119,10 +119,12 @@ #define BOOT_TARGET_DEVICES(func) \ func(ROMUSB, romusb, na) \ func(USB_DFU, usbdfu, na) \ -- func(MMC, mmc, 0) \ -- func(MMC, mmc, 1) \ -- func(MMC, mmc, 2) \ - BOOT_TARGET_DEVICES_USB(func) \ - BOOT_TARGET_NVME(func) \ - BOOT_TARGET_SCSI(func) \ -+ func(MMC, mmc, 0) \ +- BOOT_TARGET_MMC(func) \ +- BOOT_TARGET_DEVICES_USB(func) \ + func(MMC, mmc, 1) \ + BOOT_TARGET_NVME(func) \ ++ BOOT_TARGET_DEVICES_USB(func) \ + BOOT_TARGET_SCSI(func) \ + func(MMC, mmc, 2) \ - func(PXE, pxe, na) \ - func(DHCP, dhcp, na) ++ func(MMC, mmc, 0) \ + BOOT_TARGET_PXE(func) \ + BOOT_TARGET_DHCP(func) #endif -- Armbian diff --git a/patch/u-boot/v2025.04/board_odroidhc4/odroidhc4-boot-usb-sata-sd.patch b/patch/u-boot/v2026.01/board_odroidhc4/odroidhc4-boot-usb-sata-sd.patch similarity index 100% rename from patch/u-boot/v2025.04/board_odroidhc4/odroidhc4-boot-usb-sata-sd.patch rename to patch/u-boot/v2026.01/board_odroidhc4/odroidhc4-boot-usb-sata-sd.patch diff --git a/patch/u-boot/v2026.01/cmd-fileenv-read-string-from-file-into-env.patch b/patch/u-boot/v2026.01/cmd-fileenv-read-string-from-file-into-env.patch new file mode 100644 index 000000000..126fcf4e9 --- /dev/null +++ b/patch/u-boot/v2026.01/cmd-fileenv-read-string-from-file-into-env.patch @@ -0,0 +1,99 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Fri, 31 Jan 2025 15:52:03 +0100 +Subject: cmd: fileenv: read string from file into env + +- rpardini: adapted from vendor/legacy patch from 2018 + +Signed-off-by: Pascal Vizeli +Signed-off-by: Stefan Agner +Signed-off-by: Ricardo Pardini +--- + cmd/Kconfig | 5 + + cmd/Makefile | 1 + + cmd/fileenv.c | 46 ++++++++++ + 3 files changed, 52 insertions(+) + +diff --git a/cmd/Kconfig b/cmd/Kconfig +index 111111111111..222222222222 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -1898,6 +1898,11 @@ config CMD_XXD + help + Print file as hexdump to standard output + ++config CMD_FILEENV ++ bool "fileenv" ++ help ++ Read a file into memory and store it to env. ++ + endmenu + + if NET || NET_LWIP +diff --git a/cmd/Makefile b/cmd/Makefile +index 111111111111..222222222222 100644 +--- a/cmd/Makefile ++++ b/cmd/Makefile +@@ -175,6 +175,7 @@ obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o + obj-$(CONFIG_CMD_SEAMA) += seama.o + obj-$(CONFIG_CMD_SETEXPR) += setexpr.o + obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o ++obj-$(CONFIG_CMD_FILEENV) += fileenv.o + obj-$(CONFIG_CMD_SPI) += spi.o + obj-$(CONFIG_CMD_STRINGS) += strings.o + obj-$(CONFIG_CMD_SMBIOS) += smbios.o +diff --git a/cmd/fileenv.c b/cmd/fileenv.c +new file mode 100644 +index 000000000000..111111111111 +--- /dev/null ++++ b/cmd/fileenv.c +@@ -0,0 +1,46 @@ ++#include ++#include ++#include ++#include ++#include ++#include "env.h" ++static char *fs_argv[5]; ++ ++int do_fileenv(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) ++{ ++ if (argc < 6) ++ return CMD_RET_USAGE; ++ ++ fs_argv[0] = "fatload"; ++ fs_argv[1] = argv[1]; ++ fs_argv[2] = argv[2]; ++ fs_argv[3] = argv[3]; ++ fs_argv[4] = argv[4]; ++ ++ if (do_fat_fsload(cmdtp, 0, 5, fs_argv) != 0) ++ return 1; ++ ++ char *addr = (char *)simple_strtoul(argv[3], NULL, 16); ++ size_t size = env_get_hex("filesize", 0); ++ ++ // Prepare string ++ addr[size] = 0x00; ++ char *s = addr; ++ while(*s != 0x00) { ++ if (isprint(*s)) { ++ s++; ++ } ++ else { ++ *s = 0x00; ++ } ++ } ++ ++ return env_set(argv[5], addr); ++} ++ ++U_BOOT_CMD( ++ fileenv, 6, 0, do_fileenv, ++ "Read file and store it into env.", ++ " \n" ++ " - Read file from fat32 and store it as env." ++); +-- +Armbian + diff --git a/requirements.txt b/requirements.txt index 875ef0ad6..ea60cc26a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ # Always use a fixed version, this is important for correct hashing. # Dependabot will keep these versions up to date. -pip == 25.2 # pip is the package installer for Python +pip == 25.3 # pip is the package installer for Python setuptools == 80.9.0 # for building Python packages pyelftools == 0.32 # for building U-Boot unidiff == 0.7.5 # for parsing unified diff